Tests for all Components

This commit is contained in:
Lukas Heiligenbrunner 2020-06-12 15:57:30 +00:00
parent 751e09f54b
commit e95dd62ffd
27 changed files with 639 additions and 225 deletions

View File

@ -1,12 +1,12 @@
import React from 'react'; import React from 'react';
import "./css/App.css" import "./css/App.css"
import HomePage from "./pages/HomePage"; import HomePage from "./pages/HomePage/HomePage";
import RandomPage from "./pages/RandomPage"; import RandomPage from "./pages/RandomPage/RandomPage";
// include bootstraps css // include bootstraps css
import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap/dist/css/bootstrap.min.css';
import SettingsPage from "./pages/SettingsPage"; import SettingsPage from "./pages/SettingsPage/SettingsPage";
import CategoryPage from "./pages/CategoryPage"; import CategoryPage from "./pages/CategoryPage/CategoryPage";
class App extends React.Component { class App extends React.Component {
constructor(props, context) { constructor(props, context) {

View File

@ -6,8 +6,3 @@ body {
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@ -26,7 +26,9 @@ class NewTagPopup extends React.Component {
<Modal.Body> <Modal.Body>
<Form.Group> <Form.Group>
<Form.Label>Tag Name:</Form.Label> <Form.Label>Tag Name:</Form.Label>
<Form.Control id='namefield' type="text" placeholder="Enter Tag name" /> <Form.Control id='namefield' type="text" placeholder="Enter Tag name" onChange={(v) => {
this.value = v.target.value
}}/>
<Form.Text className="text-muted"> <Form.Text className="text-muted">
This Tag will automatically show up on category page. This Tag will automatically show up on category page.
</Form.Text> </Form.Text>
@ -46,7 +48,7 @@ class NewTagPopup extends React.Component {
storeselection() { storeselection() {
const updateRequest = new FormData(); const updateRequest = new FormData();
updateRequest.append('action', 'createTag'); updateRequest.append('action', 'createTag');
updateRequest.append('tagname', document.getElementById("namefield").value); updateRequest.append('tagname', this.value);
fetch('/api/Tags.php', {method: 'POST', body: updateRequest}) fetch('/api/Tags.php', {method: 'POST', body: updateRequest})
.then((response) => response.json()) .then((response) => response.json())

View File

@ -0,0 +1,41 @@
import React from "react";
import {shallow} from 'enzyme'
import "@testing-library/jest-dom"
import NewTagPopup from "./NewTagPopup";
describe('<NewTagPopup/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<NewTagPopup/>);
wrapper.unmount();
});
it('test storeseletion click event', done => {
const mockSuccessResponse = {};
const mockJsonPromise = Promise.resolve(mockSuccessResponse);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
global.fetch = jest.fn().mockImplementation(() => mockFetchPromise);
const func = jest.fn();
const wrapper = shallow(<NewTagPopup/>);
wrapper.setProps({
onHide: () => {
func()
}
});
wrapper.find('ModalFooter').find('button').simulate('click');
expect(global.fetch).toHaveBeenCalledTimes(1);
process.nextTick(() => {
//callback to close window should have called
expect(func).toHaveBeenCalledTimes(1);
global.fetch.mockClear();
done();
});
});
});

View File

@ -49,6 +49,6 @@
width: 266px; width: 266px;
} }
.tagpreviewtitle{ .tagpreviewtitle {
margin-top: 55px; margin-top: 55px;
} }

View File

@ -1,7 +1,7 @@
import React from "react"; import React from "react";
import "../css/Preview.css"; import "./Preview.css";
import Player from "../pages/Player"; import Player from "../../pages/Player/Player";
import VideoContainer from "./VideoContainer"; import VideoContainer from "../VideoContainer/VideoContainer";
class Preview extends React.Component { class Preview extends React.Component {
constructor(props, context) { constructor(props, context) {
@ -29,18 +29,18 @@ class Preview extends React.Component {
updateRequest.append('movieid', this.props.movie_id); updateRequest.append('movieid', this.props.movie_id);
fetch('/api/videoload.php', {method: 'POST', body: updateRequest}) fetch('/api/videoload.php', {method: 'POST', body: updateRequest})
.then((response) => response.text()) .then((response) => response.text()
.then((result) => { .then((result) => {
this.setState(prevState => ({ this.setState(prevState => ({
...prevState.previewpicture, previewpicture: result ...prevState.previewpicture, previewpicture: result
})); }));
}); }));
} }
render() { render() {
return ( return (
<div className='videopreview' onClick={() => this.itemClick()}> <div className='videopreview' onClick={() => this.itemClick()}>
<div className='previewtitle videopreviewtitle'>{this.state.name}</div> <div className='previewtitle'>{this.state.name}</div>
<div className='previewpic'> <div className='previewpic'>
<img className='previewimage' <img className='previewimage'
src={this.state.previewpicture} src={this.state.previewpicture}
@ -85,7 +85,7 @@ export class TagPreview extends React.Component {
this.props.categorybinding( this.props.categorybinding(
<VideoContainer <VideoContainer
data={result} data={result}
viewbinding={this.props.viewbinding}/>,tag viewbinding={this.props.viewbinding}/>, tag
); );
})) }))
.catch(() => { .catch(() => {

View File

@ -0,0 +1,107 @@
import React from 'react';
import {shallow} from 'enzyme'
import Preview, {TagPreview} from "./Preview";
describe('<Preview/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<Preview/>);
wrapper.unmount();
});
// check if preview title renders correctly
it('renders title', () => {
const wrapper = shallow(<Preview name='test'/>);
expect(wrapper.find('.previewtitle').text()).toBe('test');
});
it('click event triggered', () => {
const func = jest.fn();
const wrapper = shallow(<Preview/>);
wrapper.setProps({
viewbinding: {
showVideo: () => {
func()
}
}
});
wrapper.find('.videopreview').simulate('click');
//callback to open player should have called
expect(func).toHaveBeenCalledTimes(1);
});
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);
const wrapper = shallow(<Preview/>);
// 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();
global.fetch.mockClear();
done();
});
});
});
describe('<TagPreview/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<TagPreview/>);
wrapper.unmount();
});
// check if preview title renders correctly
it('renders title', () => {
const wrapper = shallow(<TagPreview name='test'/>);
expect(wrapper.find('.tagpreviewtitle').text()).toBe('test');
});
it('click event triggered', done => {
const mockSuccessResponse = {};
const mockJsonPromise = Promise.resolve(mockSuccessResponse);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
global.fetch = jest.fn().mockImplementation(() => mockFetchPromise);
const func = jest.fn();
const wrapper = shallow(<TagPreview/>);
wrapper.setProps({
categorybinding: () => {
func()
}
});
// first call of fetch is getting of available tags
expect(global.fetch).toHaveBeenCalledTimes(0);
wrapper.find('.videopreview').simulate('click');
// now called 1 times
expect(global.fetch).toHaveBeenCalledTimes(1);
process.nextTick(() => {
//callback to close window should have called
expect(func).toHaveBeenCalledTimes(1);
global.fetch.mockClear();
done();
});
});
});

