reformattings

no redirect on tagclick on homepage
no multiple add of same tag possible
This commit is contained in:
2020-10-25 18:48:23 +00:00
parent 812c45cb13
commit 777cc2a712
43 changed files with 493 additions and 448 deletions

View File

@ -1,12 +1,12 @@
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 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/NewTagPopup/NewTagPopup";
import PageTitle, {Line} from "../../elements/PageTitle/PageTitle";
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
import {TagPreview} from '../../elements/Preview/Preview';
import NewTagPopup from '../../elements/NewTagPopup/NewTagPopup';
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
/**
* Component for Category Page
@ -40,33 +40,33 @@ class CategoryPage extends React.Component {
<>
<PageTitle
title='Categories'
subtitle={!this.state.selected ? this.state.loadedtags.length + " different Tags" : this.state.selected}/>
subtitle={!this.state.selected ? this.state.loadedtags.length + ' different Tags' : this.state.selected}/>
<SideBar>
<SideBarTitle>Default Tags:</SideBarTitle>
<Tag viewbinding={{
changeRootElement: (e) => {
this.loadTag(e.props.category)
this.loadTag(e.props.category);
}
}}>All</Tag>
<Tag viewbinding={{
changeRootElement: (e) => {
this.loadTag(e.props.category)
this.loadTag(e.props.category);
}
}}>FullHd</Tag>
<Tag viewbinding={{
changeRootElement: (e) => {
this.loadTag(e.props.category)
this.loadTag(e.props.category);
}
}}>LowQuality</Tag>
<Tag viewbinding={{
changeRootElement: (e) => {
this.loadTag(e.props.category)
this.loadTag(e.props.category);
}
}}>HD</Tag>
<Line/>
<button data-testid='btnaddtag' className='btn btn-success' onClick={() => {
this.setState({popupvisible: true})
this.setState({popupvisible: true});
}}>Add a new Tag!
</button>
</SideBar></>
@ -98,7 +98,7 @@ class CategoryPage extends React.Component {
viewbinding={this.props.viewbinding}
categorybinding={this.loadTag}/>
)) :
"loading"}
'loading'}
</div>
}
@ -133,7 +133,7 @@ class CategoryPage extends React.Component {
updateRequest.append('action', 'getMovies');
updateRequest.append('tag', tag);
console.log("fetching data");
console.log('fetching data');
// fetch all videos available
fetch('/api/video.php', {method: 'POST', body: updateRequest})
@ -144,7 +144,7 @@ class CategoryPage extends React.Component {
this.setState({selected: tag});
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
}
@ -170,7 +170,7 @@ class CategoryPage extends React.Component {
this.setState({loadedtags: result});
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
}
}

View File

@ -1,6 +1,6 @@
import {mount, shallow} from "enzyme";
import React from "react";
import CategoryPage from "./CategoryPage";
import {mount, shallow} from 'enzyme';
import React from 'react';
import CategoryPage from './CategoryPage';
describe('<CategoryPage/>', function () {
it('renders without crashing ', function () {
@ -9,7 +9,7 @@ describe('<CategoryPage/>', function () {
});
it('test tag fetch call', done => {
global.fetch = global.prepareFetchApi(["first", "second"]);
global.fetch = global.prepareFetchApi(['first', 'second']);
const wrapper = shallow(<CategoryPage/>);
@ -38,7 +38,7 @@ describe('<CategoryPage/>', function () {
process.nextTick(() => {
//callback to close window should have called
expect(message).toBe("no connection to backend");
expect(message).toBe('no connection to backend');
global.fetch.mockClear();
done();
@ -48,14 +48,14 @@ describe('<CategoryPage/>', function () {
it('test new tag popup', function () {
const wrapper = mount(<CategoryPage/>);
expect(wrapper.find("NewTagPopup")).toHaveLength(0);
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
wrapper.find('[data-testid="btnaddtag"]').simulate('click');
// newtagpopup should be showing now
expect(wrapper.find("NewTagPopup")).toHaveLength(1);
expect(wrapper.find('NewTagPopup')).toHaveLength(1);
// click close button in modal
wrapper.find(".modal-header").find("button").simulate("click");
expect(wrapper.find("NewTagPopup")).toHaveLength(0);
wrapper.find('.modal-header').find('button').simulate('click');
expect(wrapper.find('NewTagPopup')).toHaveLength(0);
});
it('test setpage callback', done => {
@ -66,17 +66,17 @@ describe('<CategoryPage/>', function () {
wrapper.setState({
loadedtags: [
{
tag_name: "testname",
tag_name: 'testname',
tag_id: 42
}
]
});
wrapper.find("TagPreview").find("div").first().simulate("click");
wrapper.find('TagPreview').find('div').first().simulate('click');
process.nextTick(() => {
// expect callback to have loaded correct tag
expect(wrapper.state().selected).toBe("testname");
expect(wrapper.state().selected).toBe('testname');
global.fetch.mockClear();
done();
@ -87,10 +87,10 @@ describe('<CategoryPage/>', function () {
const wrapper = shallow(<CategoryPage/>);
wrapper.setState({
selected: "test"
selected: 'test'
});
expect(wrapper.state().selected).not.toBeNull();
wrapper.find('[data-testid="backbtn"]').simulate("click");
wrapper.find('[data-testid="backbtn"]').simulate('click');
expect(wrapper.state().selected).toBeNull();
});
@ -112,9 +112,9 @@ describe('<CategoryPage/>', function () {
console.log(wrapper.debug());
expect(func).toBeCalledTimes(0);
wrapper.find("SideBar").find("Tag").forEach(e => {
e.simulate("click");
})
wrapper.find('SideBar').find('Tag').forEach(e => {
e.simulate('click');
});
expect(func).toBeCalledTimes(4);

View File

@ -1,17 +1,17 @@
import React from "react";
import SideBar, {SideBarItem, SideBarTitle} from "../../elements/SideBar/SideBar";
import Tag from "../../elements/Tag/Tag";
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
import React from 'react';
import SideBar, {SideBarItem, SideBarTitle} from '../../elements/SideBar/SideBar';
import Tag from '../../elements/Tag/Tag';
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
import style from "./HomePage.module.css"
import PageTitle, {Line} from "../../elements/PageTitle/PageTitle";
import style from './HomePage.module.css';
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
/**
* The home page component showing on the initial pageload
*/
class HomePage extends React.Component {
/** keyword variable needed temporary store search keyword */
keyword = "";
keyword = '';
constructor(props, context) {
super(props, context);
@ -24,7 +24,7 @@ class HomePage extends React.Component {
sdvideonr: null,
tagnr: null
},
tag: "All",
subtitle: 'All Videos',
data: [],
selectionnr: 0
};
@ -32,7 +32,7 @@ class HomePage extends React.Component {
componentDidMount() {
// initial get of all videos
this.fetchVideoData("all");
this.fetchVideoData('All');
this.fetchStartData();
}
@ -47,7 +47,7 @@ class HomePage extends React.Component {
updateRequest.append('action', 'getMovies');
updateRequest.append('tag', tag);
console.log("fetching data");
console.log('fetching data from' + tag);
// fetch all videos available
fetch('/api/video.php', {method: 'POST', body: updateRequest})
@ -58,11 +58,12 @@ class HomePage extends React.Component {
});
this.setState({
data: result,
selectionnr: result.length
selectionnr: result.length,
tag: tag + ' Videos'
});
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
}
@ -88,7 +89,7 @@ class HomePage extends React.Component {
});
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
}
@ -98,7 +99,7 @@ class HomePage extends React.Component {
* @param keyword The keyword to search for
*/
searchVideos(keyword) {
console.log("search called");
console.log('search called');
const updateRequest = new FormData();
updateRequest.append('action', 'getSearchKeyWord');
@ -113,11 +114,12 @@ class HomePage extends React.Component {
});
this.setState({
data: result,
selectionnr: result.length
selectionnr: result.length,
tag: 'Search result: ' + keyword
});
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
}
@ -126,15 +128,15 @@ class HomePage extends React.Component {
<>
<PageTitle
title='Home Page'
subtitle={this.state.tag + " Videos - " + this.state.selectionnr}>
<form className={"form-inline " + style.searchform} onSubmit={(e) => {
subtitle={this.state.subtitle + ' - ' + this.state.selectionnr}>
<form className={'form-inline ' + style.searchform} onSubmit={(e) => {
e.preventDefault();
this.searchVideos(this.keyword);
}}>
<input data-testid='searchtextfield' className='form-control mr-sm-2'
type='text' placeholder='Search'
onChange={(e) => {
this.keyword = e.target.value
this.keyword = e.target.value;
}}/>
<button data-testid='searchbtnsubmit' className='btn btn-success' type='submit'>Search</button>
</form>
@ -149,10 +151,10 @@ class HomePage extends React.Component {
<SideBarItem><b>{this.state.sideinfo.tagnr}</b> different Tags!</SideBarItem>
<Line/>
<SideBarTitle>Default Tags:</SideBarTitle>
<Tag viewbinding={this.props.viewbinding}>All</Tag>
<Tag viewbinding={this.props.viewbinding}>FullHd</Tag>
<Tag viewbinding={this.props.viewbinding}>LowQuality</Tag>
<Tag viewbinding={this.props.viewbinding}>HD</Tag>
<Tag onclick={() => this.fetchVideoData('All')}>All</Tag>
<Tag onclick={() => this.fetchVideoData('FullHd')}>FullHd</Tag>
<Tag onclick={() => this.fetchVideoData('LowQuality')}>LowQuality</Tag>
<Tag onclick={() => this.fetchVideoData('HD')}>HD</Tag>
</SideBar>
{this.state.data.length !== 0 ?
<VideoContainer

View File

@ -1,7 +1,7 @@
import {shallow} from "enzyme";
import React from "react";
import HomePage from "./HomePage";
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
import {shallow} from 'enzyme';
import React from 'react';
import HomePage from './HomePage';
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
describe('<HomePage/>', function () {
it('renders without crashing ', function () {
@ -12,7 +12,7 @@ describe('<HomePage/>', function () {
it('test data insertion', function () {
const wrapper = shallow(<HomePage/>);
expect(wrapper.find("VideoContainer")).toHaveLength(0);
expect(wrapper.find('VideoContainer')).toHaveLength(0);
wrapper.setState({
data: [
@ -21,20 +21,20 @@ describe('<HomePage/>', function () {
});
// there shoud be loaded the Videocontainer element into dom after fetching videos correctly
expect(wrapper.find("VideoContainer")).toHaveLength(1);
expect(wrapper.find('VideoContainer')).toHaveLength(1);
});
it('test title and nr insertions', function () {
const wrapper = shallow(<HomePage/>);
expect(wrapper.find("PageTitle").props().subtitle).toBe("All Videos - 0");
expect(wrapper.find('PageTitle').props().subtitle).toBe('All Videos - 0');
wrapper.setState({
tag: "testtag",
subtitle: 'testsubtitle',
selectionnr: 42
});
expect(wrapper.find("PageTitle").props().subtitle).toBe("testtag Videos - 42");
expect(wrapper.find('PageTitle').props().subtitle).toBe('testsubtitle - 42');
});
it('test search field', done => {
@ -43,7 +43,7 @@ describe('<HomePage/>', function () {
const wrapper = shallow(<HomePage/>);
wrapper.find('[data-testid="searchtextfield"]').simulate('change', {target: {value: 'testvalue'}});
wrapper.find('[data-testid="searchbtnsubmit"]').simulate("click");
wrapper.find('[data-testid="searchbtnsubmit"]').simulate('click');
process.nextTick(() => {
// state to be set correctly with response
@ -60,7 +60,7 @@ describe('<HomePage/>', function () {
const wrapper = shallow(<HomePage/>);
const fakeEvent = {preventDefault: () => console.log('preventDefault')};
wrapper.find(".searchform").simulate('submit', fakeEvent);
wrapper.find('.searchform').simulate('submit', fakeEvent);
expect(wrapper.state().selectionnr).toBe(0);
@ -92,4 +92,34 @@ describe('<HomePage/>', function () {
done();
});
});
it('test tag click', done => {
global.fetch = prepareFetchApi(['test1', 'test2']);
const wrapper = shallow(<HomePage/>);
const tags = wrapper.find('SideBar').dive().find('Tag');
let i = 0;
function testBtn(e) {
e.dive().simulate('click');
process.nextTick(() => {
process.nextTick(() => {
// state to be set correctly with response
console.log('see ifits same');
expect(wrapper.state()).toMatchObject({data: ['test1', 'test2']});
wrapper.state.data = [];
i++;
if (i >= tags.length) {
done();
} else {
testBtn(tags.at(i));
}
});
});
}
testBtn(tags.first());
});
});

View File

@ -1,11 +1,11 @@
import React from "react";
import style from "./Player.module.css"
import React from 'react';
import style from './Player.module.css';
import {PlyrComponent} from 'plyr-react';
import SideBar, {SideBarItem, SideBarTitle} from "../../elements/SideBar/SideBar";
import Tag from "../../elements/Tag/Tag";
import AddTagPopup from "../../elements/AddTagPopup/AddTagPopup";
import PageTitle, {Line} from "../../elements/PageTitle/PageTitle";
import SideBar, {SideBarItem, SideBarTitle} from '../../elements/SideBar/SideBar';
import Tag from '../../elements/Tag/Tag';
import AddTagPopup from '../../elements/AddTagPopup/AddTagPopup';
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
/**
@ -26,7 +26,7 @@ class Player extends React.Component {
'settings', // Settings menu
'airplay', // Airplay (currently Safari only)
'download', // Show a download button with a link to either the current source or a custom URL you specify in your options
'fullscreen', // Toggle fullscreen
'fullscreen' // Toggle fullscreen
]
};
@ -66,28 +66,36 @@ class Player extends React.Component {
fetch('/api/tags.php', {method: 'POST', body: updateRequest})
.then((response) => response.json()
.then((result) => {
if (result.result !== "success") {
console.error("error occured while writing to db -- todo error handling");
if (result.result !== 'success') {
console.error('error occured while writing to db -- todo error handling');
console.error(result.result);
} else {
// update tags if successful
let array = [...this.state.suggesttag]; // make a separate copy of the array
const index = array.map(function (e) {
return e.tag_id;
}).indexOf(tag_id);
// check if tag has already been added
const tagindwx = this.state.tags.map(function (e) {
return e.tag_name;
}).indexOf(tag_name);
// check if tag is available in quickadds
if (index !== -1) {
array.splice(index, 1);
// only add tag if it isn't already there
if (tagindwx === -1) {
// update tags if successful
let array = [...this.state.suggesttag]; // make a separate copy of the array (because of setState)
const quickaddindex = this.state.suggesttag.map(function (e) {
return e.tag_id;
}).indexOf(tag_id);
this.setState({
tags: [...this.state.tags, {tag_name: tag_name}],
suggesttag: array
});
} else {
this.setState({
tags: [...this.state.tags, {tag_name: tag_name}]
});
// check if tag is available in quickadds
if (quickaddindex !== -1) {
array.splice(quickaddindex, 1);
this.setState({
tags: [...this.state.tags, {tag_name: tag_name}],
suggesttag: array
});
} else {
this.setState({
tags: [...this.state.tags, {tag_name: tag_name}]
});
}
}
}
}));
@ -170,7 +178,7 @@ class Player extends React.Component {
<button className='btn btn-info' onClick={() => this.setState({popupvisible: true})}>Give this
Video a Tag
</button>
<button className='btn btn-danger' onClick={() => {this.deleteVideo()}}>Delete Video</button>
<button className='btn btn-danger' onClick={() => {this.deleteVideo();}}>Delete Video</button>
</div>
</div>
<button className={style.closebutton} onClick={() => this.closebtn()}>Close</button>
@ -200,7 +208,7 @@ class Player extends React.Component {
{
src: result.movie_url,
type: 'video/mp4',
size: 1080,
size: 1080
}
],
poster: result.thumbnail
@ -229,11 +237,11 @@ class Player extends React.Component {
fetch('/api/video.php', {method: 'POST', body: updateRequest})
.then((response) => response.json()
.then((result) => {
if (result.result === "success") {
if (result.result === 'success') {
// likes +1 --> avoid reload of all data
this.setState({likes: this.state.likes + 1})
this.setState({likes: this.state.likes + 1});
} else {
console.error("an error occured while liking");
console.error('an error occured while liking');
console.error(result);
}
}));
@ -258,11 +266,11 @@ class Player extends React.Component {
fetch('/api/video.php', {method: 'POST', body: updateRequest})
.then((response) => response.json()
.then((result) => {
if (result.result === "success") {
if (result.result === 'success') {
// return to last element if successful
this.props.viewbinding.returnToLastElement();
} else {
console.error("an error occured while liking");
console.error('an error occured while liking');
console.error(result);
}
}));

View File

@ -1,6 +1,6 @@
import {shallow} from "enzyme";
import React from "react";
import Player from "./Player";
import {shallow} from 'enzyme';
import React from 'react';
import Player from './Player';
describe('<Player/>', function () {
it('renders without crashing ', function () {
@ -16,11 +16,11 @@ describe('<Player/>', function () {
{
src: '/tstvid.mp4',
type: 'video/mp4',
size: 1080,
size: 1080
}
]
});
expect(wrapper.find("r")).toHaveLength(1);
expect(wrapper.find('r')).toHaveLength(1);
});
function simulateLikeButtonClick() {
@ -28,7 +28,7 @@ describe('<Player/>', function () {
// initial fetch for getting movie data
expect(global.fetch).toHaveBeenCalledTimes(1);
wrapper.find('.videoactions').find("button").first().simulate('click');
wrapper.find('.videoactions').find('button').first().simulate('click');
// fetch for liking
expect(global.fetch).toHaveBeenCalledTimes(2);
@ -69,20 +69,20 @@ describe('<Player/>', function () {
it('show tag popup', function () {
const wrapper = shallow(<Player/>);
expect(wrapper.find("AddTagPopup")).toHaveLength(0);
expect(wrapper.find('AddTagPopup')).toHaveLength(0);
// todo dynamic button find without index
wrapper.find('.videoactions').find("button").at(1).simulate('click');
wrapper.find('.videoactions').find('button').at(1).simulate('click');
// addtagpopup should be showing now
expect(wrapper.find("AddTagPopup")).toHaveLength(1);
expect(wrapper.find('AddTagPopup')).toHaveLength(1);
});
it('test delete button', done => {
const wrapper = shallow(<Player viewbinding={{
returnToLastElement: jest.fn()
}}/>);
global.fetch = prepareFetchApi({result: "success"});
global.fetch = prepareFetchApi({result: 'success'});
wrapper.find('.videoactions').find("button").at(2).simulate('click');
wrapper.find('.videoactions').find('button').at(2).simulate('click');
process.nextTick(() => {
// refetch is called so fetch called 3 times
@ -101,7 +101,7 @@ describe('<Player/>', function () {
wrapper.setProps({
viewbinding: {
returnToLastElement: () => {
func()
func();
}
}
});
@ -115,7 +115,7 @@ describe('<Player/>', function () {
it('inserts Tags correctly', function () {
const wrapper = shallow(<Player/>);
expect(wrapper.find("Tag")).toHaveLength(0);
expect(wrapper.find('Tag')).toHaveLength(0);
wrapper.setState({
tags: [
@ -124,7 +124,7 @@ describe('<Player/>', function () {
]
});
expect(wrapper.find("Tag")).toHaveLength(2);
expect(wrapper.find('Tag')).toHaveLength(2);
});
it('inserts tag quickadd correctly', function () {
@ -137,7 +137,7 @@ describe('<Player/>', function () {
global.fetch = prepareFetchApi({result: 'success'});
// render tag subcomponent
const tag = wrapper.find("Tag").first().dive();
const tag = wrapper.find('Tag').first().dive();
tag.simulate('click');
process.nextTick(() => {
@ -155,7 +155,7 @@ describe('<Player/>', function () {
global.console.error = jest.fn();
// render tag subcomponent
const tag = wrapper.find("Tag").first().dive();
const tag = wrapper.find('Tag').first().dive();
tag.simulate('click');
process.nextTick(() => {
@ -169,15 +169,15 @@ describe('<Player/>', function () {
function generatetag() {
const wrapper = shallow(<Player/>);
expect(wrapper.find("Tag")).toHaveLength(0);
expect(wrapper.find('Tag')).toHaveLength(0);
wrapper.setState({
suggesttag: [
{tag_name: 'first', tag_id: 1},
{tag_name: 'first', tag_id: 1}
]
});
expect(wrapper.find("Tag")).toHaveLength(1);
expect(wrapper.find('Tag')).toHaveLength(1);
return wrapper;
}

View File

@ -1,9 +1,9 @@
import React from "react";
import style from "./RandomPage.module.css"
import SideBar, {SideBarTitle} from "../../elements/SideBar/SideBar";
import Tag from "../../elements/Tag/Tag";
import PageTitle from "../../elements/PageTitle/PageTitle";
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
import React from 'react';
import style from './RandomPage.module.css';
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
import Tag from '../../elements/Tag/Tag';
import PageTitle from '../../elements/PageTitle/PageTitle';
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
/**
* Randompage shuffles random viedeopreviews and provides a shuffle btn
@ -81,7 +81,7 @@ class RandomPage extends React.Component {
});
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
}
}

View File

@ -1,6 +1,6 @@
import {shallow} from "enzyme";
import React from "react";
import RandomPage from "./RandomPage";
import {shallow} from 'enzyme';
import React from 'react';
import RandomPage from './RandomPage';
describe('<RandomPage/>', function () {
it('renders without crashing ', function () {
@ -28,7 +28,7 @@ describe('<RandomPage/>', function () {
]
});
wrapper.find(".btnshuffle").simulate("click");
wrapper.find('.btnshuffle').simulate('click');
expect(global.fetch).toBeCalledTimes(2);
});
@ -38,11 +38,11 @@ describe('<RandomPage/>', function () {
wrapper.setState({
tags: [
{tag_name: "test1"},
{tag_name: "test2"}
{tag_name: 'test1'},
{tag_name: 'test2'}
]
});
expect(wrapper.find("Tag")).toHaveLength(2);
expect(wrapper.find('Tag')).toHaveLength(2);
});
});

View File

@ -1,10 +1,10 @@
import React from "react";
import {Button, Col, Form} from "react-bootstrap";
import style from "./GeneralSettings.module.css"
import GlobalInfos from "../../GlobalInfos";
import InfoHeaderItem from "../../elements/InfoHeaderItem/InfoHeaderItem";
import {faArchive, faBalanceScaleLeft, faRulerVertical} from "@fortawesome/free-solid-svg-icons";
import {faAddressCard} from "@fortawesome/free-regular-svg-icons";
import React from 'react';
import {Button, Col, Form} from 'react-bootstrap';
import style from './GeneralSettings.module.css';
import GlobalInfos from '../../GlobalInfos';
import InfoHeaderItem from '../../elements/InfoHeaderItem/InfoHeaderItem';
import {faArchive, faBalanceScaleLeft, faRulerVertical} from '@fortawesome/free-solid-svg-icons';
import {faAddressCard} from '@fortawesome/free-regular-svg-icons';
/**
* Component for Generalsettings tag on Settingspage
@ -18,10 +18,10 @@ class GeneralSettings extends React.Component {
passwordsupport: false,
tmdbsupport: null,
videopath: "",
tvshowpath: "",
mediacentername: "",
password: "",
videopath: '',
tvshowpath: '',
mediacentername: '',
password: '',
videonr: null,
dbsize: null,
@ -44,7 +44,7 @@ class GeneralSettings extends React.Component {
subtext='Videos in Gravity'
icon={faArchive}/>
<InfoHeaderItem backColor='yellow'
text={this.state.dbsize !== undefined ? this.state.dbsize + " MB" : undefined}
text={this.state.dbsize !== undefined ? this.state.dbsize + ' MB' : undefined}
subtext='Database size'
icon={faRulerVertical}/>
<InfoHeaderItem backColor='green'
@ -83,7 +83,7 @@ class GeneralSettings extends React.Component {
label='Enable Password support'
checked={this.state.passwordsupport}
onChange={() => {
this.setState({passwordsupport: !this.state.passwordsupport})
this.setState({passwordsupport: !this.state.passwordsupport});
}}
/>
@ -102,7 +102,7 @@ class GeneralSettings extends React.Component {
label='Enable TMDB video grabbing support'
checked={this.state.tmdbsupport}
onChange={() => {
this.setState({tmdbsupport: !this.state.tmdbsupport})
this.setState({tmdbsupport: !this.state.tmdbsupport});
}}
/>
@ -168,21 +168,21 @@ class GeneralSettings extends React.Component {
const updateRequest = new FormData();
updateRequest.append('action', 'saveGeneralSettings');
updateRequest.append('password', this.state.passwordsupport ? this.state.password : "-1");
updateRequest.append('password', this.state.passwordsupport ? this.state.password : '-1');
updateRequest.append('videopath', this.state.videopath);
updateRequest.append('tvshowpath', this.state.tvshowpath);
updateRequest.append('mediacentername', this.state.mediacentername);
updateRequest.append("tmdbsupport", this.state.tmdbsupport);
updateRequest.append("darkmodeenabled", GlobalInfos.isDarkTheme().toString());
updateRequest.append('tmdbsupport', this.state.tmdbsupport);
updateRequest.append('darkmodeenabled', GlobalInfos.isDarkTheme().toString());
fetch('/api/settings.php', {method: 'POST', body: updateRequest})
.then((response) => response.json()
.then((result) => {
if (result.success) {
console.log("successfully saved settings");
console.log('successfully saved settings');
// todo 2020-07-10: popup success
} else {
console.log("failed to save settings");
console.log('failed to save settings');
// todo 2020-07-10: popup error
}
}));

View File

@ -1,7 +1,7 @@
import {shallow} from "enzyme";
import React from "react";
import GeneralSettings from "./GeneralSettings";
import GlobalInfos from "../../GlobalInfos";
import {shallow} from 'enzyme';
import React from 'react';
import GeneralSettings from './GeneralSettings';
import GlobalInfos from '../../GlobalInfos';
describe('<GeneralSettings/>', function () {
it('renders without crashing ', function () {
@ -12,10 +12,10 @@ describe('<GeneralSettings/>', function () {
it('test password hide/show switchbutton', function () {
const wrapper = shallow(<GeneralSettings/>);
expect(wrapper.find("[data-testid='passwordfield']")).toHaveLength(0);
wrapper.find("FormCheck").findWhere(it => it.props().label === "Enable Password support").simulate("change");
expect(wrapper.find('[data-testid=\'passwordfield\']')).toHaveLength(0);
wrapper.find('FormCheck').findWhere(it => it.props().label === 'Enable Password support').simulate('change');
expect(wrapper.find("[data-testid='passwordfield']")).toHaveLength(1);
expect(wrapper.find('[data-testid=\'passwordfield\']')).toHaveLength(1);
});
it('test theme switchbutton', function () {
@ -23,7 +23,7 @@ describe('<GeneralSettings/>', function () {
GlobalInfos.enableDarkTheme(false);
expect(GlobalInfos.isDarkTheme()).toBe(false);
wrapper.find("[data-testid='darktheme-switch']").simulate("change");
wrapper.find('[data-testid=\'darktheme-switch\']').simulate('change');
expect(GlobalInfos.isDarkTheme()).toBe(true);
});
@ -34,7 +34,7 @@ describe('<GeneralSettings/>', function () {
expect(global.fetch).toBeCalledTimes(0);
const fakeEvent = {preventDefault: () => console.log('preventDefault')};
wrapper.find("[data-testid='mainformsettings']").simulate("submit", fakeEvent);
wrapper.find('[data-testid=\'mainformsettings\']').simulate('submit', fakeEvent);
expect(global.fetch).toBeCalledTimes(1);
process.nextTick(() => {
@ -52,7 +52,7 @@ describe('<GeneralSettings/>', function () {
expect(global.fetch).toBeCalledTimes(0);
const fakeEvent = {preventDefault: () => console.log('preventDefault')};
wrapper.find("[data-testid='mainformsettings']").simulate("submit", fakeEvent);
wrapper.find('[data-testid=\'mainformsettings\']').simulate('submit', fakeEvent);
expect(global.fetch).toBeCalledTimes(1);
process.nextTick(() => {
@ -66,39 +66,39 @@ describe('<GeneralSettings/>', function () {
it('test videopath change event', function () {
const wrapper = shallow(<GeneralSettings/>);
expect(wrapper.state().videopath).not.toBe("test");
expect(wrapper.state().videopath).not.toBe('test');
const event = {target: {name: "pollName", value: "test"}};
wrapper.find("[data-testid='videpathform']").find("FormControl").simulate("change", event);
expect(wrapper.state().videopath).toBe("test");
const event = {target: {name: 'pollName', value: 'test'}};
wrapper.find('[data-testid=\'videpathform\']').find('FormControl').simulate('change', event);
expect(wrapper.state().videopath).toBe('test');
});
it('test tvshowpath change event', function () {
const wrapper = shallow(<GeneralSettings/>);
const event = {target: {name: "pollName", value: "test"}};
expect(wrapper.state().tvshowpath).not.toBe("test");
wrapper.find("[data-testid='tvshowpath']").find("FormControl").simulate("change", event);
expect(wrapper.state().tvshowpath).toBe("test");
const event = {target: {name: 'pollName', value: 'test'}};
expect(wrapper.state().tvshowpath).not.toBe('test');
wrapper.find('[data-testid=\'tvshowpath\']').find('FormControl').simulate('change', event);
expect(wrapper.state().tvshowpath).toBe('test');
});
it('test mediacentername-form change event', function () {
const wrapper = shallow(<GeneralSettings/>);
const event = {target: {name: "pollName", value: "test"}};
expect(wrapper.state().mediacentername).not.toBe("test");
wrapper.find("[data-testid='nameform']").find("FormControl").simulate("change", event);
expect(wrapper.state().mediacentername).toBe("test");
const event = {target: {name: 'pollName', value: 'test'}};
expect(wrapper.state().mediacentername).not.toBe('test');
wrapper.find('[data-testid=\'nameform\']').find('FormControl').simulate('change', event);
expect(wrapper.state().mediacentername).toBe('test');
});
it('test password-form change event', function () {
const wrapper = shallow(<GeneralSettings/>);
wrapper.setState({passwordsupport: true});
const event = {target: {name: "pollName", value: "test"}};
expect(wrapper.state().password).not.toBe("test");
wrapper.find("[data-testid='passwordfield']").find("FormControl").simulate("change", event);
expect(wrapper.state().password).toBe("test");
const event = {target: {name: 'pollName', value: 'test'}};
expect(wrapper.state().password).not.toBe('test');
wrapper.find('[data-testid=\'passwordfield\']').find('FormControl').simulate('change', event);
expect(wrapper.state().password).toBe('test');
});
it('test tmdbsupport change event', function () {
@ -106,12 +106,12 @@ describe('<GeneralSettings/>', function () {
wrapper.setState({tmdbsupport: true});
expect(wrapper.state().tmdbsupport).toBe(true);
wrapper.find("[data-testid='tmdb-switch']").simulate("change");
wrapper.find('[data-testid=\'tmdb-switch\']').simulate('change');
expect(wrapper.state().tmdbsupport).toBe(false);
});
it('test insertion of 4 infoheaderitems', function () {
const wrapper = shallow(<GeneralSettings/>);
expect(wrapper.find("InfoHeaderItem").length).toBe(4);
expect(wrapper.find('InfoHeaderItem').length).toBe(4);
});
});

View File

@ -1,5 +1,5 @@
import React from "react";
import style from "./MovieSettings.module.css"
import React from 'react';
import style from './MovieSettings.module.css';
/**
* Component for MovieSettings on Settingspage
@ -28,10 +28,10 @@ class MovieSettings extends React.Component {
<>
<button disabled={this.state.startbtnDisabled}
className='btn btn-success'
onClick={() => {this.startReindex()}}>Reindex Movie
onClick={() => {this.startReindex();}}>Reindex Movie
</button>
<button className='btn btn-warning'
onClick={() => {this.cleanupGravity()}}>Cleanup Gravity
onClick={() => {this.cleanupGravity();}}>Cleanup Gravity
</button>
<div className={style.indextextarea}>{this.state.text.map(m => (
<div className='textarea-element'>{m}</div>
@ -49,23 +49,23 @@ class MovieSettings extends React.Component {
this.setState({startbtnDisabled: true});
console.log("starting");
console.log('starting');
const request = new FormData();
request.append("action", "startReindex");
request.append('action', 'startReindex');
// fetch all videos available
fetch('/api/settings.php', {method: 'POST', body: request})
.then((response) => response.json()
.then((result) => {
console.log(result);
if (result.success) {
console.log("started successfully");
console.log('started successfully');
} else {
console.log("error, reindex already running");
console.log('error, reindex already running');
this.setState({startbtnDisabled: true});
}
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
if (this.myinterval) {
clearInterval(this.myinterval);
@ -78,7 +78,7 @@ class MovieSettings extends React.Component {
*/
updateStatus = () => {
const request = new FormData();
request.append("action", "getStatusMessage");
request.append('action', 'getStatusMessage');
fetch('/api/settings.php', {method: 'POST', body: request})
.then((response) => response.json()
@ -88,7 +88,7 @@ class MovieSettings extends React.Component {
// todo 2020-07-4: scroll to bottom of div here
this.setState({
// insert a string for each line
text: [...result.message.split("\n"),
text: [...result.message.split('\n'),
...this.state.text]
});
} else {
@ -99,7 +99,7 @@ class MovieSettings extends React.Component {
}
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
};
@ -108,7 +108,7 @@ class MovieSettings extends React.Component {
*/
cleanupGravity() {
const request = new FormData();
request.append("action", "cleanupGravity");
request.append('action', 'cleanupGravity');
fetch('/api/settings.php', {method: 'POST', body: request})
.then((response) => response.text()
@ -118,7 +118,7 @@ class MovieSettings extends React.Component {
});
}))
.catch(() => {
console.log("no connection to backend");
console.log('no connection to backend');
});
}
}

View File

@ -1,6 +1,6 @@
import {shallow} from "enzyme";
import React from "react";
import MovieSettings from "./MovieSettings";
import {shallow} from 'enzyme';
import React from 'react';
import MovieSettings from './MovieSettings';
describe('<MovieSettings/>', function () {
it('renders without crashing ', function () {
@ -13,19 +13,19 @@ describe('<MovieSettings/>', function () {
wrapper.setState({
text: [
"firstline",
"secline"
'firstline',
'secline'
]
});
expect(wrapper.find(".indextextarea").find(".textarea-element")).toHaveLength(2);
expect(wrapper.find('.indextextarea').find('.textarea-element')).toHaveLength(2);
});
it('test simulate reindex', function () {
global.fetch = global.prepareFetchApi({success: true});
const wrapper = shallow(<MovieSettings/>);
wrapper.find("button").findWhere(e => e.text() === "Reindex Movie" && e.type() === "button").simulate("click");
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);
@ -35,7 +35,7 @@ describe('<MovieSettings/>', function () {
global.fetch = global.prepareFetchApi({success: false});
const wrapper = shallow(<MovieSettings/>);
wrapper.find("button").findWhere(e => e.text() === "Reindex Movie" && e.type() === "button").simulate("click");
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);
@ -52,7 +52,7 @@ describe('<MovieSettings/>', function () {
it('content available received and in state', done => {
global.fetch = global.prepareFetchApi({
contentAvailable: true,
message: "firstline\nsecondline"
message: 'firstline\nsecondline'
});
const wrapper = shallow(<MovieSettings/>);
wrapper.instance().updateStatus();
@ -60,8 +60,8 @@ describe('<MovieSettings/>', function () {
process.nextTick(() => {
expect(wrapper.state()).toMatchObject({
text: [
"firstline",
"secondline"
'firstline',
'secondline'
]
});
@ -70,7 +70,7 @@ describe('<MovieSettings/>', function () {
});
});
it('test reindex with no content available', done=> {
it('test reindex with no content available', done => {
global.fetch = global.prepareFetchApi({
contentAvailable: false
});
@ -93,11 +93,11 @@ describe('<MovieSettings/>', function () {
});
it('test simulate gravity cleanup', done => {
global.fetch = global.prepareFetchApi("mmi");
global.fetch = global.prepareFetchApi('mmi');
const wrapper = shallow(<MovieSettings/>);
wrapper.instance().setState = jest.fn(),
wrapper.find("button").findWhere(e => e.text() === "Cleanup Gravity" && e.type() === "button").simulate("click");
wrapper.find('button').findWhere(e => e.text() === 'Cleanup Gravity' && e.type() === 'button').simulate('click');
// initial send of reindex request to server
expect(global.fetch).toBeCalledTimes(1);

View File

@ -1,8 +1,8 @@
import React from "react";
import MovieSettings from "./MovieSettings";
import GeneralSettings from "./GeneralSettings";
import style from "./SettingsPage.module.css"
import GlobalInfos from "../../GlobalInfos";
import React from 'react';
import MovieSettings from './MovieSettings';
import GeneralSettings from './GeneralSettings';
import style from './SettingsPage.module.css';
import GlobalInfos from '../../GlobalInfos';
/**
* The Settingspage handles all kinds of settings for the mediacenter
@ -13,7 +13,7 @@ class SettingsPage extends React.Component {
super(props, context);
this.state = {
currentpage: "general"
currentpage: 'general'
};
}
@ -23,14 +23,14 @@ class SettingsPage extends React.Component {
*/
getContent() {
switch (this.state.currentpage) {
case "general":
case 'general':
return <GeneralSettings/>;
case "movies":
case 'movies':
return <MovieSettings/>;
case "tv":
case 'tv':
return <span/>; // todo this page
default:
return "unknown button clicked";
return 'unknown button clicked';
}
}
@ -40,13 +40,13 @@ class SettingsPage extends React.Component {
<div>
<div className={style.SettingsSidebar + ' ' + themestyle.secbackground}>
<div className={style.SettingsSidebarTitle + ' ' + themestyle.lighttextcolor}>Settings</div>
<div onClick={() => this.setState({currentpage: "general"})}
<div onClick={() => this.setState({currentpage: 'general'})}
className={style.SettingSidebarElement}>General
</div>
<div onClick={() => this.setState({currentpage: "movies"})}
<div onClick={() => this.setState({currentpage: 'movies'})}
className={style.SettingSidebarElement}>Movies
</div>
<div onClick={() => this.setState({currentpage: "tv"})}
<div onClick={() => this.setState({currentpage: 'tv'})}
className={style.SettingSidebarElement}>TV Shows
</div>
</div>

View File

@ -1,6 +1,6 @@
import {shallow} from "enzyme";
import React from "react";
import SettingsPage from "./SettingsPage";
import {shallow} from 'enzyme';
import React from 'react';
import SettingsPage from './SettingsPage';
describe('<RandomPage/>', function () {
it('renders without crashing ', function () {
@ -11,30 +11,30 @@ describe('<RandomPage/>', function () {
it('simulate topic clicka', function () {
const wrapper = shallow(<SettingsPage/>);
simulateSideBarClick("General", wrapper);
expect(wrapper.state().currentpage).toBe("general");
expect(wrapper.find(".SettingsContent").find("GeneralSettings")).toHaveLength(1);
simulateSideBarClick('General', wrapper);
expect(wrapper.state().currentpage).toBe('general');
expect(wrapper.find('.SettingsContent').find('GeneralSettings')).toHaveLength(1);
simulateSideBarClick("Movies", wrapper);
expect(wrapper.state().currentpage).toBe("movies");
expect(wrapper.find(".SettingsContent").find("MovieSettings")).toHaveLength(1);
simulateSideBarClick('Movies', wrapper);
expect(wrapper.state().currentpage).toBe('movies');
expect(wrapper.find('.SettingsContent').find('MovieSettings')).toHaveLength(1);
simulateSideBarClick("TV Shows", wrapper);
expect(wrapper.state().currentpage).toBe("tv");
expect(wrapper.find(".SettingsContent").find("span")).toHaveLength(1);
simulateSideBarClick('TV Shows', wrapper);
expect(wrapper.state().currentpage).toBe('tv');
expect(wrapper.find('.SettingsContent').find('span')).toHaveLength(1);
});
function simulateSideBarClick(name, wrapper) {
wrapper.find(".SettingSidebarElement").findWhere(it =>
wrapper.find('.SettingSidebarElement').findWhere(it =>
it.text() === name &&
it.type() === "div").simulate("click");
it.type() === 'div').simulate('click');
}
it('simulate unknown topic', function () {
const wrapper = shallow(<SettingsPage/>);
wrapper.setState({currentpage: "unknown"});
wrapper.setState({currentpage: 'unknown'});
expect(wrapper.find(".SettingsContent").text()).toBe("unknown button clicked");
expect(wrapper.find('.SettingsContent').text()).toBe('unknown button clicked');
});
});