Merge branch 'wrong_playerid' into 'master'

Homepage redirect on wrong Player id

Closes #69

See merge request lukas/openmediacenter!47
This commit is contained in:
Lukas Heiligenbrunner 2021-06-08 18:12:09 +00:00
commit f7b7df5934
9 changed files with 91 additions and 45 deletions

View File

@ -22,11 +22,12 @@ func getVideoHandlers() {
* @apiName GetMovies * @apiName GetMovies
* @apiGroup video * @apiGroup video
* *
* @apiParam {int} [Tag=all] id of VideoTag to get videos * @apiParam {int} [Tag=1] id of VideoTag to get videos (1=all)
* *
* @apiSuccess {Object[]} . List of Videos * @apiSuccess {Object[]} Videos List of Videos
* @apiSuccess {number} .MovieId Id of Video * @apiSuccess {number} Videos.MovieId Id of Video
* @apiSuccess {String} .MovieName Name of video * @apiSuccess {String} Videos.MovieName Name of video
* @apiSuccess {String} TagName Name of the Tag returned
*/ */
AddHandler("getMovies", VideoNode, func(info *HandlerInfo) []byte { AddHandler("getMovies", VideoNode, func(info *HandlerInfo) []byte {
var args struct { var args struct {
@ -40,16 +41,42 @@ func getVideoHandlers() {
var query string var query string
// 1 is the id of the ALL tag // 1 is the id of the ALL tag
if args.Tag != 1 { if args.Tag != 1 {
query = fmt.Sprintf(`SELECT movie_id,movie_name FROM videos query = fmt.Sprintf(`SELECT movie_id,movie_name,t.tag_name FROM videos
INNER JOIN video_tags vt on videos.movie_id = vt.video_id INNER JOIN video_tags vt on videos.movie_id = vt.video_id
INNER JOIN tags t on vt.tag_id = t.tag_id INNER JOIN tags t on vt.tag_id = t.tag_id
WHERE t.tag_id = '%d' WHERE t.tag_id = %d
ORDER BY likes DESC, create_date, movie_name`, args.Tag) ORDER BY likes DESC, create_date, movie_name`, args.Tag)
} else { } else {
query = "SELECT movie_id,movie_name FROM videos ORDER BY create_date DESC, movie_name" query = "SELECT movie_id,movie_name, (SELECT 'All' as tag_name) FROM videos ORDER BY create_date DESC, movie_name"
} }
result := readVideosFromResultset(database.Query(query)) var result struct {
Videos []types.VideoUnloadedType
TagName string
}
rows := database.Query(query)
vids := []types.VideoUnloadedType{}
var name string
for rows.Next() {
var vid types.VideoUnloadedType
err := rows.Scan(&vid.MovieId, &vid.MovieName, &name)
if err != nil {
return nil
}
vids = append(vids, vid)
}
if rows.Close() != nil {
return nil
}
// if the tag id doesn't exist the query won't return a name
if name == "" {
return nil
}
result.Videos = vids
result.TagName = name
// jsonify results // jsonify results
str, _ := json.Marshal(result) str, _ := json.Marshal(result)
return str return str

View File

@ -72,6 +72,10 @@ export class ActorPage extends React.Component<Props, state> {
data: result.Videos ? result.Videos : [], data: result.Videos ? result.Videos : [],
actor: result.Info actor: result.Info
}); });
},
(_) => {
// if there is an load error redirect to home page
this.props.history.push('/');
} }
); );
} }

View File

