Verified Commit a8a60915 authored by Agate's avatar Agate 💬

Fixed broken unit tests due to front-end cleanup

parent e3040de4
......@@ -81,8 +81,8 @@ front/dist/
front/npm-debug.log*
front/yarn-debug.log*
front/yarn-error.log*
front/test/unit/coverage
front/test/e2e/reports
front/tests/unit/coverage
front/tests/e2e/reports
front/selenium-debug.log
docs/_build
......
......@@ -156,7 +156,6 @@ test_api:
tags:
- docker
test_front:
stage: test
image: node:9
......@@ -166,7 +165,7 @@ test_front:
- branches
script:
- yarn install
- yarn run unit
- yarn test:unit
cache:
key: "funkwhale__front_dependencies"
paths:
......@@ -179,7 +178,6 @@ test_front:
tags:
- docker
build_front:
stage: build
image: node:9
......@@ -192,7 +190,7 @@ build_front:
- yarn run i18n-compile
# this is to ensure we don't have any errors in the output,
# cf https://code.eliotberriot.com/funkwhale/funkwhale/issues/169
- yarn run build | tee /dev/stderr | (! grep -i 'ERROR in')
- yarn build | tee /dev/stderr | (! grep -i 'ERROR in')
- chmod -R 750 dist
cache:
key: "funkwhale__front_dependencies"
......@@ -210,7 +208,6 @@ build_front:
tags:
- docker
pages:
stage: test
image: python:3.6
......
......@@ -466,12 +466,12 @@ Running tests
To run the front-end test suite, use the following command::
docker-compose -f dev.yml run --rm front yarn run unit
docker-compose -f dev.yml run --rm front yarn test:unit
We also support a "watch and test" mode were we continually relaunch
tests when changes are recorded on the file system::
docker-compose -f dev.yml run --rm front yarn run unit-watch
docker-compose -f dev.yml run --rm front yarn test:unit -w
The latter is especially useful when you are debugging failing tests.
......
{
"name": "front",
"private": true,
"version": "0.1.0",
"description": "Funkwhale front-end",
"author": "Eliot Berriot <contact@eliotberriot.com>",
"private": true,
"scripts": {
"serve": "scripts/i18n-compile.sh && vue-cli-service serve --port ${VUE_PORT:-8000} --host ${VUE_HOST:-0.0.0.0}",
"build": "scripts/i18n-compile.sh && vue-cli-service build",
"lint": "vue-cli-service lint",
"i18n-extract": "scripts/i18n-extract.sh",
"i18n-compile": "scripts/i18n-compile.sh",
"test": "npm run unit && npm run e2e",
"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",
"lint": "vue-cli-service lint"
"test:unit": "vue-cli-service test:unit"
},
"dependencies": {
"axios": "^0.18.0",
......@@ -41,11 +37,17 @@
"devDependencies": {
"@vue/cli-plugin-babel": "^3.0.0",
"@vue/cli-plugin-eslint": "^3.0.0",
"@vue/cli-plugin-unit-mocha": "^3.0.0",
"@vue/cli-service": "^3.0.0",
"@vue/test-utils": "^1.0.0-beta.20",
"chai": "^4.1.2",
"easygettext": "^2.6.3",
"eslint-plugin-html": "^4.0.5",
"mocha": "^5.2.0",
"moxios": "^0.4.0",
"node-sass": "^4.9.3",
"sass-loader": "^7.1.0",
"sinon": "^6.1.5",
"vue-template-compiler": "^2.5.17"
},
"eslintConfig": {
......@@ -84,5 +86,7 @@
"> 1%",
"last 2 versions",
"not ie <= 8"
]
],
"author": "Eliot Berriot <contact@eliotberriot.com>",
"description": "Funkwhale front-end"
}
// A custom Nightwatch assertion.
// the name of the method is the filename.
// can be used in tests like this:
//
// browser.assert.elementCount(selector, count)
//
// for how to write custom assertions see
// http://nightwatchjs.org/guide#writing-custom-assertions
exports.assertion = function (selector, count) {
this.message = 'Testing if element <' + selector + '> has count: ' + count
this.expected = count
this.pass = function (val) {
return val === this.expected
}
this.value = function (res) {
return res.value
}
this.command = function (cb) {
var self = this
return this.api.execute(function (selector) {
return document.querySelectorAll(selector).length
}, [selector], function (res) {
cb.call(self, res)
})
}
}
require('babel-register')
var config = require('../../config')
// http://nightwatchjs.org/gettingstarted#settings-file
module.exports = {
src_folders: ['test/e2e/specs'],
output_folder: 'test/e2e/reports',
custom_assertions_path: ['test/e2e/custom-assertions'],
selenium: {
start_process: true,
server_path: require('selenium-server').path,
host: '127.0.0.1',
port: 4444,
cli_args: {
'webdriver.chrome.driver': require('chromedriver').path
}
},
test_settings: {
default: {
selenium_port: 4444,
selenium_host: 'localhost',
silent: true,
globals: {
devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
}
},
chrome: {
desiredCapabilities: {
browserName: 'chrome',
javascriptEnabled: true,
acceptSslCerts: true
}
},
firefox: {
desiredCapabilities: {
browserName: 'firefox',
javascriptEnabled: true,
acceptSslCerts: true
}
}
}
}
// 1. start the dev server using production config
process.env.NODE_ENV = 'testing'
var server = require('../../build/dev-server.js')
server.ready.then(() => {
// 2. run the nightwatch test suite against it
// to run in additional browsers:
// 1. add an entry in test/e2e/nightwatch.conf.json under "test_settings"
// 2. add it to the --env flag below
// or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
// For more information on Nightwatch's config file, see
// http://nightwatchjs.org/guide#settings-file
var opts = process.argv.slice(2)
if (opts.indexOf('--config') === -1) {
opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
}
if (opts.indexOf('--env') === -1) {
opts = opts.concat(['--env', 'chrome'])
}
var spawn = require('cross-spawn')
var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
runner.on('exit', function (code) {
server.close()
process.exit(code)
})
runner.on('error', function (err) {
server.close()
throw err
})
})
// For authoring Nightwatch tests, see
// http://nightwatchjs.org/guide#usage
module.exports = {
'default e2e tests': function (browser) {
// automatically uses dev Server port from /config.index.js
// default: http://localhost:8080
// see nightwatch.conf.js
const devServer = browser.globals.devServerURL
browser
.url(devServer)
.waitForElementVisible('#app', 5000)
.assert.elementPresent('.hello')
.assert.containsText('h1', 'Welcome to Your Vue.js App')
.assert.elementCount('img', 1)
.end()
}
}
import Vue from 'vue'
Vue.config.productionTip = false
// require all test files (files that ends with .spec.js)
const testsContext = require.context('./specs', true, /\.spec$/)
testsContext.keys().forEach(testsContext)
// require all src files except main.js for coverage.
// you can also change this to match only the subset of files that
// you want coverage for.
const srcContext = require.context('../../src', true, /^\.\/(?!main(\.js)?$)/)
srcContext.keys().forEach(srcContext)
// This is a karma config file. For more details see
// http://karma-runner.github.io/0.13/config/configuration-file.html
// we are also using it with karma-webpack
// https://github.com/webpack/karma-webpack
var webpackConfig = require('../../build/webpack.test.conf')
module.exports = function (config) {
config.set({
// to run in additional browsers:
// 1. install corresponding karma launcher
// http://karma-runner.github.io/0.13/config/browsers.html
// 2. add it to the `browsers` array below.
browsers: ['PhantomJS'],
frameworks: ['mocha', 'sinon-stub-promise', 'sinon-chai', 'phantomjs-shim'],
reporters: ['spec', 'coverage'],
files: [
'../../node_modules/es6-promise/dist/es6-promise.auto.js',
'./index.js'
],
preprocessors: {
'./index.js': ['webpack', 'sourcemap']
},
captureTimeout: 15000,
retryLimit: 1,
webpack: webpackConfig,
webpackMiddleware: {
noInfo: true
},
coverageReporter: {
dir: './coverage',
reporters: [
{ type: 'lcov', subdir: '.' },
{ type: 'text-summary' }
]
}
})
}
import {expect} from 'chai'
import Username from '@/components/common/Username.vue'
import { render } from '../../utils'
......
import {expect} from 'chai'
import {truncate, markdown, ago, capitalize, year} from '@/filters'
describe('filters', () => {
......
var sinon = require('sinon')
import {expect} from 'chai'
import moxios from 'moxios'
import store from '@/store/auth'
......@@ -8,7 +10,7 @@ describe('store/auth', () => {
var sandbox
beforeEach(function () {
sandbox = sinon.sandbox.create()
sandbox = sinon.createSandbox()
moxios.install()
})
afterEach(function () {
......@@ -84,7 +86,7 @@ describe('store/auth', () => {
})
})
describe('actions', () => {
it('logout', (done) => {
it('logout', () => {
testAction({
action: store.actions.logout,
params: {state: {}},
......@@ -96,18 +98,18 @@ describe('store/auth', () => {
{ type: 'queue/reset', payload: null, options: {root: true} },
{ type: 'radios/reset', payload: null, options: {root: true} }
]
}, done)
})
})
it('check jwt null', (done) => {
it('check jwt null', () => {
testAction({
action: store.actions.check,
params: {state: {}},
expectedMutations: [
{ type: 'authenticated', payload: false }
]
}, done)
})
})
it('check jwt set', (done) => {
it('check jwt set', () => {
testAction({
action: store.actions.check,
params: {state: {token: 'test', username: 'user'}},
......@@ -118,9 +120,9 @@ describe('store/auth', () => {
{ type: 'fetchProfile' },
{ type: 'refreshToken' }
]
}, done)
})
})
it('login success', (done) => {
it('login success', () => {
moxios.stubRequest('token/', {
status: 200,
response: {
......@@ -139,9 +141,9 @@ describe('store/auth', () => {
expectedActions: [
{ type: 'fetchProfile' }
]
}, done)
})
})
it('login error', (done) => {
it('login error', () => {
moxios.stubRequest('token/', {
status: 500,
response: {
......@@ -160,7 +162,7 @@ describe('store/auth', () => {
done()
})
})
it('fetchProfile', (done) => {
it('fetchProfile', () => {
const profile = {
username: 'bob',
permissions: {
......@@ -183,9 +185,9 @@ describe('store/auth', () => {
{ type: 'favorites/fetch', payload: null, options: {root: true} },
{ type: 'playlists/fetchOwn', payload: null, options: {root: true} }
]
}, done)
})
})
it('refreshToken', (done) => {
it('refreshToken', () => {
moxios.stubRequest('token/refresh/', {
status: 200,
response: {token: 'newtoken'}
......@@ -196,7 +198,7 @@ describe('store/auth', () => {
expectedMutations: [
{ type: 'token', payload: 'newtoken' }
]
}, done)
})
})
})
})
import {expect} from 'chai'
import store from '@/store/favorites'
import { testAction } from '../../utils'
......@@ -28,7 +30,7 @@ describe('store/favorites', () => {
})
})
describe('actions', () => {
it('toggle true', (done) => {
it('toggle true', () => {
testAction({
action: store.actions.toggle,
payload: 1,
......@@ -36,9 +38,9 @@ describe('store/favorites', () => {
expectedActions: [
{ type: 'set', payload: {id: 1, value: true} }
]
}, done)
})
})
it('toggle true', (done) => {
it('toggle true', () => {
testAction({
action: store.actions.toggle,
payload: 1,
......@@ -46,7 +48,7 @@ describe('store/favorites', () => {
expectedActions: [
{ type: 'set', payload: {id: 1, value: false} }
]
}, done)
})
})
})
})
import {expect} from 'chai'
var sinon = require('sinon')
import moxios from 'moxios'
import store from '@/store/instance'
......@@ -7,7 +8,7 @@ describe('store/instance', () => {
var sandbox
beforeEach(function () {
sandbox = sinon.sandbox.create()
sandbox = sinon.createSandbox()
moxios.install()
})
afterEach(function () {
......@@ -26,7 +27,7 @@ describe('store/instance', () => {
})
})
describe('actions', () => {
it('fetchSettings', (done) => {
it('fetchSettings', () => {
moxios.stubRequest('instance/settings/', {
status: 200,
response: [
......@@ -64,7 +65,7 @@ describe('store/instance', () => {
}
}
]
}, done)
})
})
})
})
import {expect} from 'chai'
import store from '@/store/player'
import { testAction } from '../../utils'
......@@ -100,7 +102,7 @@ describe('store/player', () => {
})
})
describe('actions', () => {
it('incrementVolume', (done) => {
it('incrementVolume', () => {
testAction({
action: store.actions.incrementVolume,
payload: 0.2,
......@@ -108,27 +110,27 @@ describe('store/player', () => {
expectedMutations: [
{ type: 'volume', payload: 0.7 + 0.2 }
]
}, done)
})
})
it('toggle play false', (done) => {
it('toggle play false', () => {
testAction({
action: store.actions.togglePlay,
params: {state: {playing: false}},
expectedMutations: [
{ type: 'playing', payload: true }
]
}, done)
})
})
it('toggle play true', (done) => {
it('toggle play true', () => {
testAction({
action: store.actions.togglePlay,
params: {state: {playing: true}},
expectedMutations: [
{ type: 'playing', payload: false }
]
}, done)
})
})
it('trackEnded', (done) => {
it('trackEnded', () => {
testAction({
action: store.actions.trackEnded,
payload: {test: 'track'},
......@@ -137,9 +139,9 @@ describe('store/player', () => {
{ type: 'trackListened', payload: {test: 'track'} },
{ type: 'queue/next', payload: null, options: {root: true} }
]
}, done)
})
})
it('trackEnded calls populateQueue if last', (done) => {
it('trackEnded calls populateQueue if last', () => {
testAction({
action: store.actions.trackEnded,
payload: {test: 'track'},
......@@ -149,9 +151,9 @@ describe('store/player', () => {
{ type: 'radios/populateQueue', payload: null, options: {root: true} },
{ type: 'queue/next', payload: null, options: {root: true} }
]
}, done)
})
})
it('trackErrored', (done) => {
it('trackErrored', () => {
testAction({
action: store.actions.trackErrored,
payload: {test: 'track'},
......@@ -163,16 +165,16 @@ describe('store/player', () => {
expectedActions: [
{ type: 'queue/next', payload: null, options: {root: true} }
]
}, done)
})
})
it('updateProgress', (done) => {
it('updateProgress', () => {
testAction({
action: store.actions.updateProgress,
payload: 1,
expectedMutations: [
{ type: 'currentTime', payload: 1 }
]
}, done)
})
})
})
})
import {expect} from 'chai'
var sinon = require('sinon')
import moxios from 'moxios'
import store from '@/store/playlists'
......@@ -8,7 +9,7 @@ describe('store/playlists', () => {
var sandbox
beforeEach(function () {
sandbox = sinon.sandbox.create()
sandbox = sinon.createSandbox()
moxios.install()
})
afterEach(function () {
......@@ -24,13 +25,13 @@ describe('store/playlists', () => {
})
})
describe('actions', () => {
it('fetchOwn does nothing with no user', (done) => {
it('fetchOwn does nothing with no user', () => {
testAction({
action: store.actions.fetchOwn,
payload: null,
params: {state: { playlists: [] }, rootState: {auth: {profile: {}}}},
expectedMutations: []
}, done)
})
})
})
})
var sinon = require('sinon')
import {expect} from 'chai'
import _ from 'lodash'
import store from '@/store/queue'
......@@ -9,7 +11,7 @@ describe('store/queue', () => {
beforeEach(function () {
// Create a sandbox for the test
sandbox = sinon.sandbox.create()
sandbox = sinon.createSandbox()
})
afterEach(function () {
......@@ -83,7 +85,7 @@ describe('store/queue', () => {
})
})
describe('actions', () => {
it('append at end', (done) => {
it('append at end', () => {
testAction({
action: store.actions.append,
payload: {track: 4, skipPlay: true},
......@@ -91,9 +93,9 @@ describe('store/queue', () => {
expectedMutations: [
{ type: 'insert', payload: {track: 4, index: 3} }
]
}, done)
})
})
it('append at index', (done) => {
it('append at index', () => {
testAction({
action: store.actions.append,
payload: {track: 2, index: 1, skipPlay: true},
......@@ -101,9 +103,9 @@ describe('store/queue', () => {
expectedMutations: [
{ type: 'insert', payload: {track: 2, index: 1} }
]