...
 
Commits (21)
{
"env": {
"development": {
"presets": "next/babel"
"presets": [
"next/babel"
]
},
"production": {
"presets": "next/babel"
"presets": [
"next/babel"
]
},
"test": {
"presets": [
[
"env",
"next/babel",
{
"modules": "commonjs"
"preset-env": {
"modules": "commonjs"
}
}
],
"next/babel"
]
]
}
}
......
version: '2'
services:
proxy:
build: ./proxy/
command: npm start
ports:
- "9000:9000"
depends_on:
- webapp
webapp:
build: ./
command: npm run dev
......@@ -7,7 +14,7 @@ services:
- "3000:3000"
environment:
NODE_ENV: development
PORTIER_REDIRECT_BASE_URL: http://localhost:3000
PORTIER_REDIRECT_BASE_URL: http://localhost:9000/
SESSION_SECRET: oukauyevUAEOWBVkjshvdvsdubvaWOBEkasudpbvwqzmxnc
volumes:
- .:/usr/src/app
......
......@@ -7,10 +7,10 @@
],
"coverageThreshold": {
"global": {
"statements": 96,
"branches": 91,
"functions": 97,
"lines": 96
"statements": 99,
"branches": 97,
"functions": 100,
"lines": 99
}
},
"coverageDirectory": "coverage",
......
This diff is collapsed.
......@@ -3,22 +3,23 @@
"version": "1.0.0",
"private": true,
"dependencies": {
"babel-plugin-transform-define": "^1.3.0",
"babel-core": "^7.0.0-bridge.0",
"babel-jest": "^22.4.3",
"body-parser": "^1.18.2",
"connect-redis": "^3.3.3",
"express": "^4.16.3",
"express-graphql": "^0.6.12",
"express-session": "^1.15.6",
"graphql": "^0.12.3",
"graphql": "^0.13.2",
"jss": "^9.8.1",
"material-ui": "^1.0.0-beta.43",
"material-ui": "^1.0.0-beta.47",
"material-ui-icons": "^1.0.0-beta.36",
"next": "^5.1.0",
"next": "^6.1.1",
"next-redux-wrapper": "^1.3.5",
"next-workbox-webpack-plugin": "^1.1.0",
"portier": "^0.3.2",
"react": "^16.3.1",
"react-dom": "^16.3.1",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-jss": "^8.4.0",
"react-redux": "^5.0.7",
"redux": "^3.7.2",
......@@ -32,7 +33,7 @@
"deep-freeze": "0.0.1",
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"jest": "^21.2.1",
"jest": "^22.4.3",
"react-addons-test-utils": "^15.6.2",
"react-test-renderer": "^16.3.2"
},
......@@ -41,9 +42,10 @@
"localDev": "docker-compose -f docker-compose-local.yml up --build --force-recreate",
"start": "next build && node server.js",
"test": "npm run test:unit && npm run test:build",
"test:unit": "jest --coverage --config ./jest.config.json",
"test:unit": "NODE_ENV=test jest --coverage --config ./jest.config.json",
"test:build": "next build",
"test:unit:watch": "jest --watch --config ./jest.config.json",
"testApi": "curl -XPOST -H \"Content-Type:application/graphql\" -d 'query { movies { title } }' http://localhost:3000/graphql"
"test:unit:watch": "NODE_ENV=test jest --watch --config ./jest.config.json",
"testMoviesApi": "curl -XPOST -H \"Content-Type:application/graphql\" -d 'query { movies { title } }' http://localhost:3000/graphql",
"testMovieCollectionsApi": "curl -XPOST -H \"Content-Type:application/graphql\" -d 'query { movieCollections { name } }' http://localhost:3000/graphql"
}
}
node_modules
FROM node:8.11.1
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
COPY package-lock.json /usr/src/app/
RUN npm install --color=false
COPY . /usr/src/app
EXPOSE 9000
CMD [ "npm", "start" ]
{
"name": "fml-proxy",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"arg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arg/-/arg-1.0.1.tgz",
"integrity": "sha512-yZ7k3hP42f9XI+8s4Sg6nPlHXpqfu5G9ijGZ+7XDF1+9CchByI6Bqs8gB+6bFw0MoSN6WwnfYTLyD3Bv/4W8eA=="
},
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
},
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
"integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
"depd": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
"integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
},
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
"iconv-lite": "0.4.19"
}
},
"http-errors": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
"integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
"requires": {
"depd": "1.1.1",
"inherits": "2.0.3",
"setprototypeof": "1.0.3",
"statuses": "1.4.0"
}
},
"iconv-lite": {
"version": "0.4.19",
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
"integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
},
"inherits": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
"integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"micro": {
"version": "9.1.4",
"resolved": "https://registry.npmjs.org/micro/-/micro-9.1.4.tgz",
"integrity": "sha512-2eQ5QpO33LAPQJ/1iA3BrtLzdYlOCAXlstY4vcIj3SEmv0tsWuNZpsfgn1o8xGAYzf15kb+FXnEx8EklXz+pPg==",
"requires": {
"content-type": "1.0.4",
"is-stream": "1.1.0",
"mri": "1.1.0",
"raw-body": "2.3.2"
}
},
"micro-proxy": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/micro-proxy/-/micro-proxy-1.1.0.tgz",
"integrity": "sha512-pOkBfwxQ9ghn0y8Do6CmVoe4taVp/f+InlGqOqDB2DIwlqtDWf1951qRpqn0udLHzqi+A0DwPovxMfmoRCJWjA==",
"requires": {
"arg": "1.0.1",
"micro": "9.1.4",
"node-fetch": "1.7.3",
"ws": "3.3.3"
}
},
"mri": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/mri/-/mri-1.1.0.tgz",
"integrity": "sha1-XAo/KcjM/7ux7JQdzsCdcfoy82o="
},
"node-fetch": {
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"requires": {
"encoding": "0.1.12",
"is-stream": "1.1.0"
}
},
"raw-body": {
"version": "2.3.2",
"resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
"integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
"requires": {
"bytes": "3.0.0",
"http-errors": "1.6.2",
"iconv-lite": "0.4.19",
"unpipe": "1.0.0"
}
},
"safe-buffer": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
},
"setprototypeof": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
"integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
},
"statuses": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
"integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
},
"ultron": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
"integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
},
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
"integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
},
"ws": {
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
"integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
"requires": {
"async-limiter": "1.0.0",
"safe-buffer": "5.1.1",
"ultron": "1.1.1"
}
}
}
}
{
"name": "fml-proxy",
"version": "1.0.0",
"private": true,
"dependencies": {
"micro-proxy": "^1.1.0"
},
"scripts": {
"start": "micro-proxy -r rules.json"
}
}
{
"rules": [
{
"pathname": "/graphql",
"method": [
"POST"
],
"dest": "http://graphql:5000"
},
{
"pathname": "/**",
"dest": "http://webapp:3000"
}
]
}
......@@ -4,7 +4,7 @@ const formParser = require('body-parser').urlencoded({ extended: false });
const PortierClient = require('portier');
const graphql = require('graphql').graphql
const graphQLHTTP = require('express-graphql')
const Schema = require('./src/graphql/types/schema')
const Schema = require('./src/graphql/schema')
const next = require('next')
const redirectBaseUrl = process.env.PORTIER_REDIRECT_BASE_URL || "http://localhost:3000";
......@@ -65,11 +65,9 @@ app.prepare()
const root = process.cwd()
server.get("/sw*", (req, res) => {
console.log("someone asked for /sw*: ", req.url);
return app.serveStatic(req, res, join(root, `./static/workbox/${req.url}`))
})
server.get("/static/workbox/*", (req, res) => {
console.log("someone asked for /static/workbox/*: ", req.url);
app.serveStatic(req, res, join(root, `.${req.url}`))
})
......
......@@ -3,21 +3,8 @@ const {
GraphQLList
} = require('graphql')
const MovieType = require('./movieType')
const MOVIES = [{
id: '1381220',
title: 'Best Exotic Marigold Hotel 2 (2015)'
}, {
id: '2133893742',
title: 'Riddick - Überleben ist seine Rache (2013)'
}, {
id: '2144846395',
title: 'Hostage - Entführt'
}, {
id: '2043226252',
title: 'Baymax - Riesiges Robowabohu (2014)'
}]
const { MovieType, MOVIES } = require('./types/movieType')
const { MovieCollectionType, MOVIECOLLECTIONS } = require('./types/movieCollection')
module.exports = new GraphQLObjectType({
name: 'Query',
......@@ -28,6 +15,12 @@ module.exports = new GraphQLObjectType({
resolve: () => {
return MOVIES;
}
},
movieCollections: {
type: new GraphQLList(MovieCollectionType),
resolve: () => {
return MOVIECOLLECTIONS;
}
}
}
}
......
const {
GraphQLObjectType,
GraphQLString,
GraphQLID,
GraphQLBoolean,
GraphQLList
} = require('graphql')
const { MovieType, MOVIES } = require('./movieType')
module.exports = {MovieCollectionType: new GraphQLObjectType({
name: 'movieCollection',
fields: () => {
return {
id: {
type: GraphQLID
},
name: {
type: GraphQLString
},
isLoading: {
type: GraphQLBoolean
},
sort: {
type: GraphQLString
},
movies: {
type: new GraphQLList(MovieType)
}
}
}
}),
MOVIECOLLECTIONS: [{
id: '673655561',
name: 'Hugo Blurays',
isLoading: false,
sort: "title",
movies: MOVIES
}]
};
......@@ -4,7 +4,7 @@ const {
GraphQLID
} = require('graphql')
module.exports = new GraphQLObjectType({
module.exports = { MovieType: new GraphQLObjectType({
name: 'movie',
fields: () => {
return {
......@@ -16,4 +16,18 @@ module.exports = new GraphQLObjectType({
}
}
}
});
}),
MOVIES: [{
id: '1381220',
title: 'Best Exotic Marigold Hotel 2 (2015)'
}, {
id: '2133893742',
title: 'Riddick - Überleben ist seine Rache (2013)'
}, {
id: '2144846395',
title: 'Hostage - Entführt'
}, {
id: '2043226252',
title: 'Baymax - Riesiges Robowabohu (2014)'
}]};
......@@ -16,13 +16,13 @@ export const addMovieCollectionWithMoviesLineByLine = movieCollection => {
export const createMovieCollectionByFile = (movieCollection, worker) => {
const workerConstructor = worker || Worker;
return (dispatch) => {
return (dispatch, workerObject) => {
dispatch(addMovieCollectionByFileStart(movieCollection));
// start WebWorker and Dispatch updateMovieCollectionByFileFinished if returns with result
const worker = new workerConstructor("/static/minifiedWorker/parseVideoDbXml.js");
const worker = workerObject || new workerConstructor("/static/minifiedWorker/parseVideoDbXml.js");
worker.postMessage(movieCollection.file);
worker.onmessage = (e) => {
if(e.data.event && e.data.event === "finished") {
if(e.data && e.data.event && e.data.event === "finished") {
dispatch(addMovieCollectionByFileFinished({
name: movieCollection.name,
}));
......
......@@ -13,7 +13,10 @@ export default class MovieCollectionItem extends React.Component {
}
rate(evt) {
this.dispatch(RateProcessActions.startEmptyProcess(this.props.id));
this.dispatch(RateProcessActions.startEmptyProcess({
id: this.props.id,
personalMovieListLength: this.props.rate.personalMovieList.length
}));
this.router.push('/rate?id='+this.props.id);
}
......
export default (movieCollections = {}) => {
return Object.keys(movieCollections)[0];
};
import hashCode from '../../hashCode';
export const START_EMPTY_PROCESS = 'START_EMPTY_PROCESS';
export const startEmptyProcess = (id) => {
export const startEmptyProcess = (payload) => {
return {
type: START_EMPTY_PROCESS,
id: id
id: payload.id,
payload
};
};
......
import React from 'react'
import * as UnseenMovieListActions from '../../unseenMovieList/actions';
import MovieChooseForm from './MovieChooseForm';
import getUnratedAndSeenMovieFromCollection from '../lib/getUnratedAndSeenMovieFromCollection'
......@@ -8,6 +9,7 @@ export default class MovieChoose extends React.Component {
super(props)
this.dispatch = props.dispatch
this.start = this.start.bind(this);
this.neverSeenIt = this.neverSeenIt.bind(this);
}
start(event) {
......@@ -17,12 +19,19 @@ export default class MovieChoose extends React.Component {
})
}
neverSeenIt(event) {
this.dispatch(UnseenMovieListActions.addMovieToUnseenMovieList(this.movie.movieId));
}
render() {
const collectionId = this.props.collectionId
this.movieCollection = this.props.movieCollections[collectionId]
this.movie = getUnratedAndSeenMovieFromCollection(this.movieCollection, this.props.rate.personalMovieList)
this.movie = getUnratedAndSeenMovieFromCollection(this.movieCollection,
this.props.rate.personalMovieList, this.props.rate.unseenMovieList)
return (
<MovieChooseForm onStart={this.start}
onNeverSeenIt={this.neverSeenIt}
movie={this.movie} />
)
}
......
......@@ -4,7 +4,6 @@ export default ({ onStart, onNeverSeenIt, movie }) => (
<div>
<Movie {...movie} />
<button type="button"
disabled="true"
onClick={onNeverSeenIt}
>
Never Seen It
......
......@@ -32,7 +32,14 @@ export default class MovieCompareFinish extends React.Component {
}
startEmptyProcess() {
this.dispatch(Actions.startEmptyProcess(this.props.collectionId));
// Horrible hack:
// for an unknown reason the personalMovieList property is not yet updated with the just finished comparison process
// hence we need to increase it by one, because we know we just called finishComparisonProcess befor :(
const newPersonalMovieListLength = this.props.rate.personalMovieList.length + 1;
this.dispatch(Actions.startEmptyProcess({
id: this.props.collectionId,
personalMovieListLength: newPersonalMovieListLength
}));
}
render() {
......
import React from 'react'
import { withStyles } from 'material-ui/styles';
import MobileStepper from 'material-ui/MobileStepper';
export default class Stepper extends React.Component {
render() {
const {steps, activeStep} = this.props;
return (
<MobileStepper
variant="dots"
steps={steps}
activeStep={activeStep}
position="static"
/>
)
}
}
\ No newline at end of file
......@@ -9,7 +9,7 @@ export default(movieCollection = {movies:{}}, ratedMovies = [], unseenMovies = [
return sortOut(movieCollection, unratedMovie(ratedMovies), seenMovie(unseenMovies));
}
function sortOut(movieCollection = {movies:{}}, firstChecker, ...checkers) {
function sortOut(movieCollection, firstChecker, ...checkers) {
const movieIds = Object.keys(movieCollection.movies)
let survivedMovieIds = movieIds.filter(firstChecker);
checkers.forEach((checker) => {
......
......@@ -10,6 +10,7 @@ export default ({ onSeen, onUnseen, movie }) => (
Never Seen It
</button>
<button type="button"
disabled="true"
onClick={onUnseen}
>
Found It
......
import { expect as chaiExpect } from 'chai'
import * as Actions from '../../src/movieCollections/actions'
describe('movieCollections actions', () => {
describe('createMovieCollectionByFile', () => {
const defaultMovieCollection = {
name: 'Hugo Blurays',
file: "<xml></xml>"
};
const NOP = () => { };
const defaultWorkerMock = {
postMessage: NOP
}
const defaultWorkerConstructor = () => {
return defaultWorkerMock;
}
function getWorkerMockObject() {
return Object.assign({}, defaultWorkerMock);
}
it('should dispatch add movie collection by file start', () => {
const mockDispatch = jest.fn();
Actions.createMovieCollectionByFile(defaultMovieCollection, defaultWorkerConstructor)(mockDispatch);
expect(mockDispatch).toHaveBeenCalledWith(Actions.addMovieCollectionByFileStart(defaultMovieCollection));
})
it('should instantiate worker with file path', () => {
const workerMock = (filePath) => {
chaiExpect(filePath).to.be.a('string');
chaiExpect(filePath).to.have.length.above(2);
return {
postMessage: NOP
}
}
Actions.createMovieCollectionByFile(defaultMovieCollection, workerMock)(NOP);
})
it('should post file content as message', () => {
const mockPostMessage = jest.fn();
const workerMock = (filePath) => {
return {
postMessage: mockPostMessage
}
}
Actions.createMovieCollectionByFile(defaultMovieCollection, workerMock)(NOP);
expect(mockPostMessage).toHaveBeenCalledWith(defaultMovieCollection.file);
})
it('should set onmessage on worker to receive updates', () => {
const workerObject = getWorkerMockObject();
Actions.createMovieCollectionByFile(defaultMovieCollection, defaultWorkerConstructor)(NOP, workerObject);
chaiExpect(workerObject).to.have.own.property('onmessage');
})
it('should dispatch update event if onmessage is called with data', () => {
const mockDispatch = jest.fn();
const workerObject = getWorkerMockObject();
const movieName = "Matrix";
Actions.createMovieCollectionByFile(defaultMovieCollection, defaultWorkerConstructor)(mockDispatch, workerObject);
workerObject.onmessage({
data: movieName
});
expect(mockDispatch).toHaveBeenCalledWith(Actions.updateMovieCollectionByFile({
name: defaultMovieCollection.name,
movies: [movieName]
}));
})
it('should dispatch finished event if onmessage is called with finish', () => {
const mockDispatch = jest.fn();
const workerObject = getWorkerMockObject();
const movieName = "Matrix";
Actions.createMovieCollectionByFile(defaultMovieCollection, defaultWorkerConstructor)(mockDispatch, workerObject);
workerObject.onmessage({
data: {
event: "finished"
}
});
expect(mockDispatch).toHaveBeenCalledWith(Actions.addMovieCollectionByFileFinished(defaultMovieCollection));
})
});
})
......@@ -11,6 +11,9 @@ describe("MovieCollectionItem", () => {
dispatch: jest.fn(),
router: {
push: jest.fn()
},
rate: {
personalMovieList: []
}
}
it('should redirect if rate button is clicked', () => {
......
import getFirstMovieCollectionId from '../../../src/movieCollections/lib/getFirstMovieCollectionId'
describe("getFirstMovieCollectionId", () => {
it('should return id of first movieCollection', () => {
const movieCollectionId = '673655561';
const movieCollections = {
[movieCollectionId]: {
name:'Hugo Blurays'
}
};
expect(getFirstMovieCollectionId(movieCollections)).toEqual(movieCollectionId);
});
it('should return undefined if given no movieCollections', () => {
expect(getFirstMovieCollectionId()).toEqual(undefined);
});
});
......@@ -2,6 +2,7 @@ import { expect as chaiExpect } from 'chai'
import { mount } from 'enzyme'
import MovieChoose from '../../../../src/rate/process/components/MovieChoose'
import { ADD_MOVIE_TO_UNSEEN_MOVIE_LIST } from '../../../../src/rate/unseenMovieList/actions'
describe('MovieChoose', () => {
const minimumRequiredProps = {
......@@ -13,9 +14,7 @@ describe('MovieChoose', () => {
}
}
},
rate: {
personalMovieList: []
}
rate: {}
}
it('should call onStart callback if start button is clicked', () => {
const props = Object.assign({
......@@ -28,6 +27,23 @@ describe('MovieChoose', () => {
expect(props.onStart).toHaveBeenCalledTimes(1);
})
it('should call dispatch if neverSeenIt button is clicked', () => {
const props = Object.assign({
dispatch: jest.fn()
}, minimumRequiredProps);
const wrapper = mount(<MovieChoose {...props} />);
const neverSeenItButton = wrapper.find('button').at(0);
neverSeenItButton.simulate('click');
expect(props.dispatch).toHaveBeenCalledTimes(1);
expect(props.dispatch).toHaveBeenCalledWith({
type: ADD_MOVIE_TO_UNSEEN_MOVIE_LIST,
payload: {
movieId: '1'
}
});
})
it('should render unrated movie', () => {
const props = Object.assign(minimumRequiredProps, {
onStart: jest.fn(),
......@@ -48,4 +64,27 @@ describe('MovieChoose', () => {
chaiExpect(wrapper.text()).to.not.include('abc');
chaiExpect(wrapper.text()).to.include('xyz');
})
it('should render unrated and seen movie', () => {
const props = Object.assign(minimumRequiredProps, {
onStart: jest.fn(),
movieCollections: {
'12': {
movies: {
'1': { title: 'abc' },
'2': { title: 'xyz' },
'3': { title: 'def' }
}
}
},
rate: {
personalMovieList: ['1'],
unseenMovieList: ['2']
}
});
const wrapper = mount(<MovieChoose {...props} />);
chaiExpect(wrapper.text()).to.not.include('abc');
chaiExpect(wrapper.text()).to.not.include('xyz');
chaiExpect(wrapper.text()).to.include('def');
})
})
\ No newline at end of file
......@@ -13,7 +13,8 @@ describe("MovieCompareFinish", () => {
movieFromCollection: '11',
result: 0
}
}
},
personalMovieList: []
},
movieCollections: {
'42': {
......
import React from 'react'
import { expect } from 'chai'
import { mount } from 'enzyme'
import Stepper from '../../../../src/rate/process/components/Stepper'
describe('Stepper', () => {
const props = {
steps: 6,
activeStep: 0
}
it('should render amount of given steps', () => {
const wrapper = mount(<Stepper {...props}/>);
expect(wrapper.find(`.MuiMobileStepper-dot-${props.steps}`)).to.have.length(props.steps);
});
});
......@@ -19,7 +19,10 @@ describe('process reducer', () => {
it('should start an empty comparison process', {
stateBefore: {},
action: Actions.startEmptyProcess('673655561'),
action: Actions.startEmptyProcess({
id: '673655561',
personalMovieListLength: 0
}),
stateAfter: {
'673655561': {
finished: false
......
......@@ -4,7 +4,7 @@ import { shallow } from 'enzyme'
import FindSeenMovieForm from '../../../../src/rate/unseenMovieList/components/FindSeenMovieForm.js'
describe('FindSeenMovieForm', () => {
const subComponent = "< />"
const subComponent = "<_default />"
it('should render a sub-component and two buttons', () => {
const wrapper = shallow(<FindSeenMovieForm />);
expect(wrapper.text()).toContain(subComponent);
......