Merge branch 'SettingsPage' into 'master'
Settings page See merge request lukas/openmediacenter!6
This commit is contained in:
commit
ca499fed99
39
api/SSettings.php
Normal file
39
api/SSettings.php
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class SSettings
|
||||||
|
{
|
||||||
|
private ?Database $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SSettings constructor.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
$this->database = Database::getInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getVideoPath() {
|
||||||
|
$query = "SELECT video_path from settings";
|
||||||
|
|
||||||
|
$result = $this->database->getConnection()->query($query);
|
||||||
|
|
||||||
|
$r = mysqli_fetch_assoc($result);
|
||||||
|
return $r['video_path'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* check if TMDB is enableds
|
||||||
|
* @return bool isenabled?
|
||||||
|
*/
|
||||||
|
public function isTMDBGrabbingEnabled(): bool
|
||||||
|
{
|
||||||
|
$query = "SELECT TMDB_grabbing from settings";
|
||||||
|
|
||||||
|
$result = $this->database->getConnection()->query($query);
|
||||||
|
if(!$result){
|
||||||
|
return true; // if undefined in db --> default true
|
||||||
|
}else{
|
||||||
|
$r = mysqli_fetch_assoc($result);
|
||||||
|
return $r['TMDB_grabbing'] == '1';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
65
api/Settings.php
Normal file
65
api/Settings.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
require 'Database.php';
|
||||||
|
require 'SSettings.php';
|
||||||
|
|
||||||
|
$conn = Database::getInstance()->getConnection();
|
||||||
|
$settings = new SSettings();
|
||||||
|
|
||||||
|
if (isset($_POST['action'])) {
|
||||||
|
$action = $_POST['action'];
|
||||||
|
switch ($action) {
|
||||||
|
case "loadGeneralSettings":
|
||||||
|
$query = "SELECT * from settings";
|
||||||
|
|
||||||
|
$result = $conn->query($query);
|
||||||
|
if ($result->num_rows > 1) {
|
||||||
|
// todo throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = mysqli_fetch_assoc($result);
|
||||||
|
// booleans need to be set manually
|
||||||
|
$r['passwordEnabled'] = $r['password'] != "-1";
|
||||||
|
$r['TMDB_grabbing'] = ($r['TMDB_grabbing'] != '0');
|
||||||
|
|
||||||
|
echo json_encode($r);
|
||||||
|
break;
|
||||||
|
case "saveGeneralSettings":
|
||||||
|
$mediacentername = $_POST['mediacentername'];
|
||||||
|
$password = $_POST['password'];
|
||||||
|
$videopath = $_POST['videopath'];
|
||||||
|
$tvshowpath = $_POST['tvshowpath'];
|
||||||
|
$tmdbsupport = $_POST['tmdbsupport'];
|
||||||
|
|
||||||
|
$query = "UPDATE settings SET
|
||||||
|
video_path='$videopath',
|
||||||
|
episode_path='$tvshowpath',
|
||||||
|
password='$password',
|
||||||
|
mediacenter_name='$mediacentername',
|
||||||
|
TMDB_grabbing=$tmdbsupport
|
||||||
|
WHERE 1";
|
||||||
|
|
||||||
|
if ($conn->query($query) === true) {
|
||||||
|
echo '{"success": true}';
|
||||||
|
} else {
|
||||||
|
echo '{"success": true}';
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "loadInitialData":
|
||||||
|
$query = "SELECT * from settings";
|
||||||
|
|
||||||
|
$result = $conn->query($query);
|
||||||
|
if ($result->num_rows > 1) {
|
||||||
|
// todo throw error
|
||||||
|
}
|
||||||
|
|
||||||
|
$r = mysqli_fetch_assoc($result);
|
||||||
|
if ($r['password'] != "-1") {
|
||||||
|
$r['passwordEnabled'] = true;
|
||||||
|
} else {
|
||||||
|
$r['passwordEnabled'] = false;
|
||||||
|
}
|
||||||
|
unset($r['password']);
|
||||||
|
echo json_encode($r);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
require 'Database.php';
|
require 'Database.php';
|
||||||
require 'TMDBMovie.php';
|
require 'TMDBMovie.php';
|
||||||
|
require 'SSettings.php';
|
||||||
|
|
||||||
writeLog("starting extraction!\n");
|
writeLog("starting extraction!\n");
|
||||||
|
|
||||||
@ -10,9 +11,12 @@ $tmdb = new TMDBMovie();
|
|||||||
$tmdbgenres = $tmdb->getAllGenres();
|
$tmdbgenres = $tmdb->getAllGenres();
|
||||||
|
|
||||||
$conn = Database::getInstance()->getConnection();
|
$conn = Database::getInstance()->getConnection();
|
||||||
|
$settings = new SSettings();
|
||||||
|
|
||||||
$scandir = "../videos/prn/";
|
// load video path from settings
|
||||||
|
$scandir = "../" . $settings->getVideoPath();
|
||||||
$arr = scandir($scandir);
|
$arr = scandir($scandir);
|
||||||
|
$TMDB_enabled = $settings->isTMDBGrabbingEnabled();
|
||||||
|
|
||||||
$all = 0;
|
$all = 0;
|
||||||
$added = 0;
|
$added = 0;
|
||||||
@ -33,14 +37,21 @@ foreach ($arr as $elem) {
|
|||||||
$poster = -1;
|
$poster = -1;
|
||||||
$genres = -1;
|
$genres = -1;
|
||||||
if (!is_null($dta = $tmdb->searchMovie($moviename))) {
|
if (!is_null($dta = $tmdb->searchMovie($moviename))) {
|
||||||
$pic = file_get_contents($tmdb->picturebase . $dta->poster_path);
|
|
||||||
$poster = shell_exec("ffmpeg -hide_banner -loglevel panic -ss 00:04:00 -i \"../videos/prn/$elem\" -vframes 1 -q:v 2 -f singlejpeg pipe:1 2>/dev/null");
|
$poster = shell_exec("ffmpeg -hide_banner -loglevel panic -ss 00:04:00 -i \"../videos/prn/$elem\" -vframes 1 -q:v 2 -f singlejpeg pipe:1 2>/dev/null");
|
||||||
|
|
||||||
// error handling for download error
|
// check if tmdb support is enabled
|
||||||
if (!$pic) {
|
if ($TMDB_enabled) {
|
||||||
|
$pic = file_get_contents($tmdb->picturebase . $dta->poster_path);
|
||||||
|
|
||||||
|
// error handling for download error
|
||||||
|
if (!$pic) {
|
||||||
|
$pic = $poster;
|
||||||
|
$poster = -1;
|
||||||
|
echo "Failed to load Picture from TMDB! \n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
$pic = $poster;
|
$pic = $poster;
|
||||||
$poster = -1;
|
$poster = -1;
|
||||||
echo "Failed to load Picture from TMDB! \n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$genres = $dta->genre_ids;
|
$genres = $dta->genre_ids;
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
<?php
|
<?php
|
||||||
require 'Database.php';
|
require 'Database.php';
|
||||||
|
require 'SSettings.php';
|
||||||
|
|
||||||
|
// establish initial db connection
|
||||||
$conn = Database::getInstance()->getConnection();
|
$conn = Database::getInstance()->getConnection();
|
||||||
|
$settings = new SSettings();
|
||||||
|
|
||||||
|
// load video path from settings
|
||||||
|
$videopath = $settings->getVideoPath();
|
||||||
|
|
||||||
|
|
||||||
//$_POST['action'] = "getRandomMovies";$_POST['number'] =6;
|
|
||||||
if (isset($_POST['action'])) {
|
if (isset($_POST['action'])) {
|
||||||
$action = $_POST['action'];
|
$action = $_POST['action'];
|
||||||
switch ($action) {
|
switch ($action) {
|
||||||
@ -84,7 +90,9 @@ if (isset($_POST['action'])) {
|
|||||||
|
|
||||||
$arr["movie_id"] = $row["movie_id"];
|
$arr["movie_id"] = $row["movie_id"];
|
||||||
$arr["movie_name"] = $row["movie_name"];
|
$arr["movie_name"] = $row["movie_name"];
|
||||||
$arr["movie_url"] = str_replace("?","%3F",$row["movie_url"]);
|
// todo drop video url from db -- maybe one with and one without extension
|
||||||
|
// extension hardcoded here!!!
|
||||||
|
$arr["movie_url"] = str_replace("?", "%3F", $videopath . $row["movie_name"] . ".mp4");
|
||||||
$arr["likes"] = $row["likes"];
|
$arr["likes"] = $row["likes"];
|
||||||
$arr["quality"] = $row["quality"];
|
$arr["quality"] = $row["quality"];
|
||||||
$arr["length"] = $row["length"];
|
$arr["length"] = $row["length"];
|
||||||
|
13
database.sql
13
database.sql
@ -29,9 +29,22 @@ create table if not exists video_tags
|
|||||||
foreign key (video_id) references videos (movie_id)
|
foreign key (video_id) references videos (movie_id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
create table settings
|
||||||
|
(
|
||||||
|
id enum(1) NOT NULL default 0,
|
||||||
|
video_path varchar(255) null,
|
||||||
|
episode_path varchar(255) null,
|
||||||
|
password varchar(32) default '-1' null,
|
||||||
|
mediacenter_name varchar(32) default 'OpenMediaCenter' null,
|
||||||
|
PRIMARY KEY (id)
|
||||||
|
);
|
||||||
|
|
||||||
INSERT INTO tags (tag_id, tag_name)
|
INSERT INTO tags (tag_id, tag_name)
|
||||||
VALUES (2, 'fullhd');
|
VALUES (2, 'fullhd');
|
||||||
INSERT INTO tags (tag_id, tag_name)
|
INSERT INTO tags (tag_id, tag_name)
|
||||||
VALUES (3, 'lowquality');
|
VALUES (3, 'lowquality');
|
||||||
INSERT INTO tags (tag_id, tag_name)
|
INSERT INTO tags (tag_id, tag_name)
|
||||||
VALUES (4, 'hd');
|
VALUES (4, 'hd');
|
||||||
|
|
||||||
|
INSERT INTO settings (video_path, episode_path, password, mediacenter_name)
|
||||||
|
VALUES ('./videos/', './tvshows/', -1, 'OpenMediaCenter');
|
||||||
|
50
src/App.js
50
src/App.js
@ -11,37 +11,57 @@ import CategoryPage from "./pages/CategoryPage/CategoryPage";
|
|||||||
class App extends React.Component {
|
class App extends React.Component {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
this.state = {page: "default"};
|
this.state = {
|
||||||
|
page: "default",
|
||||||
|
generalSettingsLoaded: false,
|
||||||
|
passwordsupport: null,
|
||||||
|
mediacentername: "OpenMediaCenter"
|
||||||
|
};
|
||||||
|
|
||||||
// bind this to the method for being able to call methods such as this.setstate
|
// bind this to the method for being able to call methods such as this.setstate
|
||||||
this.changeRootElement = this.changeRootElement.bind(this);
|
this.changeRootElement = this.changeRootElement.bind(this);
|
||||||
this.returnToLastElement = this.returnToLastElement.bind(this);
|
this.returnToLastElement = this.returnToLastElement.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const updateRequest = new FormData();
|
||||||
|
updateRequest.append('action', 'loadInitialData');
|
||||||
|
|
||||||
|
fetch('/api/Settings.php', {method: 'POST', body: updateRequest})
|
||||||
|
.then((response) => response.json()
|
||||||
|
.then((result) => {
|
||||||
|
console.log(result);
|
||||||
|
this.setState({
|
||||||
|
generalSettingsLoaded: true,
|
||||||
|
passwordsupport: result.passwordEnabled,
|
||||||
|
mediacentername: result.mediacenter_name
|
||||||
|
});
|
||||||
|
console.log(this.state);
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
newElement = null;
|
newElement = null;
|
||||||
|
|
||||||
|
constructViewBinding() {
|
||||||
|
return {
|
||||||
|
changeRootElement: this.changeRootElement,
|
||||||
|
returnToLastElement: this.returnToLastElement
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
MainBody() {
|
MainBody() {
|
||||||
let page;
|
let page;
|
||||||
if (this.state.page === "default") {
|
if (this.state.page === "default") {
|
||||||
page = <HomePage viewbinding={{
|
page = <HomePage viewbinding={this.constructViewBinding()}/>;
|
||||||
changeRootElement: this.changeRootElement,
|
|
||||||
returnToLastElement: this.returnToLastElement
|
|
||||||
}}/>;
|
|
||||||
this.mypage = page;
|
this.mypage = page;
|
||||||
} else if (this.state.page === "random") {
|
} else if (this.state.page === "random") {
|
||||||
page = <RandomPage viewbinding={{
|
page = <RandomPage viewbinding={this.constructViewBinding()}/>;
|
||||||
changeRootElement: this.changeRootElement,
|
|
||||||
returnToLastElement: this.returnToLastElement
|
|
||||||
}}/>;
|
|
||||||
this.mypage = page;
|
this.mypage = page;
|
||||||
} else if (this.state.page === "settings") {
|
} else if (this.state.page === "settings") {
|
||||||
page = <SettingsPage/>;
|
page = <SettingsPage/>;
|
||||||
this.mypage = page;
|
this.mypage = page;
|
||||||
} else if (this.state.page === "categories") {
|
} else if (this.state.page === "categories") {
|
||||||
page = <CategoryPage viewbinding={{
|
page = <CategoryPage viewbinding={this.constructViewBinding()}/>;
|
||||||
changeRootElement: this.changeRootElement,
|
|
||||||
returnToLastElement: this.returnToLastElement
|
|
||||||
}}/>;
|
|
||||||
this.mypage = page;
|
this.mypage = page;
|
||||||
} else if (this.state.page === "video") {
|
} else if (this.state.page === "video") {
|
||||||
// show videoelement if neccessary
|
// show videoelement if neccessary
|
||||||
@ -61,7 +81,7 @@ class App extends React.Component {
|
|||||||
return (
|
return (
|
||||||
<div className="App">
|
<div className="App">
|
||||||
<nav className="navbar navbar-expand-sm bg-primary navbar-dark">
|
<nav className="navbar navbar-expand-sm bg-primary navbar-dark">
|
||||||
<div className="navbar-brand">OpenMediaCenter</div>
|
<div className="navbar-brand">{this.state.mediacentername}</div>
|
||||||
|
|
||||||
<ul className="navbar-nav">
|
<ul className="navbar-nav">
|
||||||
<li className="nav-item">
|
<li className="nav-item">
|
||||||
@ -90,7 +110,7 @@ class App extends React.Component {
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
{this.MainBody()}
|
{this.state.generalSettingsLoaded ? this.MainBody() : "loading"}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,14 @@ import React from 'react';
|
|||||||
import App from './App';
|
import App from './App';
|
||||||
import {shallow} from 'enzyme'
|
import {shallow} from 'enzyme'
|
||||||
|
|
||||||
|
function prepareFetchApi(response) {
|
||||||
|
const mockJsonPromise = Promise.resolve(response);
|
||||||
|
const mockFetchPromise = Promise.resolve({
|
||||||
|
json: () => mockJsonPromise,
|
||||||
|
});
|
||||||
|
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
||||||
|
}
|
||||||
|
|
||||||
describe('<App/>', function () {
|
describe('<App/>', function () {
|
||||||
it('renders without crashing ', function () {
|
it('renders without crashing ', function () {
|
||||||
const wrapper = shallow(<App/>);
|
const wrapper = shallow(<App/>);
|
||||||
@ -20,6 +28,7 @@ describe('<App/>', function () {
|
|||||||
|
|
||||||
it('simulate video view change ', function () {
|
it('simulate video view change ', function () {
|
||||||
const wrapper = shallow(<App/>);
|
const wrapper = shallow(<App/>);
|
||||||
|
wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
|
||||||
|
|
||||||
wrapper.instance().changeRootElement(<div id='testit'></div>);
|
wrapper.instance().changeRootElement(<div id='testit'></div>);
|
||||||
|
|
||||||
@ -28,6 +37,7 @@ describe('<App/>', function () {
|
|||||||
|
|
||||||
it('test hide video again', function () {
|
it('test hide video again', function () {
|
||||||
const wrapper = shallow(<App/>);
|
const wrapper = shallow(<App/>);
|
||||||
|
wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
|
||||||
|
|
||||||
wrapper.instance().changeRootElement(<div id='testit'></div>);
|
wrapper.instance().changeRootElement(<div id='testit'></div>);
|
||||||
|
|
||||||
@ -40,6 +50,7 @@ describe('<App/>', function () {
|
|||||||
|
|
||||||
it('test fallback to last loaded page', function () {
|
it('test fallback to last loaded page', function () {
|
||||||
const wrapper = shallow(<App/>);
|
const wrapper = shallow(<App/>);
|
||||||
|
wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
|
||||||
|
|
||||||
wrapper.find(".nav-link").findWhere(t => t.text() === "Random Video" && t.type() === "div").simulate("click");
|
wrapper.find(".nav-link").findWhere(t => t.text() === "Random Video" && t.type() === "div").simulate("click");
|
||||||
|
|
||||||
@ -54,6 +65,8 @@ describe('<App/>', function () {
|
|||||||
|
|
||||||
it('test home click', function () {
|
it('test home click', function () {
|
||||||
const wrapper = shallow(<App/>);
|
const wrapper = shallow(<App/>);
|
||||||
|
wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
|
||||||
|
|
||||||
wrapper.setState({page: "wrongvalue"});
|
wrapper.setState({page: "wrongvalue"});
|
||||||
expect(wrapper.find("HomePage")).toHaveLength(0);
|
expect(wrapper.find("HomePage")).toHaveLength(0);
|
||||||
wrapper.find(".nav-link").findWhere(t => t.text() === "Home" && t.type() === "div").simulate("click");
|
wrapper.find(".nav-link").findWhere(t => t.text() === "Home" && t.type() === "div").simulate("click");
|
||||||
@ -62,6 +75,7 @@ describe('<App/>', function () {
|
|||||||
|
|
||||||
it('test category click', function () {
|
it('test category click', function () {
|
||||||
const wrapper = shallow(<App/>);
|
const wrapper = shallow(<App/>);
|
||||||
|
wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
|
||||||
|
|
||||||
expect(wrapper.find("CategoryPage")).toHaveLength(0);
|
expect(wrapper.find("CategoryPage")).toHaveLength(0);
|
||||||
wrapper.find(".nav-link").findWhere(t => t.text() === "Categories" && t.type() === "div").simulate("click");
|
wrapper.find(".nav-link").findWhere(t => t.text() === "Categories" && t.type() === "div").simulate("click");
|
||||||
@ -70,9 +84,33 @@ describe('<App/>', function () {
|
|||||||
|
|
||||||
it('test settings click', function () {
|
it('test settings click', function () {
|
||||||
const wrapper = shallow(<App/>);
|
const wrapper = shallow(<App/>);
|
||||||
|
wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
|
||||||
|
|
||||||
expect(wrapper.find("SettingsPage")).toHaveLength(0);
|
expect(wrapper.find("SettingsPage")).toHaveLength(0);
|
||||||
wrapper.find(".nav-link").findWhere(t => t.text() === "Settings" && t.type() === "div").simulate("click");
|
wrapper.find(".nav-link").findWhere(t => t.text() === "Settings" && t.type() === "div").simulate("click");
|
||||||
expect(wrapper.find("SettingsPage")).toHaveLength(1);
|
expect(wrapper.find("SettingsPage")).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('test initial fetch from api', done => {
|
||||||
|
global.fetch = prepareFetchApi({
|
||||||
|
generalSettingsLoaded: true,
|
||||||
|
passwordsupport: true,
|
||||||
|
mediacentername: "testname"
|
||||||
|
});
|
||||||
|
|
||||||
|
const wrapper = shallow(<App/>);
|
||||||
|
|
||||||
|
|
||||||
|
const func = jest.fn();
|
||||||
|
wrapper.instance().setState = func;
|
||||||
|
|
||||||
|
expect(global.fetch).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
|
expect(func).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
global.fetch.mockClear();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -13,10 +13,6 @@ class Preview extends React.Component {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.setState({});
|
|
||||||
}
|
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.setState({
|
this.setState({
|
||||||
previewpicture: null,
|
previewpicture: null,
|
||||||
@ -30,9 +26,9 @@ class Preview extends React.Component {
|
|||||||
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.previewpicture, previewpicture: result
|
previewpicture: result
|
||||||
}));
|
});
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import {shallow, mount} from "enzyme";
|
import {mount, shallow} from "enzyme";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import CategoryPage from "./CategoryPage";
|
import CategoryPage from "./CategoryPage";
|
||||||
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
|
|
||||||
|
|
||||||
function prepareFetchApi(response) {
|
function prepareFetchApi(response) {
|
||||||
const mockJsonPromise = Promise.resolve(response);
|
const mockJsonPromise = Promise.resolve(response);
|
||||||
@ -111,4 +110,21 @@ describe('<CategoryPage/>', function () {
|
|||||||
|
|
||||||
expect(func).toBeCalledTimes(1);
|
expect(func).toBeCalledTimes(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('test sidebar tag clicks', function () {
|
||||||
|
const func = jest.fn();
|
||||||
|
|
||||||
|
const wrapper = mount(<CategoryPage category="fullhd"/>);
|
||||||
|
wrapper.instance().loadTag = func;
|
||||||
|
|
||||||
|
console.log(wrapper.debug());
|
||||||
|
|
||||||
|
expect(func).toBeCalledTimes(0);
|
||||||
|
wrapper.find("SideBar").find("Tag").forEach(e => {
|
||||||
|
e.simulate("click");
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(func).toBeCalledTimes(4);
|
||||||
|
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
131
src/pages/SettingsPage/GeneralSettings.js
Normal file
131
src/pages/SettingsPage/GeneralSettings.js
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
import React from "react";
|
||||||
|
import {Button, Col, Form} from "react-bootstrap";
|
||||||
|
import style from "./GeneralSettings.module.css"
|
||||||
|
|
||||||
|
class GeneralSettings extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
passwordsupport: false,
|
||||||
|
tmdbsupport: null,
|
||||||
|
|
||||||
|
videopath: "",
|
||||||
|
tvshowpath: "",
|
||||||
|
mediacentername: "",
|
||||||
|
password: ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const updateRequest = new FormData();
|
||||||
|
updateRequest.append('action', 'loadGeneralSettings');
|
||||||
|
|
||||||
|
fetch('/api/Settings.php', {method: 'POST', body: updateRequest})
|
||||||
|
.then((response) => response.json()
|
||||||
|
.then((result) => {
|
||||||
|
console.log(result);
|
||||||
|
this.setState({
|
||||||
|
videopath: result.video_path,
|
||||||
|
tvshowpath: result.episode_path,
|
||||||
|
mediacentername: result.mediacenter_name,
|
||||||
|
password: result.password,
|
||||||
|
passwordsupport: result.passwordEnabled,
|
||||||
|
tmdbsupport: result.TMDB_grabbing
|
||||||
|
});
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className={style.GeneralForm}>
|
||||||
|
<Form data-testid='mainformsettings' onSubmit={(e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
this.saveSettings();
|
||||||
|
}}>
|
||||||
|
<Form.Row>
|
||||||
|
<Form.Group as={Col} data-testid="videpathform">
|
||||||
|
<Form.Label>Video Path</Form.Label>
|
||||||
|
<Form.Control type="text" placeholder="/var/www/html/video" value={this.state.videopath}
|
||||||
|
onChange={(ee) => this.setState({videopath: ee.target.value})}/>
|
||||||
|
</Form.Group>
|
||||||
|
|
||||||
|
<Form.Group as={Col} data-testid="tvshowpath">
|
||||||
|
<Form.Label>TV Show Path</Form.Label>
|
||||||
|
<Form.Control type='text' placeholder="/var/www/html/tvshow"
|
||||||
|
value={this.state.tvshowpath}
|
||||||
|
onChange={(e) => this.setState({tvshowpath: e.target.value})}/>
|
||||||
|
</Form.Group>
|
||||||
|
</Form.Row>
|
||||||
|
|
||||||
|
<Form.Check
|
||||||
|
type="switch"
|
||||||
|
id="custom-switch"
|
||||||
|
data-testid='passwordswitch'
|
||||||
|
label="Enable Password support"
|
||||||
|
checked={this.state.passwordsupport}
|
||||||
|
onChange={() => {
|
||||||
|
this.setState({passwordsupport: !this.state.passwordsupport})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Form.Check
|
||||||
|
type="switch"
|
||||||
|
id="custom-switch-2"
|
||||||
|
data-testid='tmdb-switch'
|
||||||
|
label="Enable TMDB video grabbing support"
|
||||||
|
checked={this.state.tmdbsupport}
|
||||||
|
onChange={() => {
|
||||||
|
this.setState({tmdbsupport: !this.state.tmdbsupport})
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{this.state.passwordsupport ?
|
||||||
|
<Form.Group data-testid="passwordfield">
|
||||||
|
<Form.Label>Password</Form.Label>
|
||||||
|
<Form.Control type="password" placeholder="**********" value={this.state.password}
|
||||||
|
onChange={(e) => this.setState({password: e.target.value})}/>
|
||||||
|
</Form.Group> : null
|
||||||
|
}
|
||||||
|
|
||||||
|
<Form.Group className={style.mediacenternameform} data-testid="nameform">
|
||||||
|
<Form.Label>The name of the Mediacenter</Form.Label>
|
||||||
|
<Form.Control type="text" placeholder="Mediacentername" value={this.state.mediacentername}
|
||||||
|
onChange={(e) => this.setState({mediacentername: e.target.value})}/>
|
||||||
|
</Form.Group>
|
||||||
|
|
||||||
|
<Button variant="primary" type="submit">
|
||||||
|
Submit
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
saveSettings() {
|
||||||
|
const updateRequest = new FormData();
|
||||||
|
updateRequest.append('action', 'saveGeneralSettings');
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
fetch('/api/Settings.php', {method: 'POST', body: updateRequest})
|
||||||
|
.then((response) => response.json()
|
||||||
|
.then((result) => {
|
||||||
|
if (result.success) {
|
||||||
|
console.log("successfully saved settings");
|
||||||
|
// todo 2020-07-10: popup success
|
||||||
|
} else {
|
||||||
|
console.log("failed to save settings");
|
||||||
|
// todo 2020-07-10: popup error
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default GeneralSettings;
|
8
src/pages/SettingsPage/GeneralSettings.module.css
Normal file
8
src/pages/SettingsPage/GeneralSettings.module.css
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
.GeneralForm {
|
||||||
|
width: 60%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mediacenternameform {
|
||||||
|
margin-top: 25px;
|
||||||
|
width: 40%;
|
||||||
|
}
|
110
src/pages/SettingsPage/GeneralSettings.test.js
Normal file
110
src/pages/SettingsPage/GeneralSettings.test.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
import {shallow} from "enzyme";
|
||||||
|
import React from "react";
|
||||||
|
import GeneralSettings from "./GeneralSettings";
|
||||||
|
|
||||||
|
function prepareFetchApi(response) {
|
||||||
|
const mockJsonPromise = Promise.resolve(response);
|
||||||
|
const mockFetchPromise = Promise.resolve({
|
||||||
|
json: () => mockJsonPromise,
|
||||||
|
});
|
||||||
|
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('<GeneralSettings/>', function () {
|
||||||
|
it('renders without crashing ', function () {
|
||||||
|
const wrapper = shallow(<GeneralSettings/>);
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
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(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test savesettings', done => {
|
||||||
|
const wrapper = shallow(<GeneralSettings/>);
|
||||||
|
|
||||||
|
global.fetch = prepareFetchApi({success: true});
|
||||||
|
|
||||||
|
expect(global.fetch).toBeCalledTimes(0);
|
||||||
|
const fakeEvent = {preventDefault: () => console.log('preventDefault')};
|
||||||
|
wrapper.find("[data-testid='mainformsettings']").simulate("submit", fakeEvent);
|
||||||
|
expect(global.fetch).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
|
// todo 2020-07-13: test popup of error success here
|
||||||
|
|
||||||
|
global.fetch.mockClear();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test failing savesettings', done => {
|
||||||
|
const wrapper = shallow(<GeneralSettings/>);
|
||||||
|
|
||||||
|
global.fetch = prepareFetchApi({success: false});
|
||||||
|
|
||||||
|
expect(global.fetch).toBeCalledTimes(0);
|
||||||
|
const fakeEvent = {preventDefault: () => console.log('preventDefault')};
|
||||||
|
wrapper.find("[data-testid='mainformsettings']").simulate("submit", fakeEvent);
|
||||||
|
expect(global.fetch).toBeCalledTimes(1);
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
|
// todo 2020-07-13: test error popup here!
|
||||||
|
|
||||||
|
global.fetch.mockClear();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test videopath change event', function () {
|
||||||
|
const wrapper = shallow(<GeneralSettings/>);
|
||||||
|
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
|
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");
|
||||||
|
});
|
||||||
|
|
||||||
|
it('test tmdbsupport change event', function () {
|
||||||
|
const wrapper = shallow(<GeneralSettings/>);
|
||||||
|
wrapper.setState({tmdbsupport: true});
|
||||||
|
|
||||||
|
expect(wrapper.state().tmdbsupport).toBe(true);
|
||||||
|
wrapper.find("[data-testid='tmdb-switch']").simulate("change");
|
||||||
|
expect(wrapper.state().tmdbsupport).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
89
src/pages/SettingsPage/MovieSettings.js
Normal file
89
src/pages/SettingsPage/MovieSettings.js
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
import React from "react";
|
||||||
|
import style from "./MovieSettings.module.css"
|
||||||
|
|
||||||
|
class MovieSettings extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
text: [],
|
||||||
|
startbtnDisabled: false
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
if (this.myinterval) {
|
||||||
|
clearInterval(this.myinterval);
|
||||||
|
}
|
||||||
|
this.myinterval = setInterval(this.updateStatus, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
clearInterval(this.myinterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<button disabled={this.state.startbtnDisabled} className='reindexbtn btn btn-success' onClick={() => {
|
||||||
|
this.startReindex()
|
||||||
|
}}>Reindex Movies
|
||||||
|
</button>
|
||||||
|
<div className={style.indextextarea}>{this.state.text.map(m => (
|
||||||
|
<div className='textarea-element'>{m}</div>
|
||||||
|
))}</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
startReindex() {
|
||||||
|
// clear output text before start
|
||||||
|
this.setState({text: []});
|
||||||
|
|
||||||
|
this.setState({startbtnDisabled: true});
|
||||||
|
|
||||||
|
console.log("starting");
|
||||||
|
const updateRequest = new FormData();
|
||||||
|
// fetch all videos available
|
||||||
|
fetch('/api/extractvideopreviews.php', {method: 'POST', body: updateRequest})
|
||||||
|
.then((response) => response.json()
|
||||||
|
.then((result) => {
|
||||||
|
// todo 2020-07-4: some kind of start event
|
||||||
|
console.log("returned");
|
||||||
|
}))
|
||||||
|
.catch(() => {
|
||||||
|
console.log("no connection to backend");
|
||||||
|
});
|
||||||
|
if (this.myinterval) {
|
||||||
|
clearInterval(this.myinterval);
|
||||||
|
}
|
||||||
|
this.myinterval = setInterval(this.updateStatus, 1000);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStatus = () => {
|
||||||
|
const updateRequest = new FormData();
|
||||||
|
fetch('/api/extractionData.php', {method: 'POST', body: updateRequest})
|
||||||
|
.then((response) => response.json()
|
||||||
|
.then((result) => {
|
||||||
|
if (result.contentAvailable === true) {
|
||||||
|
console.log(result);
|
||||||
|
// todo 2020-07-4: scroll to bottom of div here
|
||||||
|
this.setState({
|
||||||
|
// insert a string for each line
|
||||||
|
text: [...result.message.split("\n"),
|
||||||
|
...this.state.text]
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// clear refresh interval if no content available
|
||||||
|
clearInterval(this.myinterval);
|
||||||
|
|
||||||
|
this.setState({startbtnDisabled: false});
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
.catch(() => {
|
||||||
|
console.log("no connection to backend");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MovieSettings;
|
13
src/pages/SettingsPage/MovieSettings.module.css
Normal file
13
src/pages/SettingsPage/MovieSettings.module.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
.indextextarea {
|
||||||
|
margin-top: 15px;
|
||||||
|
padding: 10px;
|
||||||
|
|
||||||
|
overflow-y: scroll;
|
||||||
|
overflow-x: auto;
|
||||||
|
|
||||||
|
min-height: 100px;
|
||||||
|
max-height: 300px;
|
||||||
|
width: 50%;
|
||||||
|
background-color: #c2c2c2;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
62
src/pages/SettingsPage/MovieSettings.test.js
Normal file
62
src/pages/SettingsPage/MovieSettings.test.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
import {shallow} from "enzyme";
|
||||||
|
import React from "react";
|
||||||
|
import MovieSettings from "./MovieSettings";
|
||||||
|
|
||||||
|
function prepareFetchApi(response) {
|
||||||
|
const mockJsonPromise = Promise.resolve(response);
|
||||||
|
const mockFetchPromise = Promise.resolve({
|
||||||
|
json: () => mockJsonPromise,
|
||||||
|
});
|
||||||
|
return (jest.fn().mockImplementation(() => mockFetchPromise));
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('<MovieSettings/>', function () {
|
||||||
|
it('renders without crashing ', function () {
|
||||||
|
const wrapper = shallow(<MovieSettings/>);
|
||||||
|
wrapper.unmount();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('received text renders into dom', function () {
|
||||||
|
const wrapper = shallow(<MovieSettings/>);
|
||||||
|
|
||||||
|
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(<MovieSettings/>);
|
||||||
|
|
||||||
|
wrapper.find(".reindexbtn").simulate("click");
|
||||||
|
|
||||||
|
// initial send of reindex request to server
|
||||||
|
expect(global.fetch).toBeCalledTimes(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('content available received and in state', done => {
|
||||||
|
global.fetch = prepareFetchApi({
|
||||||
|
contentAvailable: true,
|
||||||
|
message: "firstline\nsecondline"
|
||||||
|
});
|
||||||
|
const wrapper = shallow(<MovieSettings/>);
|
||||||
|
wrapper.instance().updateStatus();
|
||||||
|
|
||||||
|
process.nextTick(() => {
|
||||||
|
expect(wrapper.state()).toMatchObject({
|
||||||
|
text: [
|
||||||
|
"firstline",
|
||||||
|
"secondline"
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
global.fetch.mockClear();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -1,82 +1,52 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import PageTitle from "../../elements/PageTitle/PageTitle";
|
import MovieSettings from "./MovieSettings";
|
||||||
|
import GeneralSettings from "./GeneralSettings";
|
||||||
|
import style from "./SettingsPage.module.css"
|
||||||
|
|
||||||
|
|
||||||
class SettingsPage extends React.Component {
|
class SettingsPage extends React.Component {
|
||||||
constructor(props, context) {
|
constructor(props, context) {
|
||||||
super(props, context);
|
super(props, context);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
text: []
|
currentpage: "general"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
updateStatus = () => {
|
getContent() {
|
||||||
const updateRequest = new FormData();
|
switch (this.state.currentpage) {
|
||||||
fetch('/api/extractionData.php', {method: 'POST', body: updateRequest})
|
case "general":
|
||||||
.then((response) => response.json()
|
return <GeneralSettings/>;
|
||||||
.then((result) => {
|
case "movies":
|
||||||
if (result.contentAvailable === true) {
|
return <MovieSettings/>;
|
||||||
console.log(result);
|
case "tv":
|
||||||
this.setState({
|
return <span/>; // todo this page
|
||||||
text: [...result.message.split("\n"),
|
default:
|
||||||
...this.state.text]
|
return "unknown button clicked";
|
||||||
});
|
|
||||||
} else {
|
|
||||||
clearInterval(this.myinterval);
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
.catch(() => {
|
|
||||||
console.log("no connection to backend");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
if (this.myinterval) {
|
|
||||||
clearInterval(this.myinterval);
|
|
||||||
}
|
}
|
||||||
this.myinterval = setInterval(this.updateStatus, 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
clearInterval(this.myinterval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<PageTitle
|
<div className={style.SettingsSidebar}>
|
||||||
title='Settings Page'
|
<div className={style.SettingsSidebarTitle}>Settings</div>
|
||||||
subtitle='todo'/>
|
<div onClick={() => this.setState({currentpage: "general"})}
|
||||||
|
className={style.SettingSidebarElement}>General
|
||||||
<button className='reindexbtn btn btn-success' onClick={() => {
|
</div>
|
||||||
this.startReindex()
|
<div onClick={() => this.setState({currentpage: "movies"})}
|
||||||
}}>Reindex Movies
|
className={style.SettingSidebarElement}>Movies
|
||||||
</button>
|
</div>
|
||||||
<div className='indextextarea'>{this.state.text.map(m => (
|
<div onClick={() => this.setState({currentpage: "tv"})}
|
||||||
<div className='textarea-element'>{m}</div>
|
className={style.SettingSidebarElement}>TV Shows
|
||||||
))}</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className={style.SettingsContent}>
|
||||||
|
{this.getContent()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
startReindex() {
|
|
||||||
console.log("starting");
|
|
||||||
const updateRequest = new FormData();
|
|
||||||
// fetch all videos available
|
|
||||||
fetch('/api/extractvideopreviews.php', {method: 'POST', body: updateRequest})
|
|
||||||
.then((response) => response.json()
|
|
||||||
.then((result) => {
|
|
||||||
console.log("returned");
|
|
||||||
}))
|
|
||||||
.catch(() => {
|
|
||||||
console.log("no connection to backend");
|
|
||||||
});
|
|
||||||
if (this.myinterval) {
|
|
||||||
clearInterval(this.myinterval);
|
|
||||||
}
|
|
||||||
this.myinterval = setInterval(this.updateStatus, 1000);
|
|
||||||
console.log("sent");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default SettingsPage;
|
export default SettingsPage;
|
||||||
|
40
src/pages/SettingsPage/SettingsPage.module.css
Normal file
40
src/pages/SettingsPage/SettingsPage.module.css
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
.SettingsSidebar {
|
||||||
|
padding-top: 20px;
|
||||||
|
float: left;
|
||||||
|
width: 10%;
|
||||||
|
background-color: #d3dcef;
|
||||||
|
min-height: calc(100vh - 56px);
|
||||||
|
min-width: 110px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingsSidebarTitle {
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: larger;
|
||||||
|
margin-bottom: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingsContent {
|
||||||
|
float: left;
|
||||||
|
width: 80%;
|
||||||
|
padding-left: 30px;
|
||||||
|
padding-top: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingSidebarElement {
|
||||||
|
margin: 10px 5px 5px;
|
||||||
|
padding: 5px;
|
||||||
|
background-color: #a8b2de;
|
||||||
|
text-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
border-radius: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.SettingSidebarElement:hover {
|
||||||
|
font-weight: bolder;
|
||||||
|
background-color: #7d8dd4;
|
||||||
|
box-shadow: #7d8dd4 0 0 0 5px;
|
||||||
|
transition: all 300ms;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
@ -16,26 +16,33 @@ describe('<RandomPage/>', function () {
|
|||||||
wrapper.unmount();
|
wrapper.unmount();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('received text renders into dom', function () {
|
it('simulate topic clicka', function () {
|
||||||
const wrapper = shallow(<SettingsPage/>);
|
const wrapper = shallow(<SettingsPage/>);
|
||||||
|
|
||||||
wrapper.setState({
|
simulateSideBarClick("General", wrapper);
|
||||||
text: [
|
expect(wrapper.state().currentpage).toBe("general");
|
||||||
"firstline",
|
expect(wrapper.find(".SettingsContent").find("GeneralSettings")).toHaveLength(1);
|
||||||
"secline"
|
|
||||||
]
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(wrapper.find(".indextextarea").find(".textarea-element")).toHaveLength(2);
|
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);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('test simulate reindex', function () {
|
function simulateSideBarClick(name, wrapper) {
|
||||||
global.fetch = prepareFetchApi({});
|
wrapper.find(".SettingSidebarElement").findWhere(it =>
|
||||||
|
it.text() === name &&
|
||||||
|
it.type() === "div").simulate("click");
|
||||||
|
}
|
||||||
|
|
||||||
|
it('simulate unknown topic', function () {
|
||||||
const wrapper = shallow(<SettingsPage/>);
|
const wrapper = shallow(<SettingsPage/>);
|
||||||
|
wrapper.setState({currentpage: "unknown"});
|
||||||
|
|
||||||
wrapper.find(".reindexbtn").simulate("click");
|
expect(wrapper.find(".SettingsContent").text()).toBe("unknown button clicked");
|
||||||
|
|
||||||
// initial send of reindex request to server
|
|
||||||
expect(global.fetch).toBeCalledTimes(1);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user