fix some tests

fix merge issues
This commit is contained in:
2020-12-29 19:39:30 +00:00
parent e11f021efe
commit 80a04456e6
74 changed files with 8067 additions and 4481 deletions

View File

@ -1,140 +0,0 @@
import React from 'react';
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
import Tag from '../../elements/Tag/Tag';
import videocontainerstyle from '../../elements/VideoContainer/VideoContainer.module.css';
import {TagPreview} from '../../elements/Preview/Preview';
import NewTagPopup from '../../elements/Popups/NewTagPopup/NewTagPopup';
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
import {callAPI} from '../../utils/Api';
/**
* Component for Category Page
* Contains a Tag Overview and loads specific Tag videos in VideoContainer
*/
class CategoryPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
loadedtags: [],
selected: null
};
}
componentDidMount() {
// check if predefined category is set
if (this.props.category) {
this.fetchVideoData(this.props.category);
} else {
this.loadTags();
}
}
/**
* render the Title and SideBar component for the Category page
* @returns {JSX.Element} corresponding jsx element for Title and Sidebar
*/
renderSideBarATitle() {
return (
<>
<PageTitle
title='Categories'
subtitle={!this.state.selected ? this.state.loadedtags.length + ' different Tags' : this.state.selected}/>
<SideBar>
<SideBarTitle>Default Tags:</SideBarTitle>
<Tag onclick={(tag) => {this.loadTag(tag);}}>All</Tag>
<Tag onclick={(tag) => {this.loadTag(tag);}}>FullHd</Tag>
<Tag onclick={(tag) => {this.loadTag(tag);}}>LowQuality</Tag>
<Tag onclick={(tag) => {this.loadTag(tag);}}>HD</Tag>
<Line/>
<button data-testid='btnaddtag' className='btn btn-success' onClick={() => {
this.setState({popupvisible: true});
}}>Add a new Tag!
</button>
</SideBar></>
);
}
render() {
return (
<>
{this.renderSideBarATitle()}
{this.state.selected ?
<>
{this.videodata ?
<VideoContainer
data={this.videodata}/> : null}
<button data-testid='backbtn' className='btn btn-success'
onClick={this.loadCategoryPageDefault}>Back
</button>
</> :
<div className={videocontainerstyle.maincontent}>
{this.state.loadedtags ?
this.state.loadedtags.map((m) => (
<TagPreview
key={m.tag_name}
name={m.tag_name}
tag_id={m.tag_id}
categorybinding={this.loadTag}/>
)) :
'loading'}
</div>
}
{this.state.popupvisible ?
<NewTagPopup show={this.state.popupvisible}
onHide={() => {
console.error("setstatecalled!");
this.setState({popupvisible: false});
this.loadTags();
}}/> :
null
}
</>
);
}
/**
* load a specific tag into a new previewcontainer
* @param tagname
*/
loadTag = (tagname) => {
this.fetchVideoData(tagname);
};
/**
* fetch data for a specific tag from backend
* @param tag tagname
*/
fetchVideoData(tag) {
callAPI('video.php', {action: 'getMovies', tag: tag}, result => {
this.videodata = result;
this.setState({selected: null}); // needed to trigger the state reload correctly
this.setState({selected: tag});
});
}
/**
* go back to the default category overview
*/
loadCategoryPageDefault = () => {
this.setState({selected: null});
this.loadTags();
};
/**
* load all available tags from db.
*/
loadTags() {
callAPI('tags.php', {action: 'getAllTags'}, result => {
this.setState({loadedtags: result});
});
}
}
export default CategoryPage;

View File