View File

@ -12,7 +12,8 @@ class Tag extends React.Component {
render() { render() {
// todo onclick events correctlyy // todo onclick events correctlyy
return ( return (
<button className='tagbtn' onClick={this.props.onClick} data-testid="Test-Tag">{this.props.children}</button> <button className='tagbtn' onClick={this.props.onClick}
data-testid="Test-Tag">{this.props.children}</button>
); );
} }
} }

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import Preview from "./Preview"; import Preview from "../Preview/Preview";
class VideoContainer extends React.Component { class VideoContainer extends React.Component {
constructor(props, context) { constructor(props, context) {

View File

@ -0,0 +1,30 @@
import {shallow} from "enzyme";
import React from "react";
import VideoContainer from "./VideoContainer";
describe('<VideoContainer/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<VideoContainer data={[]}/>);
wrapper.unmount();
});
it('inserts tiles correctly', () => {
const wrapper = shallow(<VideoContainer data={[
{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}
]}/>);
expect(wrapper.find('Preview')).toHaveLength(12);
});
it('inserts tiles correctly if not enough available', () => {
const wrapper = shallow(<VideoContainer data={[
{}, {}, {}, {}
]}/>);
expect(wrapper.find('Preview')).toHaveLength(4);
});
it('no items available', () => {
const wrapper = shallow(<VideoContainer data={[]}/>);
expect(wrapper.find('Preview')).toHaveLength(0);
expect(wrapper.find(".maincontent").text()).toBe("no items to show!");
});
});

View File

@ -2,7 +2,6 @@ import React from 'react';
import ReactDOM from 'react-dom'; import ReactDOM from 'react-dom';
import './css/index.css'; import './css/index.css';
import App from './App'; import App from './App';
import * as serviceWorker from './serviceWorker';
ReactDOM.render( ReactDOM.render(
<React.StrictMode> <React.StrictMode>
@ -10,8 +9,3 @@ ReactDOM.render(
</React.StrictMode>, </React.StrictMode>,
document.getElementById('root') document.getElementById('root')
); );
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.register();

View File

@ -1,9 +1,9 @@
import React from "react"; import React from "react";
import SideBar from "../elements/SideBar/SideBar"; import SideBar from "../../elements/SideBar/SideBar";
import Tag from "../elements/Tag/Tag"; import Tag from "../../elements/Tag/Tag";
import {TagPreview} from "../elements/Preview"; import {TagPreview} from "../../elements/Preview/Preview";
import NewTagPopup from "../elements/NewTagPopup"; import NewTagPopup from "../../elements/NewTagPopup/NewTagPopup";
class CategoryPage extends React.Component { class CategoryPage extends React.Component {
constructor(props, context) { constructor(props, context) {
@ -37,7 +37,7 @@ class CategoryPage extends React.Component {
<Tag>LowQuality</Tag> <Tag>LowQuality</Tag>
<Tag>HD</Tag> <Tag>HD</Tag>
<hr/> <hr/>
<button className='btn btn-success' onClick={() => { <button data-testid='btnaddtag' className='btn btn-success' onClick={() => {
this.setState({popupvisible: true}) this.setState({popupvisible: true})
}}>Add a new Tag! }}>Add a new Tag!
</button> </button>
@ -58,7 +58,9 @@ class CategoryPage extends React.Component {
</div>) : </div>) :
<> <>
{this.selectionelements} {this.selectionelements}
<button className="btn btn-success" onClick={this.loadCategoryPageDefault}>Back</button> <button data-testid='backbtn' className="btn btn-success"
onClick={this.loadCategoryPageDefault}>Back
</button>
</> </>
} }

View File

@ -0,0 +1,107 @@
import {shallow, mount} from "enzyme";
import React from "react";
import CategoryPage from "./CategoryPage";
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
function prepareFetchApi(response) {
const mockJsonPromise = Promise.resolve(response);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
return (jest.fn().mockImplementation(() => mockFetchPromise));
}
describe('<CategoryPage/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<CategoryPage/>);
wrapper.unmount();
});
it('test tag fetch call', done => {
global.fetch = 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 errored fetch call', done => {
global.fetch = prepareFetchApi({});
let message;
global.console.log = jest.fn((m) => {
message = m;
})
const wrapper = shallow(<CategoryPage/>);
expect(global.fetch).toHaveBeenCalledTimes(1);
process.nextTick(() => {
//callback to close window should have called
expect(message).toBe("no connection to backend");
global.fetch.mockClear();
done();
});
});
it('test new tag popup', function () {
const wrapper = mount(<CategoryPage/>);
expect(wrapper.find("NewTagPopup")).toHaveLength(0);
wrapper.find('[data-testid="btnaddtag"]').simulate('click');
// newtagpopup should be showing now
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);
});
it('test setpage callback', done => {
global.fetch = prepareFetchApi([{}, {}]);
const wrapper = mount(<CategoryPage/>);
wrapper.setState({
loadedtags: [
{
tag_name: "testname",
tag_id: 42
}
]
});
wrapper.find("TagPreview").find("div").first().simulate("click");
process.nextTick(() => {
// expect callback to have loaded correct tag
expect(wrapper.state().selected).toBe("testname");
// expect to receive a videocontainer with simulated data
expect(wrapper.instance().selectionelements).toMatchObject(<VideoContainer data={[{}, {}]}/>);
global.fetch.mockClear();
done();
});
});
it('test back to category view callback', 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();
});
});

