fix failing tests / remove obsolente ones

add basic structure of episode page
This commit is contained in:
lukas 2021-04-20 21:17:34 +02:00
parent 6d41b86120
commit c30c193ce0
13 changed files with 122 additions and 180 deletions

View File

@ -1,15 +1,43 @@
package api package api
import "openmediacenter/apiGo/database" import (
"fmt"
"openmediacenter/apiGo/database"
)
func AddTvshowHandlers() { func AddTvshowHandlers() {
var dT struct { AddHandler("getTVShows", TVShowNode, nil, func() []byte {
TagId int
Force bool
}
AddHandler("getTVShows", TVShowNode, &dT, func() []byte {
query := "SELECT id, name FROM tvshow" query := "SELECT id, name FROM tvshow"
rows := database.Query(query) rows := database.Query(query)
return jsonify(readTVshowsFromResultset(rows)) return jsonify(readTVshowsFromResultset(rows))
}) })
var ge struct {
ShowID uint32
}
AddHandler("getEpisodes", TVShowNode, &ge, func() []byte {
query := fmt.Sprintf("SELECT id, name, season, episode FROM tvshow_episodes WHERE tvshow_id=%d", ge.ShowID)
rows := database.Query(query)
type Episode struct {
ID uint32
Name string
Season uint8
Episode uint8
}
episodes := []Episode{}
for rows.Next() {
var ep Episode
err := rows.Scan(&ep.ID, &ep.Name, &ep.Season, &ep.Episode)
if err != nil {
fmt.Println(err.Error())
continue
}
episodes = append(episodes, ep)
}
return jsonify(episodes)
})
} }

View File

@ -3,19 +3,9 @@
"name": "Create React App Sample", "name": "Create React App Sample",
"icons": [ "icons": [
{ {
"src": "favicon.ico", "src": "logo_circle.png",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png", "type": "image/png",
"sizes": "192x192" "sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
} }
], ],
"start_url": ".", "start_url": ".",

View File