@ -1,4 +1,4 @@
import {mount, shallow} from 'enzyme';
import {shallow} from 'enzyme';
import React from 'react';
import CategoryPage from './CategoryPage';
@ -8,22 +8,6 @@ describe('<CategoryPage/>', function () {
wrapper.unmount();
});
it('test tag fetch call', done => {
global.fetch = global.prepareFetchApi(['first', 'second']);
const wrapper = shallow(<CategoryPage/>);
expect(global.fetch).toHaveBeenCalledTimes(1);
process.nextTick(() => {
//callback to close window should have called
expect(wrapper.state().loadedtags.length).toBe(2);
global.fetch.mockClear();
done();
});
});
it('test new tag popup', function () {
const wrapper = shallow(<CategoryPage/>);
@ -33,63 +17,31 @@ describe('<CategoryPage/>', function () {
expect(wrapper.find('NewTagPopup')).toHaveLength(1);
});
it('test setpage callback', done => {
global.fetch = global.prepareFetchApi([{}, {}]);
it('test add popup', function () {
const wrapper = shallow(<CategoryPage/>);
wrapper.setState({
loadedtags: [
{
tag_name: 'testname',
tag_id: 42
}
]
});
wrapper.find('TagPreview').dive().find('div').first().simulate('click');
process.nextTick(() => {
// expect callback to have loaded correct tag
expect(wrapper.state().selected).toBe('testname');
global.fetch.mockClear();
done();
});
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
wrapper.setState({popupvisible: true});
expect(wrapper.find('NewTagPopup')).toHaveLength(1);
});
it('test back to category view callback', function () {
it('test hiding of popup', function () {
const wrapper = shallow(<CategoryPage/>);
wrapper.setState({popupvisible: true});
wrapper.find('NewTagPopup').props().onHide();
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
});
it('test setting of subtitle', function () {
const wrapper = shallow(<CategoryPage/>);
wrapper.setState({
selected: 'test'
});
expect(wrapper.state().selected).not.toBeNull();
wrapper.find('[data-testid="backbtn"]').simulate('click');
expect(wrapper.state().selected).toBeNull();
});
expect(wrapper.find('PageTitle').props().subtitle).not.toBe('testtitle');
it('load categorypage with predefined tag', function () {
const func = jest.fn();
CategoryPage.prototype.fetchVideoData = func;
shallow(<CategoryPage category='fullhd'/>);
expect(func).toBeCalledTimes(1);
});
it('test sidebar tag clicks', function () {
const func = jest.fn();
const wrapper = shallow(<CategoryPage category='fullhd'/>);
wrapper.instance().loadTag = func;
expect(func).toBeCalledTimes(0);
wrapper.find('SideBar').find('Tag').forEach(e => {
e.dive().simulate('click');
});
expect(func).toBeCalledTimes(4);
wrapper.instance().setSubTitle('testtitle');
// test if prop of title is set correctly
expect(wrapper.find('PageTitle').props().subtitle).toBe('testtitle');
});
});

View File

@ -0,0 +1,83 @@
import React from 'react';
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
import Tag from '../../elements/Tag/Tag';
import NewTagPopup from '../../elements/Popups/NewTagPopup/NewTagPopup';
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
import {Route, Switch} from 'react-router-dom';
import {DefaultTags} from '../../api/GeneralTypes';
import {CategoryViewWR} from './CategoryView';
import TagView from './TagView';
interface CategoryPageState {
popupvisible: boolean;
subtitle: string;
}
/**
* Component for Category Page
* Contains a Tag Overview and loads specific Tag videos in VideoContainer
*/
class CategoryPage extends React.Component<{}, CategoryPageState> {
constructor(props: {}) {
super(props);
this.state = {
popupvisible: false,
subtitle: ''
};
this.setSubTitle = this.setSubTitle.bind(this);
}
render(): JSX.Element {
return (
<>
<PageTitle
title='Categories'
subtitle={this.state.subtitle}/>
<SideBar>
<SideBarTitle>Default Tags:</SideBarTitle>
<Tag tagInfo={DefaultTags.all}/>
<Tag tagInfo={DefaultTags.fullhd}/>
<Tag tagInfo={DefaultTags.hd}/>
<Tag tagInfo={DefaultTags.lowq}/>
<Line/>
<button data-testid='btnaddtag' className='btn btn-success' onClick={(): void => {
this.setState({popupvisible: true});
}}>Add a new Tag!
</button>
</SideBar>
<Switch>
<Route path='/categories/:id'>
<CategoryViewWR setSubTitle={this.setSubTitle}/>
</Route>
<Route path='/categories'>
<TagView setSubTitle={this.setSubTitle}/>
</Route>
</Switch>
{this.state.popupvisible ?
<NewTagPopup show={this.state.popupvisible}
onHide={(): void => {
this.setState({popupvisible: false});
// this.loadTags();
}}/> :
null
}
</>
);
}
/**
* set the subtitle of this page
* @param subtitle string as subtitle
*/
setSubTitle(subtitle: string): void {
this.setState({subtitle: subtitle});
}
}
export default CategoryPage;

View File

@ -0,0 +1,24 @@
import {shallow} from 'enzyme';
import React from 'react';
import {CategoryView} from './CategoryView';
describe('<CategoryView/>', function () {
function instance() {
return shallow(<CategoryView match={{params: {id: 10}}}/>);
}
it('renders without crashing ', function () {
const wrapper = instance();
wrapper.unmount();
});
it('test backbutton', function () {
const wrapper = instance();
const func = jest.fn();
wrapper.setProps({history: {push: func}});
expect(func).toHaveBeenCalledTimes(0);
wrapper.find('button').simulate('click');
expect(func).toHaveBeenCalledTimes(1);
});
});

View File

@ -0,0 +1,75 @@
import {RouteComponentProps} from 'react-router';
import React from 'react';
import {VideoUnloadedType} from '../../api/VideoTypes';
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
import {callAPI} from '../../utils/Api';
import {withRouter} from 'react-router-dom';
interface CategoryViewProps extends RouteComponentProps<{ id: string }> {
setSubTitle: (title: string) => void
}
interface CategoryViewState {
loaded: boolean
}
/**
* plain class (for unit testing only)
*/
export class CategoryView extends React.Component<CategoryViewProps, CategoryViewState> {
private videodata: VideoUnloadedType[] = [];
constructor(props: CategoryViewProps) {
super(props);
this.state = {
loaded: false
};
}
componentDidMount(): void {
this.fetchVideoData(parseInt(this.props.match.params.id));
}
componentDidUpdate(prevProps: Readonly<CategoryViewProps>, prevState: Readonly<CategoryViewState>): void {
// trigger video refresh if id changed
if (prevProps.match.params.id !== this.props.match.params.id) {
this.setState({loaded: false});
this.fetchVideoData(parseInt(this.props.match.params.id));
}
}
render(): JSX.Element {
return (
<>
{this.state.loaded ?
<VideoContainer
data={this.videodata}/> : null}
<button data-testid='backbtn' className='btn btn-success'
onClick={(): void => {
this.props.history.push('/categories');
}}>Back to Categories
</button>
</>
);
}
/**
* fetch data for a specific tag from backend
* @param id tagid
*/
fetchVideoData(id: number): void {
callAPI<VideoUnloadedType[]>('video.php', {action: 'getMovies', tag: id}, result => {
this.videodata = result;
this.setState({loaded: true});
this.props.setSubTitle(this.videodata.length + ' Videos');
});
}
}
/**
* export with react Router wrapped (default use)
*/
export const CategoryViewWR = withRouter(CategoryView);

View File

@ -0,0 +1,17 @@
import {shallow} from 'enzyme';
import React from 'react';
import TagView from './TagView';
describe('<TagView/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<TagView/>);
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);
});
});