View File

@ -1,10 +1,10 @@
import React from "react"; import React from "react";
import SideBar from "../elements/SideBar/SideBar"; import SideBar from "../../elements/SideBar/SideBar";
import Tag from "../elements/Tag/Tag"; import Tag from "../../elements/Tag/Tag";
import VideoContainer from "../elements/VideoContainer"; import VideoContainer from "../../elements/VideoContainer/VideoContainer";
import "../css/HomePage.css" import "./HomePage.css"
import "../css/DefaultPage.css" import "../../css/DefaultPage.css"
class HomePage extends React.Component { class HomePage extends React.Component {
constructor(props, context) { constructor(props, context) {
@ -25,7 +25,6 @@ class HomePage extends React.Component {
} }
componentDidMount() { componentDidMount() {
// document.addEventListener('scroll', this.trackScrolling);
// initial get of all videos // initial get of all videos
this.fetchVideoData("all"); this.fetchVideoData("all");
this.fetchStartData(); this.fetchStartData();
@ -129,7 +128,8 @@ class HomePage extends React.Component {
{this.state.data.length !== 0 ? {this.state.data.length !== 0 ?
<VideoContainer <VideoContainer
data={this.state.data} data={this.state.data}
viewbinding={this.props.viewbinding}/> : null} viewbinding={this.props.viewbinding}/> :
<div>No Data found!</div>}
<div className='rightinfo'> <div className='rightinfo'>
</div> </div>

View File

@ -0,0 +1,58 @@
import {shallow} from "enzyme";
import React from "react";
import HomePage from "./HomePage";
function prepareFetchApi(response) {
const mockJsonPromise = Promise.resolve(response);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
return (jest.fn().mockImplementation(() => mockFetchPromise));
}
describe('<HomePage/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<HomePage/>);
wrapper.unmount();
});
it('ckeck default tag click events', function () {
const wrapper = shallow(<HomePage/>);
global.fetch = prepareFetchApi({});
expect(global.fetch).toBeCalledTimes(0);
// click every tag button
wrapper.find("Tag").map((i) => {
i.simulate("click");
});
expect(global.fetch).toBeCalledTimes(4);
});
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/>);
expect(wrapper.find(".pageheadersubtitle").text()).toBe("All Videos - 0");
wrapper.setState({
tag: "testtag",
selectionnr: 42
});
expect(wrapper.find(".pageheadersubtitle").text()).toBe("testtag Videos - 42");
});
});

