fix failing tests / remove obsolente ones
add basic structure of episode page
This commit is contained in:
parent
6d41b86120
commit
c30c193ce0
@ -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)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -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": ".",
|
||||||
|
@ -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 => {
|
||||||
|
@ -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);
|
||||||
|
@ -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/>);
|
||||||
|
|
||||||
|
@ -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/>);
|
||||||
|
|
||||||
|
@ -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/>);
|
||||||
|
|
||||||
|
@ -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',
|
||||||
|
@ -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']
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
61
src/pages/TVShowPage/EpisodePage.tsx
Normal file
61
src/pages/TVShowPage/EpisodePage.tsx
Normal 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);
|
@ -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 />
|
||||||
|
@ -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),
|
||||||
|
@ -27,7 +27,7 @@ class StaticInfos {
|
|||||||
|
|
||||||
// trigger onThemeChange handlers
|
// trigger onThemeChange handlers
|
||||||
this.handlers.map((func) => {
|
this.handlers.map((func) => {
|
||||||
return func();
|
func();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user