View File

@ -0,0 +1,55 @@
import {TagType} from '../../api/VideoTypes';
import React from 'react';
import videocontainerstyle from '../../elements/VideoContainer/VideoContainer.module.css';
import {Link} from 'react-router-dom';
import {TagPreview} from '../../elements/Preview/Preview';
import {callAPI} from '../../utils/Api';
interface TagViewState {
loadedtags: TagType[];
}
interface props {
setSubTitle: (title: string) => void
}
class TagView extends React.Component<props, TagViewState> {
constructor(props: props) {
super(props);
this.state = {loadedtags: []};
}
componentDidMount(): void {
this.loadTags();
}
render(): JSX.Element {
return (
<>
<div className={videocontainerstyle.maincontent}>
{this.state.loadedtags ?
this.state.loadedtags.map((m) => (
<Link to={'/categories/' + m.tag_id}><TagPreview
key={m.tag_id}
name={m.tag_name}
tag_id={m.tag_id}/></Link>
)) :
'loading'}
</div>
</>
);
}
/**
* load all available tags from db.
*/
loadTags(): void {
callAPI<TagType[]>('tags.php', {action: 'getAllTags'}, result => {
this.setState({loadedtags: result});
this.props.setSubTitle(result.length + ' different Tags');
});
}
}
export default TagView;