@ -18,7 +18,7 @@ describe('<App/>', function () {
it('are navlinks correct', function () { it('are navlinks correct', function () {
const wrapper = shallow(<App/>); const wrapper = shallow(<App/>);
wrapper.setState({password: false}); wrapper.setState({password: false});
expect(wrapper.find('.navitem')).toHaveLength(4); expect(wrapper.find('.navitem')).toHaveLength(5);
}); });
it('test initial fetch from api', done => { it('test initial fetch from api', done => {

View File

@ -5,37 +5,29 @@ import Preview, {TagPreview} from './Preview';
describe('<Preview/>', function () { describe('<Preview/>', function () {
it('renders without crashing ', function () { it('renders without crashing ', function () {
const wrapper = shallow(<Preview movieId={1}/>); const wrapper = shallow(<Preview movieId={1} name='test' picLoader={callback => callback('')}/>);
wrapper.unmount(); wrapper.unmount();
}); });
it('picture rendered correctly', done => { it('picture rendered correctly', () => {
const mockSuccessResponse = 'testsrc'; const func = jest.fn();
const mockJsonPromise = Promise.resolve(mockSuccessResponse); const wrapper = shallow(<Preview movieId={1} name='test' picLoader={callback => {
const mockFetchPromise = Promise.resolve({ func();
text: () => mockJsonPromise callback('42');
}); }}/>);
global.fetch = jest.fn().mockImplementation(() => mockFetchPromise);
const wrapper = shallow(<Preview name='test' movieId={1}/>); // expect picloader tobe called once
expect(func).toHaveBeenCalledTimes(1)
// now called 1 times
expect(global.fetch).toHaveBeenCalledTimes(1);
process.nextTick(() => {
// received picture should be rendered into wrapper // received picture should be rendered into wrapper
expect(wrapper.find('.previewimage').props().src).not.toBeNull(); expect(wrapper.find('.previewimage').props().src).toBe('42');
// check if preview title renders correctly // check if preview title renders correctly
expect(wrapper.find('.previewtitle').text()).toBe('test'); expect(wrapper.find('.previewtitle').text()).toBe('test');
global.fetch.mockClear();
done();
});
}); });
it('spinner loads correctly', function () { it('spinner loads correctly', function () {
const wrapper = shallow(<Preview movieId={1}/>); // if callback is never called --> infinite spinner
const wrapper = shallow(<Preview movieId={1} name='test' picLoader={callback => {}}/>);
// expect load animation to be visible // expect load animation to be visible
expect(wrapper.find('.loadAnimation')).toHaveLength(1); expect(wrapper.find('.loadAnimation')).toHaveLength(1);

View File

@ -8,20 +8,6 @@ describe('<ActorOverviewPage/>', function () {
wrapper.unmount(); wrapper.unmount();
}); });
it('test inerstion of actor tiles', function () {
const wrapper = shallow(<ActorOverviewPage/>);
wrapper.setState({
actors: [{
thumbnail: '',
name: 'testname',
actor_id: 42
}]
});
expect(wrapper.find('ActorTile')).toHaveLength(1);
});
it('test newtagpopup visibility', function () { it('test newtagpopup visibility', function () {
const wrapper = shallow(<ActorOverviewPage/>); const wrapper = shallow(<ActorOverviewPage/>);

View File

@ -8,13 +8,6 @@ describe('<TagView/>', function () {
wrapper.unmount(); wrapper.unmount();
}); });
it('test Tag insertion', function () {
const wrapper = shallow(<TagView/>);
wrapper.setState({loadedtags: [{tag_name: 'test', tag_id: 42}]});
expect(wrapper.find('TagPreview')).toHaveLength(1);
});
it('test new tag popup', function () { it('test new tag popup', function () {
const wrapper = shallow(<TagView/>); const wrapper = shallow(<TagView/>);

View File

@ -10,21 +10,6 @@ describe('<HomePage/>', function () {
wrapper.unmount(); wrapper.unmount();
}); });
it('test data insertion', function () {
const wrapper = shallow(<HomePage/>);
expect(wrapper.find('VideoContainer')).toHaveLength(0);
wrapper.setState({
data: [
{}, {}
]
});
// there shoud be loaded the Videocontainer element into dom after fetching videos correctly
expect(wrapper.find('VideoContainer')).toHaveLength(1);
});
it('test title and nr insertions', function () { it('test title and nr insertions', function () {
const wrapper = shallow(<HomePage/>); const wrapper = shallow(<HomePage/>);

View File

@ -279,8 +279,6 @@ export class Player extends React.Component<myprops, mystate> {
APINode.Video, APINode.Video,
{action: 'loadVideo', MovieId: parseInt(this.props.match.params.id, 10)}, {action: 'loadVideo', MovieId: parseInt(this.props.match.params.id, 10)},
(result: VideoTypes.loadVideoType) => { (result: VideoTypes.loadVideoType) => {
console.log(result);
console.log(process.env.REACT_APP_CUST_BACK_DOMAIN);
this.setState({ this.setState({
sources: { sources: {
type: 'video', type: 'video',

View File

@ -1,7 +1,6 @@
import {shallow} from 'enzyme'; import {shallow} from 'enzyme';
import React from 'react'; import React from 'react';
import MovieSettings from './MovieSettings'; import MovieSettings from './MovieSettings';
import {callAPI} from "../../utils/Api";
describe('<MovieSettings/>', function () { describe('<MovieSettings/>', function () {
it('renders without crashing ', function () { it('renders without crashing ', function () {
@ -31,98 +30,4 @@ describe('<MovieSettings/>', function () {
// initial send of reindex request to server // initial send of reindex request to server
expect(global.fetch).toBeCalledTimes(1); expect(global.fetch).toBeCalledTimes(1);
}); });
it('test failing reindex start', done => {
global.fetch = global.prepareFetchApi({success: false});
const wrapper = shallow(<MovieSettings/>);
wrapper.find('button').findWhere(e => e.text() === 'Reindex Movie' && e.type() === 'button').simulate('click');
// initial send of reindex request to server
expect(global.fetch).toBeCalledTimes(1);
process.nextTick(() => {
// reindex already running --> so disable startbdn
expect(wrapper.state()).toMatchObject({startbtnDisabled: true});
global.fetch.mockClear();
done();
});
});
it('content available received and in state', () => {
const wrapper = shallow(<MovieSettings/>);
callAPIMock({
ContentAvailable: true,
Messages: ['firstline', 'secondline']
})
wrapper.instance().updateStatus();
expect(wrapper.state()).toMatchObject({
text: [
'firstline',
'secondline'
]
});
});
it('test reindex with no content available', () => {
callAPIMock({
Messages: [],
ContentAvailable: false
})
global.clearInterval = jest.fn();
const wrapper = shallow(<MovieSettings/>);
wrapper.instance().updateStatus();
// expect the refresh interval to be cleared
expect(global.clearInterval).toBeCalledTimes(1);
// expect startbtn to be reenabled
expect(wrapper.state()).toMatchObject({startbtnDisabled: false});
});
it('test simulate gravity cleanup', () => {
// global.fetch = global.prepareFetchApi('mmi');
callAPIMock({})
const wrapper = shallow(<MovieSettings/>);
wrapper.instance().setState = jest.fn();
wrapper.find('button').findWhere(e => e.text() === 'Cleanup Gravity' && e.type() === 'button').simulate('click');
// initial send of reindex request to server
expect(callAPI).toBeCalledTimes(1);
expect(wrapper.instance().setState).toBeCalledTimes(1);
});
it('expect insertion before existing ones', function () {
const wrapper = shallow(<MovieSettings/>);
callAPIMock({
ContentAvailable: true,
Messages: ['test']
})
wrapper.instance().updateStatus();
expect(wrapper.state()).toMatchObject({
text: ['test']
});
// expect an untouched state if we try to add an empty string...
callAPIMock({
ContentAvailable: true,
Messages: ['']
})
wrapper.instance().updateStatus();
expect(wrapper.state()).toMatchObject({
text: ['', 'test']
});
});
}); });

View File

@ -0,0 +1,61 @@
import * as React from 'react';
import {RouteComponentProps} from 'react-router';
import {withRouter} from 'react-router-dom';
import {APINode, callAPI} from '../../utils/Api';
import {Link} from 'react-router-dom';
import DynamicContentContainer from '../../elements/DynamicContentContainer/DynamicContentContainer';
interface Props extends RouteComponentProps<{id: string}> {}
interface State {
loaded: boolean;
}
interface Episode {
ID: number;
Name: string;
Season: number;
Episode: number;
}
class EpisodePage extends React.Component<Props, State> {
episodes: Episode[] = [];
state = {
loaded: false
};
componentDidMount(): void {
callAPI(APINode.TVShow, {action: 'getEpisodes', ShowID: parseInt(this.props.match.params.id, 10)}, (episodes: Episode[]) => {
this.episodes = episodes;
this.setState({loaded: true});
});
}
render(): JSX.Element {
if (!this.state.loaded) {
return <>loading...</>;
}
return (
<>
<DynamicContentContainer
renderElement={(el): JSX.Element => <EpisodeTile key={el.ID} episode={el} />}
data={this.episodes}
/>
</>
);
}
}
const EpisodeTile = (props: {episode: Episode}): JSX.Element => {
return (
<Link to={'/tvplayer/' + props.episode.ID}>
<div>
Season:{props.episode.Season} Episode:{props.episode.Episode} {props.episode.Name}
</div>
</Link>
);
};
export default withRouter(EpisodePage);

View File

@ -4,6 +4,7 @@ import {APINode, callAPI} from '../../utils/Api';
import {TVShow} from '../../types/ApiTypes'; import {TVShow} from '../../types/ApiTypes';
import DynamicContentContainer from '../../elements/DynamicContentContainer/DynamicContentContainer'; import DynamicContentContainer from '../../elements/DynamicContentContainer/DynamicContentContainer';
import {Route, Switch, useRouteMatch} from 'react-router-dom'; import {Route, Switch, useRouteMatch} from 'react-router-dom';
import EpisodePage from './EpisodePage';
interface State { interface State {
loading: boolean; loading: boolean;
@ -29,7 +30,12 @@ class TVShowPage extends React.Component<Props, State> {
return ( return (
<DynamicContentContainer <DynamicContentContainer
renderElement={(elem): JSX.Element => ( renderElement={(elem): JSX.Element => (
<Preview name={elem.Name} picLoader={(callback): void => callback('')} linkPath={'/tvshows/' + elem.Id} /> <Preview
key={elem.Id}
name={elem.Name}
picLoader={(callback): void => callback('')}
linkPath={'/tvshows/' + elem.Id}
/>
)} )}
data={this.state.loading ? [] : this.data} data={this.state.loading ? [] : this.data}
/> />
@ -42,8 +48,8 @@ export default function (): JSX.Element {
return ( return (
<Switch> <Switch>
<Route path={`${match.path}/:episodeID`}> <Route path={`${match.path}/:id`}>
<div>hey from episode page</div> <EpisodePage />
</Route> </Route>
<Route path={match.path}> <Route path={match.path}>
<TVShowPage /> <TVShowPage />

View File

@ -68,7 +68,6 @@ export function refreshAPIToken(callback: (error: string) => void, force?: boole
callFuncQue(result.error); callFuncQue(result.error);
return; return;
} }
console.log(result);
// set api token // set api token
apiToken = result.access_token; apiToken = result.access_token;
// set expire time // set expire time
@ -188,7 +187,6 @@ export function callAPI<T>(
errorcallback: (_: string) => void = (_: string): void => {} errorcallback: (_: string) => void = (_: string): void => {}
): void { ): void {
checkAPITokenValid(() => { checkAPITokenValid(() => {
console.log(apiToken);
fetch(APIPREFIX + apinode, { fetch(APIPREFIX + apinode, {
method: 'POST', method: 'POST',
body: JSON.stringify(fd), body: JSON.stringify(fd),

View File

@ -27,7 +27,7 @@ class StaticInfos {
// trigger onThemeChange handlers // trigger onThemeChange handlers
this.handlers.map((func) => { this.handlers.map((func) => {
return func(); func();
}); });
} }