View File

@ -27,6 +27,6 @@
margin-top: 25px; margin-top: 25px;
} }
.videoactions{ .videoactions {
margin-top: 15px; margin-top: 15px;
} }

View File

@ -1,9 +1,9 @@
import React from "react"; import React from "react";
import "../css/Player.css" import "./Player.css"
import {PlyrComponent} from 'plyr-react'; import {PlyrComponent} from 'plyr-react';
import SideBar from "../elements/SideBar/SideBar"; import SideBar from "../../elements/SideBar/SideBar";
import Tag from "../elements/Tag/Tag"; import Tag from "../../elements/Tag/Tag";
import AddTagPopup from "../elements/AddTagPopup/AddTagPopup"; import AddTagPopup from "../../elements/AddTagPopup/AddTagPopup";
class Player extends React.Component { class Player extends React.Component {
@ -137,7 +137,7 @@ class Player extends React.Component {
updateRequest.append('movieid', this.props.movie_id); updateRequest.append('movieid', this.props.movie_id);
fetch('/api/videoload.php', {method: 'POST', body: updateRequest}) fetch('/api/videoload.php', {method: 'POST', body: updateRequest})
.then((response) => response.json()) .then((response) => response.json()
.then((result) => { .then((result) => {
if (result.result === "success") { if (result.result === "success") {
this.fetchMovieData(); this.fetchMovieData();
@ -145,7 +145,7 @@ class Player extends React.Component {
console.log("an error occured while liking"); console.log("an error occured while liking");
console.log(result); console.log(result);
} }
}); }));
} }
closebtn() { closebtn() {

View File

@ -0,0 +1,128 @@
import {shallow} from "enzyme";
import React from "react";
import Player from "./Player";
function prepareFetchApi(response) {
const mockJsonPromise = Promise.resolve(response);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
return (jest.fn().mockImplementation(() => mockFetchPromise));
}
describe('<Player/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<Player/>);
wrapper.unmount();
});
it('plyr insertion', function () {
const wrapper = shallow(<Player/>);
wrapper.setState({
sources: [
{
src: '/tstvid.mp4',
type: 'video/mp4',
size: 1080,
}
]
});
expect(wrapper.find("r")).toHaveLength(1);
});
it('likebtn click', done => {
global.fetch = prepareFetchApi({result: 'success'});
const func = jest.fn();
const wrapper = shallow(<Player/>);
wrapper.setProps({
onHide: () => {
func()
}
});
// initial fetch for getting movie data
expect(global.fetch).toHaveBeenCalledTimes(1);
wrapper.find('.videoactions').find("button").first().simulate('click');
// fetch for liking
expect(global.fetch).toHaveBeenCalledTimes(2);
process.nextTick(() => {
// refetch is called so fetch called 3 times
expect(global.fetch).toHaveBeenCalledTimes(3);
global.fetch.mockClear();
done();
});
});
it('errored likebtn click', done => {
global.fetch = prepareFetchApi({result: 'nosuccess'});
const func = jest.fn();
const wrapper = shallow(<Player/>);
wrapper.setProps({
onHide: () => {
func()
}
});
// initial fetch for getting movie data
expect(global.fetch).toHaveBeenCalledTimes(1);
wrapper.find('.videoactions').find("button").first().simulate('click');
// fetch for liking
expect(global.fetch).toHaveBeenCalledTimes(2);
process.nextTick(() => {
// refetch is called so fetch called 3 times
expect(global.fetch).toHaveBeenCalledTimes(2);
global.fetch.mockClear();
done();
});
});
it('show tag popup', function () {
const wrapper = shallow(<Player/>);
expect(wrapper.find("AddTagPopup")).toHaveLength(0);
wrapper.find('.videoactions').find("button").last().simulate('click');
// addtagpopup should be showing now
expect(wrapper.find("AddTagPopup")).toHaveLength(1);
});
it('hide click ', function () {
const wrapper = shallow(<Player/>);
const func = jest.fn();
wrapper.setProps({
viewbinding: {
hideVideo: () => {
func()
}
}
});
expect(func).toHaveBeenCalledTimes(0);
wrapper.find('.closebutton').simulate('click');
// addtagpopup should be showing now
expect(func).toHaveBeenCalledTimes(1);
});
it('inserts Tags correctly', function () {
const wrapper = shallow(<Player/>);
expect(wrapper.find("Tag")).toHaveLength(0);
wrapper.setState({
tags: [
{tag_name: 'first'},
{tag_name: 'second'}
]
});
expect(wrapper.find("Tag")).toHaveLength(2);
});
});

View File

@ -3,7 +3,7 @@
align-content: center; align-content: center;
} }
.btnshuffle{ .btnshuffle {
background-color: #39a945; background-color: #39a945;
color: white; color: white;
@ -16,6 +16,6 @@
font-size: larger; font-size: larger;
} }
.btnshuffle:focus{ .btnshuffle:focus {
outline: none; outline: none;
} }

