diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b21dcf8..35aea6a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,7 @@ stages: - prepare - build - test + - deploy cache: paths: @@ -11,6 +12,7 @@ cache: include: - template: SAST.gitlab-ci.yml + - template: Code-Quality.gitlab-ci.yml variables: SAST_DISABLE_DIND: "true" @@ -28,6 +30,7 @@ build: expire_in: 7 days paths: - build/ + needs: ["prepare"] test: stage: test @@ -37,6 +40,7 @@ test: reports: junit: - ./junit.xml + needs: ["prepare"] coverage: stage: test @@ -46,3 +50,21 @@ coverage: reports: cobertura: - ./coverage/cobertura-coverage.xml + needs: ["prepare"] + +deploy_test1: + stage: deploy + image: luki42/alpineopenssh:latest + needs: + - test + - build + only: + - master + script: + - eval $(ssh-agent -s) + - ssh-add <(echo "$SSH_PRIVATE_KEY") + - mkdir -p ~/.ssh + - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config' + - scp -r build/* root@192.168.0.42:/var/www/html/ + - scp -r api/ root@192.168.0.42:/var/www/html/ + diff --git a/src/App.js b/src/App.js index 0bc97e0..6aba9c4 100644 --- a/src/App.js +++ b/src/App.js @@ -11,6 +11,8 @@ import SettingsPage from "./pages/SettingsPage/SettingsPage"; import CategoryPage from "./pages/CategoryPage/CategoryPage"; class App extends React.Component { + newElement = null; + constructor(props, context) { super(props, context); this.state = { @@ -45,8 +47,6 @@ class App extends React.Component { })); } - newElement = null; - constructViewBinding() { return { changeRootElement: this.changeRootElement, diff --git a/src/App.test.js b/src/App.test.js index bb341c0..cc12113 100644 --- a/src/App.test.js +++ b/src/App.test.js @@ -2,14 +2,6 @@ import React from 'react'; import App from './App'; import {shallow} from 'enzyme' -function prepareFetchApi(response) { - const mockJsonPromise = Promise.resolve(response); - const mockFetchPromise = Promise.resolve({ - json: () => mockJsonPromise, - }); - return (jest.fn().mockImplementation(() => mockFetchPromise)); -} - describe('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -92,7 +84,7 @@ describe('', function () { }); it('test initial fetch from api', done => { - global.fetch = prepareFetchApi({ + global.fetch = global.prepareFetchApi({ generalSettingsLoaded: true, passwordsupport: true, mediacentername: "testname" diff --git a/src/elements/Preview/Preview.js b/src/elements/Preview/Preview.js index 82cbadf..0a1cb5a 100644 --- a/src/elements/Preview/Preview.js +++ b/src/elements/Preview/Preview.js @@ -39,7 +39,7 @@ class Preview extends React.Component {
this.itemClick()}>
{this.state.name}
- {this.state.previewpicture != null ? + {this.state.previewpicture !== null ? Pic loading. : diff --git a/src/elements/Preview/Preview.module.css b/src/elements/Preview/Preview.module.css index a369f71..ae23695 100644 --- a/src/elements/Preview/Preview.module.css +++ b/src/elements/Preview/Preview.module.css @@ -1,15 +1,17 @@ .previewtitle { height: 20px; text-align: center; - font-weight: bold; - max-width: 266px; font-size: smaller; + font-weight: bold; + height: 20px; + max-width: 266px; + text-align: center; } .previewpic { - min-width: 266px; - min-height: 150px; height: 80%; + min-height: 150px; + min-width: 266px; overflow: hidden; text-align: center; } @@ -17,14 +19,14 @@ .loadAnimation { display: inline-block; line-height: 150px; - vertical-align: center; + vertical-align: middle; } .previewimage { - min-height: 150px; max-height: 400px; - min-width: 266px; max-width: 410px; + min-height: 150px; + min-width: 266px; } .previewbottom { @@ -32,12 +34,12 @@ } .videopreview { + border-radius: 20px; + cursor: pointer; float: left; margin-left: 25px; margin-top: 25px; - cursor: pointer; opacity: 0.85; - border-radius: 20px; } .videopreview:hover { @@ -46,11 +48,11 @@ } .tagpreview { - text-transform: uppercase; - font-weight: bolder; font-size: x-large; - text-align: center; + font-weight: bolder; height: 150px; + text-align: center; + text-transform: uppercase; width: 266px; } diff --git a/src/elements/SideBar/SideBar.module.css b/src/elements/SideBar/SideBar.module.css index fcb93c9..1ced68e 100644 --- a/src/elements/SideBar/SideBar.module.css +++ b/src/elements/SideBar/SideBar.module.css @@ -1,22 +1,22 @@ .sideinfo { - width: 20%; - float: left; - padding: 20px; - margin-top: 25px; - margin-left: 15px; - border-radius: 20px; border: 2px #3574fe solid; + border-radius: 20px; + float: left; + margin-left: 15px; + margin-top: 25px; overflow: hidden; + padding: 20px; + width: 20%; } .sidebartitle { - font-weight: bold; font-size: larger; + font-weight: bold; } .sidebarinfo { - margin-top: 5px; border-radius: 5px; + margin-top: 5px; padding: 2px 10px 2px 15px; width: 220px; } diff --git a/src/elements/Tag/Tag.module.css b/src/elements/Tag/Tag.module.css index 8af1b1f..e8ac9dc 100644 --- a/src/elements/Tag/Tag.module.css +++ b/src/elements/Tag/Tag.module.css @@ -1,12 +1,12 @@ .tagbtn { - color: white; - margin: 10px; background-color: #3574fe; border: none; border-radius: 10px; - padding: 5px 15px 5px 15px; - /*font-weight: bold;*/ + color: white; display: block; + margin: 10px; + /*font-weight: bold;*/ + padding: 5px 15px 5px 15px; } .tagbtn:focus { diff --git a/src/elements/Tag/Tag.test.js b/src/elements/Tag/Tag.test.js index f0ea51d..f53bfbc 100644 --- a/src/elements/Tag/Tag.test.js +++ b/src/elements/Tag/Tag.test.js @@ -5,14 +5,6 @@ import "@testing-library/jest-dom" import {shallow} from 'enzyme' describe('', function () { - function prepareFetchApi(response) { - const mockJsonPromise = Promise.resolve(response); - const mockFetchPromise = Promise.resolve({ - json: () => mockJsonPromise, - }); - return (jest.fn().mockImplementation(() => mockFetchPromise)); - } - it('renders without crashing ', function () { const wrapper = shallow(test); wrapper.unmount(); @@ -24,7 +16,7 @@ describe('', function () { }); it('click event triggered and setvideo callback called', function () { - global.fetch = prepareFetchApi({}); + global.fetch = global.prepareFetchApi({}); const func = jest.fn(); const elem = { changeRootElement: () => func() diff --git a/src/elements/VideoContainer/VideoContainer.js b/src/elements/VideoContainer/VideoContainer.js index ac95277..a59baab 100644 --- a/src/elements/VideoContainer/VideoContainer.js +++ b/src/elements/VideoContainer/VideoContainer.js @@ -3,6 +3,9 @@ import Preview from "../Preview/Preview"; import style from "./VideoContainer.module.css" class VideoContainer extends React.Component { + // stores current index of loaded elements + loadindex = 0; + constructor(props, context) { super(props, context); @@ -14,9 +17,6 @@ class VideoContainer extends React.Component { }; } - // stores current index of loaded elements - loadindex = 0; - componentDidMount() { document.addEventListener('scroll', this.trackScrolling); diff --git a/src/pages/CategoryPage/CategoryPage.test.js b/src/pages/CategoryPage/CategoryPage.test.js index 1f739fa..5f806d7 100644 --- a/src/pages/CategoryPage/CategoryPage.test.js +++ b/src/pages/CategoryPage/CategoryPage.test.js @@ -2,14 +2,6 @@ import {mount, shallow} from "enzyme"; import React from "react"; import CategoryPage from "./CategoryPage"; -function prepareFetchApi(response) { - const mockJsonPromise = Promise.resolve(response); - const mockFetchPromise = Promise.resolve({ - json: () => mockJsonPromise, - }); - return (jest.fn().mockImplementation(() => mockFetchPromise)); -} - describe('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -17,7 +9,7 @@ describe('', function () { }); it('test tag fetch call', done => { - global.fetch = prepareFetchApi(["first", "second"]); + global.fetch = global.prepareFetchApi(["first", "second"]); const wrapper = shallow(); @@ -33,14 +25,14 @@ describe('', function () { }); it('test errored fetch call', done => { - global.fetch = prepareFetchApi({}); + global.fetch = global.prepareFetchApi({}); let message; global.console.log = jest.fn((m) => { message = m; }); - const wrapper = shallow(); + shallow(); expect(global.fetch).toHaveBeenCalledTimes(1); @@ -67,7 +59,7 @@ describe('', function () { }); it('test setpage callback', done => { - global.fetch = prepareFetchApi([{}, {}]); + global.fetch = global.prepareFetchApi([{}, {}]); const wrapper = mount(); @@ -106,7 +98,7 @@ describe('', function () { const func = jest.fn(); CategoryPage.prototype.fetchVideoData = func; - const wrapper = shallow(); + shallow(); expect(func).toBeCalledTimes(1); }); diff --git a/src/pages/HomePage/HomePage.js b/src/pages/HomePage/HomePage.js index 5f92a23..4b2a14e 100644 --- a/src/pages/HomePage/HomePage.js +++ b/src/pages/HomePage/HomePage.js @@ -1,5 +1,5 @@ import React from "react"; -import SideBar, {SideBarTitle, SideBarItem} from "../../elements/SideBar/SideBar"; +import SideBar, {SideBarItem, SideBarTitle} from "../../elements/SideBar/SideBar"; import Tag from "../../elements/Tag/Tag"; import VideoContainer from "../../elements/VideoContainer/VideoContainer"; @@ -7,6 +7,9 @@ import style from "./HomePage.module.css" import PageTitle, {Line} from "../../elements/PageTitle/PageTitle"; class HomePage extends React.Component { + /** keyword variable needed temporary store search keyword */ + keyword = ""; + constructor(props, context) { super(props, context); @@ -24,9 +27,6 @@ class HomePage extends React.Component { }; } - /** keyword variable needed temporary store search keyword */ - keyword = ""; - componentDidMount() { // initial get of all videos this.fetchVideoData("all"); diff --git a/src/pages/HomePage/HomePage.module.css b/src/pages/HomePage/HomePage.module.css index 977257e..3b1a495 100644 --- a/src/pages/HomePage/HomePage.module.css +++ b/src/pages/HomePage/HomePage.module.css @@ -4,6 +4,6 @@ } .searchform { - margin-top: 25px; float: right; + margin-top: 25px; } diff --git a/src/pages/HomePage/HomePage.test.js b/src/pages/HomePage/HomePage.test.js index da78fc2..8c3cc15 100644 --- a/src/pages/HomePage/HomePage.test.js +++ b/src/pages/HomePage/HomePage.test.js @@ -3,19 +3,6 @@ import React from "react"; import HomePage from "./HomePage"; 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)); -} - -function prepareFailingFetchApi() { - const mockFetchPromise = Promise.reject("myreason"); - return (jest.fn().mockImplementation(() => mockFetchPromise)); -} - describe('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -51,7 +38,7 @@ describe('', function () { }); it('test search field', done => { - global.fetch = prepareFetchApi([{}, {}]); + global.fetch = global.prepareFetchApi([{}, {}]); const wrapper = shallow(); @@ -68,7 +55,7 @@ describe('', function () { }); it('test form submit', done => { - global.fetch = prepareFetchApi([{}, {}]); + global.fetch = global.prepareFetchApi([{}, {}]); const wrapper = shallow(); @@ -88,14 +75,14 @@ describe('', function () { it('test no backend connection behaviour', done => { // this test assumes a console.log within every connection fail - global.fetch = prepareFailingFetchApi(); + global.fetch = global.prepareFailingFetchApi(); let count = 0; - global.console.log = jest.fn((m) => { + global.console.log = jest.fn(() => { count++; }); - const wrapper = shallow(); + shallow(); process.nextTick(() => { // state to be set correctly with response diff --git a/src/pages/Player/Player.js b/src/pages/Player/Player.js index 03bd5af..d9b4906 100644 --- a/src/pages/Player/Player.js +++ b/src/pages/Player/Player.js @@ -2,28 +2,13 @@ import React from "react"; import style from "./Player.module.css" import {PlyrComponent} from 'plyr-react'; -import SideBar, {SideBarTitle, SideBarItem} from "../../elements/SideBar/SideBar"; +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"; class Player extends React.Component { - constructor(props, context) { - super(props, context); - - this.state = { - sources: null, - movie_id: null, - movie_name: null, - likes: null, - quality: null, - length: null, - tags: [], - popupvisible: false - }; - } - options = { controls: [ 'play-large', // The large play button in the center @@ -41,6 +26,21 @@ class Player extends React.Component { ] }; + constructor(props, context) { + super(props, context); + + this.state = { + sources: null, + movie_id: null, + movie_name: null, + likes: null, + quality: null, + length: null, + tags: [], + popupvisible: false + }; + } + componentDidMount() { this.fetchMovieData(); } diff --git a/src/pages/Player/Player.module.css b/src/pages/Player/Player.module.css index 4a9322a..115329b 100644 --- a/src/pages/Player/Player.module.css +++ b/src/pages/Player/Player.module.css @@ -1,17 +1,18 @@ .closebutton { - color: white; + background-color: #FF0000; border: none; border-radius: 10px; - padding: 5px 15px 5px 15px; - background-color: #FF0000; - margin-top: 25px; + color: white; margin-left: 25px; + margin-top: 25px; + padding: 5px 15px 5px 15px; } .videowrapper { - margin-left: 20px; display: block; float: left; + margin-left: 20px; + margin-top: 25px; width: 60%; margin-top: 20px; } diff --git a/src/pages/Player/Player.test.js b/src/pages/Player/Player.test.js index 2ac02e2..67b5bab 100644 --- a/src/pages/Player/Player.test.js +++ b/src/pages/Player/Player.test.js @@ -2,14 +2,6 @@ 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('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -32,7 +24,7 @@ describe('', function () { }); it('likebtn click', done => { - global.fetch = prepareFetchApi({result: 'success'}); + global.fetch = global.prepareFetchApi({result: 'success'}); const func = jest.fn(); @@ -59,7 +51,7 @@ describe('', function () { }); it('errored likebtn click', done => { - global.fetch = prepareFetchApi({result: 'nosuccess'}); + global.fetch = global.prepareFetchApi({result: 'nosuccess'}); const func = jest.fn(); const wrapper = shallow(); diff --git a/src/pages/RandomPage/RandomPage.module.css b/src/pages/RandomPage/RandomPage.module.css index 50d6ce4..566addb 100644 --- a/src/pages/RandomPage/RandomPage.module.css +++ b/src/pages/RandomPage/RandomPage.module.css @@ -1,19 +1,19 @@ .Shufflebutton { - width: 100%; align-content: center; + width: 100%; } .btnshuffle { background-color: #39a945; - color: white; - margin-top: 20px; - margin-left: 45%; border: none; border-radius: 10px; - padding: 15px 25px 15px 25px; - font-weight: bold; + color: white; font-size: larger; + font-weight: bold; + margin-left: 45%; + margin-top: 20px; + padding: 15px 25px 15px 25px; } .btnshuffle:focus { diff --git a/src/pages/RandomPage/RandomPage.test.js b/src/pages/RandomPage/RandomPage.test.js index beeeeca..afb8c61 100644 --- a/src/pages/RandomPage/RandomPage.test.js +++ b/src/pages/RandomPage/RandomPage.test.js @@ -2,14 +2,6 @@ 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('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -17,22 +9,24 @@ describe('', function () { }); it('test shuffleload fetch', function () { - global.fetch = prepareFetchApi({}); + global.fetch = global.prepareFetchApi({}); - const wrapper = shallow(); + shallow(); expect(global.fetch).toBeCalledTimes(1); }); it('btnshuffle click test', function () { - global.fetch = prepareFetchApi({}); + global.fetch = global.prepareFetchApi({}); const wrapper = shallow(); // simulate at least one existing element - wrapper.setState({videos: [ + wrapper.setState({ + videos: [ {} - ]}); + ] + }); wrapper.find(".btnshuffle").simulate("click"); diff --git a/src/pages/SettingsPage/GeneralSettings.test.js b/src/pages/SettingsPage/GeneralSettings.test.js index 6d8ba59..fd675c9 100644 --- a/src/pages/SettingsPage/GeneralSettings.test.js +++ b/src/pages/SettingsPage/GeneralSettings.test.js @@ -3,14 +3,6 @@ import React from "react"; import GeneralSettings from "./GeneralSettings"; import GlobalInfos from "../../GlobalInfos"; -function prepareFetchApi(response) { - const mockJsonPromise = Promise.resolve(response); - const mockFetchPromise = Promise.resolve({ - json: () => mockJsonPromise, - }); - return (jest.fn().mockImplementation(() => mockFetchPromise)); -} - describe('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -38,7 +30,7 @@ describe('', function () { it('test savesettings', done => { const wrapper = shallow(); - global.fetch = prepareFetchApi({success: true}); + global.fetch = global.prepareFetchApi({success: true}); expect(global.fetch).toBeCalledTimes(0); const fakeEvent = {preventDefault: () => console.log('preventDefault')}; @@ -56,7 +48,7 @@ describe('', function () { it('test failing savesettings', done => { const wrapper = shallow(); - global.fetch = prepareFetchApi({success: false}); + global.fetch = global.prepareFetchApi({success: false}); expect(global.fetch).toBeCalledTimes(0); const fakeEvent = {preventDefault: () => console.log('preventDefault')}; diff --git a/src/pages/SettingsPage/MovieSettings.module.css b/src/pages/SettingsPage/MovieSettings.module.css index 4551e8d..77e35e7 100644 --- a/src/pages/SettingsPage/MovieSettings.module.css +++ b/src/pages/SettingsPage/MovieSettings.module.css @@ -1,13 +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; + + margin-top: 15px; + max-height: 300px; + + min-height: 100px; + overflow-x: auto; + overflow-y: scroll; + padding: 10px; + width: 50%; } diff --git a/src/pages/SettingsPage/MovieSettings.test.js b/src/pages/SettingsPage/MovieSettings.test.js index 51d38c3..f12734f 100644 --- a/src/pages/SettingsPage/MovieSettings.test.js +++ b/src/pages/SettingsPage/MovieSettings.test.js @@ -2,14 +2,6 @@ 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('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -30,7 +22,7 @@ describe('', function () { }); it('test simulate reindex', function () { - global.fetch = prepareFetchApi({}); + global.fetch = global.prepareFetchApi({}); const wrapper = shallow(); wrapper.find(".reindexbtn").simulate("click"); @@ -40,7 +32,7 @@ describe('', function () { }); it('content available received and in state', done => { - global.fetch = prepareFetchApi({ + global.fetch = global.prepareFetchApi({ contentAvailable: true, message: "firstline\nsecondline" }); diff --git a/src/pages/SettingsPage/SettingsPage.module.css b/src/pages/SettingsPage/SettingsPage.module.css index e4f9eda..965d459 100644 --- a/src/pages/SettingsPage/SettingsPage.module.css +++ b/src/pages/SettingsPage/SettingsPage.module.css @@ -1,42 +1,41 @@ .SettingsSidebar { - padding-top: 20px; + border-bottom-right-radius: 10px; + border-top-right-radius: 10px; float: left; - width: 10%; min-height: calc(100vh - 62px); min-width: 110px; - - border-top-right-radius: 10px; - border-bottom-right-radius: 10px; + padding-top: 20px; + width: 10%; } .SettingsSidebarTitle { - text-align: center; - font-weight: bold; - text-transform: uppercase; font-size: larger; + font-weight: bold; margin-bottom: 25px; + text-align: center; + text-transform: uppercase; } .SettingsContent { float: left; - width: 80%; padding-left: 30px; padding-top: 30px; + width: 80%; } .SettingSidebarElement { + background-color: #919fd9; + border-radius: 7px; + font-weight: bold; margin: 10px 5px 5px; padding: 5px; - background-color: #919fd9; 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; + font-weight: bolder; + transition: all 300ms; } diff --git a/src/pages/SettingsPage/SettingsPage.test.js b/src/pages/SettingsPage/SettingsPage.test.js index 735cea9..8a45deb 100644 --- a/src/pages/SettingsPage/SettingsPage.test.js +++ b/src/pages/SettingsPage/SettingsPage.test.js @@ -2,14 +2,6 @@ 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('', function () { it('renders without crashing ', function () { const wrapper = shallow(); diff --git a/src/setupTests.js b/src/setupTests.js index cfe9893..325f27d 100644 --- a/src/setupTests.js +++ b/src/setupTests.js @@ -8,3 +8,16 @@ import {configure} from 'enzyme'; import Adapter from 'enzyme-adapter-react-16'; configure({adapter: new Adapter()}); + +global.prepareFetchApi = (response) => { + const mockJsonPromise = Promise.resolve(response); + const mockFetchPromise = Promise.resolve({ + json: () => mockJsonPromise, + }); + return (jest.fn().mockImplementation(() => mockFetchPromise)); +} + +global.prepareFailingFetchApi = () => { + const mockFetchPromise = Promise.reject("myreason"); + return (jest.fn().mockImplementation(() => mockFetchPromise)); +}