fix failing tests / remove obsolente ones
add basic structure of episode page
This commit is contained in:
		@@ -1,15 +1,43 @@
 | 
			
		||||
package api
 | 
			
		||||
 | 
			
		||||
import "openmediacenter/apiGo/database"
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"openmediacenter/apiGo/database"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func AddTvshowHandlers() {
 | 
			
		||||
	var dT struct {
 | 
			
		||||
		TagId int
 | 
			
		||||
		Force bool
 | 
			
		||||
	}
 | 
			
		||||
	AddHandler("getTVShows", TVShowNode, &dT, func() []byte {
 | 
			
		||||
	AddHandler("getTVShows", TVShowNode, nil, func() []byte {
 | 
			
		||||
		query := "SELECT id, name FROM tvshow"
 | 
			
		||||
		rows := database.Query(query)
 | 
			
		||||
		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",
 | 
			
		||||
  "icons": [
 | 
			
		||||
    {
 | 
			
		||||
      "src": "favicon.ico",
 | 
			
		||||
      "sizes": "64x64 32x32 24x24 16x16",
 | 
			
		||||
      "type": "image/x-icon"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "logo192.png",
 | 
			
		||||
      "src": "logo_circle.png",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "sizes": "192x192"
 | 
			
		||||
    },
 | 
			
		||||
    {
 | 
			
		||||
      "src": "logo512.png",
 | 
			
		||||
      "type": "image/png",
 | 
			
		||||
      "sizes": "512x512"
 | 
			
		||||
    }
 | 
			
		||||
  ],
 | 
			
		||||
  "start_url": ".",
 | 
			
		||||
 
 | 
			
		||||
@@ -18,7 +18,7 @@ describe('<App/>', function () {
 | 
			
		||||
    it('are navlinks correct', function () {
 | 
			
		||||
        const wrapper = shallow(<App/>);
 | 
			
		||||
        wrapper.setState({password: false});
 | 
			
		||||
        expect(wrapper.find('.navitem')).toHaveLength(4);
 | 
			
		||||
        expect(wrapper.find('.navitem')).toHaveLength(5);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('test initial fetch from api', done => {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,37 +5,29 @@ import Preview, {TagPreview} from './Preview';
 | 
			
		||||
 | 
			
		||||
describe('<Preview/>', 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();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('picture rendered correctly', done => {
 | 
			
		||||
        const mockSuccessResponse = 'testsrc';
 | 
			
		||||
        const mockJsonPromise = Promise.resolve(mockSuccessResponse);
 | 
			
		||||
        const mockFetchPromise = Promise.resolve({
 | 
			
		||||
            text: () => mockJsonPromise
 | 
			
		||||
        });
 | 
			
		||||
        global.fetch = jest.fn().mockImplementation(() => mockFetchPromise);
 | 
			
		||||
    it('picture rendered correctly', () => {
 | 
			
		||||
        const func = jest.fn();
 | 
			
		||||
        const wrapper = shallow(<Preview movieId={1} name='test' picLoader={callback => {
 | 
			
		||||
            func();
 | 
			
		||||
            callback('42');
 | 
			
		||||
        }}/>);
 | 
			
		||||
 | 
			
		||||
        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
 | 
			
		||||
            expect(wrapper.find('.previewimage').props().src).not.toBeNull();
 | 
			
		||||
        expect(wrapper.find('.previewimage').props().src).toBe('42');
 | 
			
		||||
        // check if preview title renders correctly
 | 
			
		||||
        expect(wrapper.find('.previewtitle').text()).toBe('test');
 | 
			
		||||
 | 
			
		||||
            global.fetch.mockClear();
 | 
			
		||||
            done();
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    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(wrapper.find('.loadAnimation')).toHaveLength(1);
 | 
			
		||||
 
 | 
			
		||||
@@ -8,20 +8,6 @@ describe('<ActorOverviewPage/>', function () {
 | 
			
		||||
        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 () {
 | 
			
		||||
        const wrapper = shallow(<ActorOverviewPage/>);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,13 +8,6 @@ describe('<TagView/>', function () {
 | 
			
		||||
        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 () {
 | 
			
		||||
        const wrapper = shallow(<TagView/>);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,21 +10,6 @@ describe('<HomePage/>', function () {
 | 
			
		||||
        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 () {
 | 
			
		||||
        const wrapper = shallow(<HomePage/>);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -279,8 +279,6 @@ export class Player extends React.Component<myprops, mystate> {
 | 
			
		||||
            APINode.Video,
 | 
			
		||||
            {action: 'loadVideo', MovieId: parseInt(this.props.match.params.id, 10)},
 | 
			
		||||
            (result: VideoTypes.loadVideoType) => {
 | 
			
		||||
                console.log(result);
 | 
			
		||||
                console.log(process.env.REACT_APP_CUST_BACK_DOMAIN);
 | 
			
		||||
                this.setState({
 | 
			
		||||
                    sources: {
 | 
			
		||||
                        type: 'video',
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
import {shallow} from 'enzyme';
 | 
			
		||||
import React from 'react';
 | 
			
		||||
import MovieSettings from './MovieSettings';
 | 
			
		||||
import {callAPI} from "../../utils/Api";
 | 
			
		||||
 | 
			
		||||
describe('<MovieSettings/>', function () {
 | 
			
		||||
    it('renders without crashing ', function () {
 | 
			
		||||
@@ -31,98 +30,4 @@ describe('<MovieSettings/>', function () {
 | 
			
		||||
        // initial send of reindex request to server
 | 
			
		||||
        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 DynamicContentContainer from '../../elements/DynamicContentContainer/DynamicContentContainer';
 | 
			
		||||
import {Route, Switch, useRouteMatch} from 'react-router-dom';
 | 
			
		||||
import EpisodePage from './EpisodePage';
 | 
			
		||||
 | 
			
		||||
interface State {
 | 
			
		||||
    loading: boolean;
 | 
			
		||||
@@ -29,7 +30,12 @@ class TVShowPage extends React.Component<Props, State> {
 | 
			
		||||
        return (
 | 
			
		||||
            <DynamicContentContainer
 | 
			
		||||
                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}
 | 
			
		||||
            />
 | 
			
		||||
@@ -42,8 +48,8 @@ export default function (): JSX.Element {
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <Switch>
 | 
			
		||||
            <Route path={`${match.path}/:episodeID`}>
 | 
			
		||||
                <div>hey from episode page</div>
 | 
			
		||||
            <Route path={`${match.path}/:id`}>
 | 
			
		||||
                <EpisodePage />
 | 
			
		||||
            </Route>
 | 
			
		||||
            <Route path={match.path}>
 | 
			
		||||
                <TVShowPage />
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,6 @@ export function refreshAPIToken(callback: (error: string) => void, force?: boole
 | 
			
		||||
                callFuncQue(result.error);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            console.log(result);
 | 
			
		||||
            // set api token
 | 
			
		||||
            apiToken = result.access_token;
 | 
			
		||||
            // set expire time
 | 
			
		||||
@@ -188,7 +187,6 @@ export function callAPI<T>(
 | 
			
		||||
    errorcallback: (_: string) => void = (_: string): void => {}
 | 
			
		||||
): void {
 | 
			
		||||
    checkAPITokenValid(() => {
 | 
			
		||||
        console.log(apiToken);
 | 
			
		||||
        fetch(APIPREFIX + apinode, {
 | 
			
		||||
            method: 'POST',
 | 
			
		||||
            body: JSON.stringify(fd),
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ class StaticInfos {
 | 
			
		||||
 | 
			
		||||
        // trigger onThemeChange handlers
 | 
			
		||||
        this.handlers.map((func) => {
 | 
			
		||||
            return func();
 | 
			
		||||
            func();
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user