View File

@ -1,8 +1,8 @@
import React from "react"; import React from "react";
import Preview from "../elements/Preview"; import Preview from "../../elements/Preview/Preview";
import "../css/RandomPage.css" import "./RandomPage.css"
import SideBar from "../elements/SideBar/SideBar"; import SideBar from "../../elements/SideBar/SideBar";
import Tag from "../elements/Tag/Tag"; import Tag from "../../elements/Tag/Tag";
class RandomPage extends React.Component { class RandomPage extends React.Component {
constructor(props, context) { constructor(props, context) {

View File

@ -0,0 +1,49 @@
import {shallow} from "enzyme";
import React from "react";
import RandomPage from "./RandomPage";
function prepareFetchApi(response) {
const mockJsonPromise = Promise.resolve(response);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
return (jest.fn().mockImplementation(() => mockFetchPromise));
}
describe('<RandomPage/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<RandomPage/>);
wrapper.unmount();
});
it('test shuffleload fetch', function () {
global.fetch = prepareFetchApi({});
const wrapper = shallow(<RandomPage/>);
expect(global.fetch).toBeCalledTimes(1);
});
it('btnshuffle click test', function () {
global.fetch = prepareFetchApi({});
const wrapper = shallow(<RandomPage/>);
wrapper.find(".btnshuffle").simulate("click");
expect(global.fetch).toBeCalledTimes(2);
});
it('test tags in random selection', function () {
const wrapper = shallow(<RandomPage/>);
wrapper.setState({
tags: [
{tag_name: "test1"},
{tag_name: "test2"}
]
});
expect(wrapper.find("Tag")).toHaveLength(2);
});
});

View File

@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import "../css/DefaultPage.css" import "../../css/DefaultPage.css"
class SettingsPage extends React.Component { class SettingsPage extends React.Component {
@ -31,7 +31,7 @@ class SettingsPage extends React.Component {
}; };
componentDidMount() { componentDidMount() {
if(this.myinterval){ if (this.myinterval) {
clearInterval(this.myinterval); clearInterval(this.myinterval);
} }
this.myinterval = setInterval(this.updateStatus, 1000); this.myinterval = setInterval(this.updateStatus, 1000);
@ -50,12 +50,12 @@ class SettingsPage extends React.Component {
<hr/> <hr/>
</div> </div>
<button className='btn btn-success' onClick={() => { <button className='reindexbtn btn btn-success' onClick={() => {
this.startReindex() this.startReindex()
}}>Reindex Movies }}>Reindex Movies
</button> </button>
<div>{this.state.text.map(m => ( <div className='indextextarea'>{this.state.text.map(m => (
<div>{m}</div> <div className='textarea-element'>{m}</div>
))}</div> ))}</div>
</div> </div>
); );
@ -73,7 +73,7 @@ class SettingsPage extends React.Component {
.catch(() => { .catch(() => {
console.log("no connection to backend"); console.log("no connection to backend");
}); });
if(this.myinterval){ if (this.myinterval) {
clearInterval(this.myinterval); clearInterval(this.myinterval);
} }
this.myinterval = setInterval(this.updateStatus, 1000); this.myinterval = setInterval(this.updateStatus, 1000);

View File

@ -0,0 +1,41 @@
import {shallow} from "enzyme";
import React from "react";
import SettingsPage from "./SettingsPage";
function prepareFetchApi(response) {
const mockJsonPromise = Promise.resolve(response);
const mockFetchPromise = Promise.resolve({
json: () => mockJsonPromise,
});
return (jest.fn().mockImplementation(() => mockFetchPromise));
}
describe('<RandomPage/>', function () {
it('renders without crashing ', function () {
const wrapper = shallow(<SettingsPage/>);
wrapper.unmount();
});
it('received text renders into dom', function () {
const wrapper = shallow(<SettingsPage/>);
wrapper.setState({
text: [
"firstline",
"secline"
]
});
expect(wrapper.find(".indextextarea").find(".textarea-element")).toHaveLength(2);
});
it('test simulate reindex', function () {
global.fetch = prepareFetchApi({});
const wrapper = shallow(<SettingsPage/>);
wrapper.find(".reindexbtn").simulate("click");
// initial send of reindex request to server
expect(global.fetch).toBeCalledTimes(1);
});
});

View File

@ -1,141 +0,0 @@
// This optional code is used to register a service worker.
// register() is not called by default.
// This lets the app load faster on subsequent visits in production, and gives
// it offline capabilities. However, it also means that developers (and users)
// will only see deployed updates on subsequent visits to a page, after all the
// existing tabs open on the page have been closed, since previously cached
// resources are updated in the background.
// To learn more about the benefits of this model and instructions on how to
// opt-in, read https://bit.ly/CRA-PWA
const isLocalhost = Boolean(
window.location.hostname === 'localhost' ||
// [::1] is the IPv6 localhost address.
window.location.hostname === '[::1]' ||
// 127.0.0.0/8 are considered localhost for IPv4.
window.location.hostname.match(
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
)
);
export function register(config) {
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
// The URL constructor is available in all browsers that support SW.
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
if (publicUrl.origin !== window.location.origin) {
// Our service worker won't work if PUBLIC_URL is on a different origin
// from what our page is served on. This might happen if a CDN is used to
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
return;
}
window.addEventListener('load', () => {
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
if (isLocalhost) {
// This is running on localhost. Let's check if a service worker still exists or not.
checkValidServiceWorker(swUrl, config);
// Add some additional logging to localhost, pointing developers to the
// service worker/PWA documentation.
navigator.serviceWorker.ready.then(() => {
console.log(
'This web app is being served cache-first by a service ' +
'worker. To learn more, visit https://bit.ly/CRA-PWA'
);
});
} else {
// Is not localhost. Just register service worker
registerValidSW(swUrl, config);
}
});
}
}
function registerValidSW(swUrl, config) {
navigator.serviceWorker
.register(swUrl)
.then(registration => {
registration.onupdatefound = () => {
const installingWorker = registration.installing;
if (installingWorker == null) {
return;
}
installingWorker.onstatechange = () => {
if (installingWorker.state === 'installed') {
if (navigator.serviceWorker.controller) {
// At this point, the updated precached content has been fetched,
// but the previous service worker will still serve the older
// content until all client tabs are closed.
console.log(
'New content is available and will be used when all ' +
'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
);
// Execute callback
if (config && config.onUpdate) {
config.onUpdate(registration);
}
} else {
// At this point, everything has been precached.
// It's the perfect time to display a
// "Content is cached for offline use." message.
console.log('Content is cached for offline use.');
// Execute callback
if (config && config.onSuccess) {
config.onSuccess(registration);
}
}
}
};
};
})
.catch(error => {
console.error('Error during service worker registration:', error);
});
}
function checkValidServiceWorker(swUrl, config) {
// Check if the service worker can be found. If it can't reload the page.
fetch(swUrl, {
headers: {'Service-Worker': 'script'},
})
.then(response => {
// Ensure service worker exists, and that we really are getting a JS file.
const contentType = response.headers.get('content-type');
if (
response.status === 404 ||
(contentType != null && contentType.indexOf('javascript') === -1)
) {
// No service worker found. Probably a different app. Reload the page.
navigator.serviceWorker.ready.then(registration => {
registration.unregister().then(() => {
window.location.reload();
});
});
} else {
// Service worker found. Proceed as normal.
registerValidSW(swUrl, config);
}
})
.catch(() => {
console.log(
'No internet connection found. App is running in offline mode.'
);
});
}
export function unregister() {
if ('serviceWorker' in navigator) {
navigator.serviceWorker.ready
.then(registration => {
registration.unregister();
})
.catch(error => {
console.error(error.message);
});
}
}

View File

@ -4,7 +4,7 @@
// learn more: https://github.com/testing-library/jest-dom // learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom/extend-expect'; import '@testing-library/jest-dom/extend-expect';
import { configure } from 'enzyme'; import {configure} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16'; import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() }); configure({adapter: new Adapter()});