@ -4,7 +4,9 @@ import {CategoryView} from './CategoryView';
describe('<CategoryView/>', function () { describe('<CategoryView/>', function () {
function instance() { function instance() {
return shallow(<CategoryView match={{params: {id: 10}}} history={{push: jest.fn()}}/>); const inst = shallow(<CategoryView match={{params: {id: 10}}} history={{push: jest.fn()}}/>);
inst.setState({loaded: true});
return inst;
} }
it('renders without crashing ', function () { it('renders without crashing ', function () {

View File

@ -10,12 +10,14 @@ import Tag from '../../elements/Tag/Tag';
import {DefaultTags, GeneralSuccess} from '../../types/GeneralTypes'; import {DefaultTags, GeneralSuccess} from '../../types/GeneralTypes';
import {Button} from '../../elements/GPElements/Button'; import {Button} from '../../elements/GPElements/Button';
import SubmitPopup from '../../elements/Popups/SubmitPopup/SubmitPopup'; import SubmitPopup from '../../elements/Popups/SubmitPopup/SubmitPopup';
import {Spinner} from 'react-bootstrap';
interface CategoryViewProps extends RouteComponentProps<{id: string}> {} interface CategoryViewProps extends RouteComponentProps<{id: string}> {}
interface CategoryViewState { interface CategoryViewState {
loaded: boolean; loaded: boolean;
submitForceDelete: boolean; submitForceDelete: boolean;
TagName: string;
} }
/** /**
@ -29,7 +31,8 @@ export class CategoryView extends React.Component<CategoryViewProps, CategoryVie
this.state = { this.state = {
loaded: false, loaded: false,
submitForceDelete: false submitForceDelete: false,
TagName: ''
}; };
} }
@ -50,9 +53,13 @@ export class CategoryView extends React.Component<CategoryViewProps, CategoryVie
} }
render(): JSX.Element { render(): JSX.Element {
if (!this.state.loaded) {
return <Spinner animation='border' />;
}
return ( return (
<> <>
<PageTitle title='Categories' subtitle={this.videodata.length + ' Videos'} /> <PageTitle title={this.state.TagName} subtitle={this.videodata.length + ' Videos'} />
<SideBar> <SideBar>
<SideBarTitle>Default Tags:</SideBarTitle> <SideBarTitle>Default Tags:</SideBarTitle>
@ -105,10 +112,18 @@ export class CategoryView extends React.Component<CategoryViewProps, CategoryVie
* @param id tagid * @param id tagid
*/ */
private fetchVideoData(id: number): void { private fetchVideoData(id: number): void {
callAPI<VideoTypes.VideoUnloadedType[]>(APINode.Video, {action: 'getMovies', Tag: id}, (result) => { callAPI(
this.videodata = result; APINode.Video,
this.setState({loaded: true}); {action: 'getMovies', Tag: id},
}); (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
this.videodata = result.Videos;
this.setState({loaded: true, TagName: result.TagName});
},
(_) => {
// if there is an load error redirect to home page
this.props.history.push('/');
}
);
} }
/** /**

View File

@ -23,23 +23,6 @@ describe('<HomePage/>', function () {
expect(wrapper.find('PageTitle').props().subtitle).toBe('testsubtitle - 42'); expect(wrapper.find('PageTitle').props().subtitle).toBe('testsubtitle - 42');
}); });
it('test search field', done => {
global.fetch = global.prepareFetchApi([{}, {}]);
const wrapper = shallow(<HomePage/>);
wrapper.find('[data-testid="searchtextfield"]').simulate('change', {target: {value: 'testvalue'}});
wrapper.find('[data-testid="searchbtnsubmit"]').simulate('click');
process.nextTick(() => {
// state to be set correctly with response
expect(wrapper.state().selectionnr).toBe(2);
global.fetch.mockClear();
done();
});
});
it('test form submit', () => { it('test form submit', () => {
const func = jest.fn(); const func = jest.fn();
const wrapper = shallow(<HomePage/>); const wrapper = shallow(<HomePage/>);
@ -72,7 +55,7 @@ describe('<HomePage/>', function () {
}); });
it('test tag click', done => { it('test tag click', done => {
global.fetch = prepareFetchApi(['test1', 'test2']); global.fetch = prepareFetchApi({Videos: ['test1', 'test2'], TagName: 'all'});
const wrapper = shallow(<HomePage/>); const wrapper = shallow(<HomePage/>);

View File

@ -59,15 +59,19 @@ export class HomePage extends React.Component<Props, state> {
* @param tag tag to fetch videos * @param tag tag to fetch videos
*/ */
fetchVideoData(tag: number): void { fetchVideoData(tag: number): void {
callAPI(APINode.Video, {action: 'getMovies', Tag: tag}, (result: VideoTypes.VideoUnloadedType[]) => { callAPI(
this.setState({ APINode.Video,
data: [] {action: 'getMovies', Tag: tag},
}); (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
this.setState({ this.setState({
data: result, data: []
selectionnr: result.length });
}); this.setState({
}); data: result.Videos,
selectionnr: result.Videos.length
});
}
);
} }
/** /**

View File

@ -286,6 +286,10 @@ export class Player extends React.Component<Props, mystate> {
suggesttag: result.SuggestedTag, suggesttag: result.SuggestedTag,
actors: result.Actors actors: result.Actors
}); });
},
(_) => {
// if there is an load error redirect to home page
this.props.history.push('/');
} }
); );
} }

View File

@ -46,6 +46,10 @@ export class TVPlayer extends React.Component<Props, State> {
console.log(data); console.log(data);
this.data = data; this.data = data;
this.setState({loaded: true}); this.setState({loaded: true});
},
(_) => {
// if there is an load error redirect to home page
this.props.history.push('/');
} }
); );
} }

View File

@ -37,9 +37,12 @@ export function callAPI<T>(
.then((response) => { .then((response) => {
if (response.status === 200) { if (response.status === 200) {
// success // success
response.json().then((result: T) => { response
callback(result); .json()
}); .then((result: T) => {
callback(result);
})
.catch((reason) => errorcallback(reason));
} else if (response.status === 400) { } else if (response.status === 400) {
// Bad Request --> invalid token // Bad Request --> invalid token
console.log('loading Password page.'); console.log('loading Password page.');