diff --git a/front/package.json b/front/package.json index e79ffcbebab4b40238fa5aa98eae3097b1b13b1f..2818757a3ff86411842020921c08c732ad25c47b 100644 --- a/front/package.json +++ b/front/package.json @@ -9,6 +9,7 @@ "start": "node build/dev-server.js", "build": "node build/build.js", "unit": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js --single-run", + "unit-watch": "cross-env BABEL_ENV=test karma start test/unit/karma.conf.js", "e2e": "node test/e2e/runner.js", "test": "npm run unit && npm run e2e", "lint": "eslint --ext .js,.vue src test/unit/specs test/e2e/specs" diff --git a/front/src/store/auth.js b/front/src/store/auth.js index d8bd197f33fabd1938fe65a5c71ca950314b663f..6021f30fa9c0d919e9a112ec02c8ca62f5025b1d 100644 --- a/front/src/store/auth.js +++ b/front/src/store/auth.js @@ -44,6 +44,7 @@ export default { state.token = value if (value) { state.tokenData = jwtDecode(value) + console.log(state.tokenData) } else { state.tokenData = {} } diff --git a/front/src/store/player.js b/front/src/store/player.js index 74b0b9f9ea72dcbc38d0c3cefc6fa90d1647fc49..9e50d6c194b2afa1afeb3c273607cdeed2d227eb 100644 --- a/front/src/store/player.js +++ b/front/src/store/player.js @@ -61,8 +61,8 @@ export default { } }, actions: { - incrementVolume (context, value) { - context.commit('volume', context.state.volume + value) + incrementVolume ({commit, state}, value) { + commit('volume', state.volume + value) }, stop (context) { }, diff --git a/front/test/unit/karma.conf.js b/front/test/unit/karma.conf.js index da5a2187663e2479f48a0c2ccefac20927c0f049..47b46880704756d08b5654c074ad2aa44b91f8b4 100644 --- a/front/test/unit/karma.conf.js +++ b/front/test/unit/karma.conf.js @@ -21,7 +21,7 @@ module.exports = function (config) { preprocessors: { './index.js': ['webpack', 'sourcemap'] }, - captureTimeout: 5000, + captureTimeout: 15000, retryLimit: 1, webpack: webpackConfig, webpackMiddleware: { diff --git a/front/test/unit/specs/store/auth.spec.js b/front/test/unit/specs/store/auth.spec.js index 6ef558f6e0b0a89e252d2e46794221d5730d6299..8be2708f3324b60d533a190dc0d3d53fb665d588 100644 --- a/front/test/unit/specs/store/auth.spec.js +++ b/front/test/unit/specs/store/auth.spec.js @@ -1,52 +1,108 @@ -import store from '@/store/player' +import store from '@/store/auth' -describe('mutations', () => { - it('set volume', () => { - // mock state - const state = { volume: 0 } - // apply mutation - store.mutations.volume(state, 0.9) - // assert result - expect(state.volume).to.equal(0.9) - }) - it('set volume max 1', () => { - // mock state - const state = { volume: 0 } - // apply mutation - store.mutations.volume(state, 2) - // assert result - expect(state.volume).to.equal(1) - }) - it('set volume min to 0', () => { - // mock state - const state = { volume: 0.5 } - // apply mutation - store.mutations.volume(state, -2) - // assert result - expect(state.volume).to.equal(0) - }) - it('increment volume', () => { - // mock state - const state = { volume: 0 } - // apply mutation - store.mutations.incrementVolume(state, 0.1) - // assert result - expect(state.volume).to.equal(0.1) +import { testAction } from '../../utils' + +describe('store/auth', () => { + describe('mutations', () => { + it('profile', () => { + const state = {} + store.mutations.profile(state, {}) + expect(state.profile).to.deep.equal({}) + }) + it('username', () => { + const state = {} + store.mutations.username(state, 'world') + expect(state.username).to.equal('world') + }) + it('authenticated true', () => { + const state = {} + store.mutations.authenticated(state, true) + expect(state.authenticated).to.equal(true) + }) + it('authenticated false', () => { + const state = { + username: 'dummy', + token: 'dummy', + tokenData: 'dummy', + profile: 'dummy', + availablePermissions: 'dummy' + } + store.mutations.authenticated(state, false) + expect(state.authenticated).to.equal(false) + expect(state.username).to.equal(null) + expect(state.token).to.equal(null) + expect(state.tokenData).to.equal(null) + expect(state.profile).to.equal(null) + expect(state.availablePermissions).to.deep.equal({}) + }) + it('token null', () => { + const state = {} + store.mutations.token(state, null) + expect(state.token).to.equal(null) + expect(state.tokenData).to.deep.equal({}) + }) + it('token real', () => { + // generated on http://kjur.github.io/jsjws/tool_jwt.html + const state = {} + let token = 'eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJpc3MiOiJodHRwczovL2p3dC1pZHAuZXhhbXBsZS5jb20iLCJzdWIiOiJtYWlsdG86bWlrZUBleGFtcGxlLmNvbSIsIm5iZiI6MTUxNTUzMzQyOSwiZXhwIjoxNTE1NTM3MDI5LCJpYXQiOjE1MTU1MzM0MjksImp0aSI6ImlkMTIzNDU2IiwidHlwIjoiaHR0cHM6Ly9leGFtcGxlLmNvbS9yZWdpc3RlciJ9.' + let tokenData = { + iss: 'https://jwt-idp.example.com', + sub: 'mailto:mike@example.com', + nbf: 1515533429, + exp: 1515537029, + iat: 1515533429, + jti: 'id123456', + typ: 'https://example.com/register' + } + store.mutations.token(state, token) + expect(state.token).to.equal(token) + expect(state.tokenData).to.deep.equal(tokenData) + }) + it('permissions', () => { + const state = { availablePermissions: {} } + store.mutations.permission(state, {key: 'admin', status: true}) + expect(state.availablePermissions).to.deep.equal({admin: true}) + }) }) - it('increment volume max 1', () => { - // mock state - const state = { volume: 0 } - // apply mutation - store.mutations.incrementVolume(state, 2) - // assert result - expect(state.volume).to.equal(1) + describe('getters', () => { + it('header', () => { + const state = { token: 'helloworld' } + expect(store.getters['header'](state)).to.equal('JWT helloworld') + }) }) - it('increment volume min to 0', () => { - // mock state - const state = { volume: 0.5 } - // apply mutation - store.mutations.incrementVolume(state, -2) - // assert result - expect(state.volume).to.equal(0) + describe('actions', () => { + it('logout', (done) => { + testAction({ + action: store.actions.logout, + params: {state: {}}, + expectedMutations: [ + { type: 'authenticated', payload: false } + ] + }, done) + }) + it('check jwt null', (done) => { + testAction({ + action: store.actions.check, + params: {state: {}}, + expectedMutations: [ + { type: 'authenticated', payload: false } + ] + }, done) + }) + it('check jwt set', (done) => { + testAction({ + action: store.actions.check, + params: {state: {token: 'test', username: 'user'}}, + expectedMutations: [ + { type: 'authenticated', payload: true }, + { type: 'username', payload: 'user' }, + { type: 'token', payload: 'test' } + ], + expectedActions: [ + { type: 'fetchProfile' }, + { type: 'refreshToken' } + ] + }, done) + }) }) }) diff --git a/front/test/unit/specs/store/favorites.spec.js b/front/test/unit/specs/store/favorites.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..6d4314ca661a2ffbb3865d3a4edc53a2b40b1cc8 --- /dev/null +++ b/front/test/unit/specs/store/favorites.spec.js @@ -0,0 +1,52 @@ +import store from '@/store/favorites' + +import { testAction } from '../../utils' + +describe('store/favorites', () => { + describe('mutations', () => { + it('track true', () => { + const state = { tracks: [] } + store.mutations.track(state, {id: 1, value: true}) + expect(state.tracks).to.deep.equal([1]) + expect(state.count).to.deep.equal(1) + }) + it('track false', () => { + const state = { tracks: [1] } + store.mutations.track(state, {id: 1, value: false}) + expect(state.tracks).to.deep.equal([]) + expect(state.count).to.deep.equal(0) + }) + }) + describe('getters', () => { + it('isFavorite true', () => { + const state = { tracks: [1] } + expect(store.getters['isFavorite'](state)(1)).to.equal(true) + }) + it('isFavorite false', () => { + const state = { tracks: [] } + expect(store.getters['isFavorite'](state)(1)).to.equal(false) + }) + }) + describe('actions', () => { + it('toggle true', (done) => { + testAction({ + action: store.actions.toggle, + payload: 1, + params: {getters: {isFavorite: () => false}}, + expectedActions: [ + { type: 'set', payload: {id: 1, value: true} } + ] + }, done) + }) + it('toggle true', (done) => { + testAction({ + action: store.actions.toggle, + payload: 1, + params: {getters: {isFavorite: () => true}}, + expectedActions: [ + { type: 'set', payload: {id: 1, value: false} } + ] + }, done) + }) + }) +}) diff --git a/front/test/unit/specs/store/player.spec.js b/front/test/unit/specs/store/player.spec.js new file mode 100644 index 0000000000000000000000000000000000000000..af0b6b4354394dbc9c1c62186796e62653ca52fb --- /dev/null +++ b/front/test/unit/specs/store/player.spec.js @@ -0,0 +1,153 @@ +import store from '@/store/player' + +import { testAction } from '../../utils' + +describe('store/player', () => { + describe('mutations', () => { + it('set volume', () => { + const state = { volume: 0 } + store.mutations.volume(state, 0.9) + expect(state.volume).to.equal(0.9) + }) + it('set volume max 1', () => { + const state = { volume: 0 } + store.mutations.volume(state, 2) + expect(state.volume).to.equal(1) + }) + it('set volume min to 0', () => { + const state = { volume: 0.5 } + store.mutations.volume(state, -2) + expect(state.volume).to.equal(0) + }) + it('increment volume', () => { + const state = { volume: 0 } + store.mutations.incrementVolume(state, 0.1) + expect(state.volume).to.equal(0.1) + }) + it('increment volume max 1', () => { + const state = { volume: 0 } + store.mutations.incrementVolume(state, 2) + expect(state.volume).to.equal(1) + }) + it('increment volume min to 0', () => { + const state = { volume: 0.5 } + store.mutations.incrementVolume(state, -2) + expect(state.volume).to.equal(0) + }) + it('set duration', () => { + const state = { duration: 42 } + store.mutations.duration(state, 14) + expect(state.duration).to.equal(14) + }) + it('set errored', () => { + const state = { errored: false } + store.mutations.errored(state, true) + expect(state.errored).to.equal(true) + }) + it('set looping', () => { + const state = { looping: 1 } + store.mutations.looping(state, 2) + expect(state.looping).to.equal(2) + }) + it('set playing', () => { + const state = { playing: false } + store.mutations.playing(state, true) + expect(state.playing).to.equal(true) + }) + it('set current time', () => { + const state = { currentTime: 1 } + store.mutations.currentTime(state, 2) + expect(state.currentTime).to.equal(2) + }) + it('toggle looping from 0', () => { + const state = { looping: 0 } + store.mutations.toggleLooping(state) + expect(state.looping).to.equal(1) + }) + it('toggle looping from 1', () => { + const state = { looping: 1 } + store.mutations.toggleLooping(state) + expect(state.looping).to.equal(2) + }) + it('toggle looping from 2', () => { + const state = { looping: 2 } + store.mutations.toggleLooping(state) + expect(state.looping).to.equal(0) + }) + }) + describe('getters', () => { + it('durationFormatted', () => { + const state = { duration: 12.51 } + expect(store.getters['durationFormatted'](state)).to.equal('00:13') + }) + it('currentTimeFormatted', () => { + const state = { currentTime: 12.51 } + expect(store.getters['currentTimeFormatted'](state)).to.equal('00:13') + }) + it('progress', () => { + const state = { currentTime: 4, duration: 10 } + expect(store.getters['progress'](state)).to.equal(40) + }) + }) + describe('actions', () => { + it('incrementVolume', (done) => { + testAction({ + action: store.actions.incrementVolume, + payload: 0.2, + params: {state: {volume: 0.7}}, + expectedMutations: [ + { type: 'volume', payload: 0.7 + 0.2 } + ] + }, done) + }) + it('toggle play false', (done) => { + testAction({ + action: store.actions.togglePlay, + params: {state: {playing: false}}, + expectedMutations: [ + { type: 'playing', payload: true } + ] + }, done) + }) + it('toggle play true', (done) => { + testAction({ + action: store.actions.togglePlay, + params: {state: {playing: true}}, + expectedMutations: [ + { type: 'playing', payload: false } + ] + }, done) + }) + it('trackEnded', (done) => { + testAction({ + action: store.actions.trackEnded, + payload: {test: 'track'}, + expectedActions: [ + { type: 'trackListened', payload: {test: 'track'} }, + { type: 'queue/next', payload: null, options: {root: true} } + ] + }, done) + }) + it('trackErrored', (done) => { + testAction({ + action: store.actions.trackErrored, + payload: {test: 'track'}, + expectedMutations: [ + { type: 'errored', payload: true } + ], + expectedActions: [ + { type: 'queue/next', payload: null, options: {root: true} } + ] + }, done) + }) + it('updateProgress', (done) => { + testAction({ + action: store.actions.updateProgress, + payload: 1, + expectedMutations: [ + { type: 'currentTime', payload: 1 } + ] + }, done) + }) + }) +}) diff --git a/front/test/unit/utils.js b/front/test/unit/utils.js new file mode 100644 index 0000000000000000000000000000000000000000..e67c7687f9ecd65024e513853a57cbbc2d5c1a8e --- /dev/null +++ b/front/test/unit/utils.js @@ -0,0 +1,68 @@ +// helper for testing action with expected mutations +export const testAction = ({action, payload, params, expectedMutations, expectedActions}, done) => { + let mutationsCount = 0 + let actionsCount = 0 + + if (!expectedMutations) { + expectedMutations = [] + } + if (!expectedActions) { + expectedActions = [] + } + const isOver = () => { + return mutationsCount >= expectedMutations.length && actionsCount >= expectedActions.length + } + // mock commit + const commit = (type, payload) => { + const mutation = expectedMutations[mutationsCount] + + try { + expect(mutation.type).to.equal(type) + if (payload) { + expect(mutation.payload).to.deep.equal(payload) + } + } catch (error) { + done(error) + } + + mutationsCount++ + if (isOver()) { + done() + } + } + // mock dispatch + const dispatch = (type, payload, options) => { + const a = expectedActions[actionsCount] + + try { + expect(a.type).to.equal(type) + if (payload) { + expect(a.payload).to.deep.equal(payload) + } + if (a.options) { + expect(options).to.deep.equal(a.options) + } + } catch (error) { + done(error) + } + + actionsCount++ + if (isOver()) { + done() + } + } + + // call the action with mocked store and arguments + action({ commit, dispatch, ...params }, payload) + + // check if no mutations should have been dispatched + if (expectedMutations.length === 0) { + expect(mutationsCount).to.equal(0) + } + if (expectedActions.length === 0) { + expect(actionsCount).to.equal(0) + } + if (isOver()) { + done() + } +}