Files
hammond/ui/tests/unit/setup.js
Akhil Gupta d25c30a7b2 first commit
2021-05-29 15:20:50 +05:30

210 lines
5.4 KiB
JavaScript

import fs from 'fs'
import path from 'path'
import Vue from 'vue'
import Vuex from 'vuex'
import axios from 'axios'
// ===
// Utility functions
// ===
// https://vue-test-utils.vuejs.org/
const vueTestUtils = require('@vue/test-utils')
// https://lodash.com/
const _ = require('lodash')
_.mixin({
pascalCase: _.flow(_.camelCase, _.upperFirst),
})
// ===
// Configure Axios
// ===
// Force Axios to use the XHR adapter so that it behaves
// more like it would in a browser environment.
axios.defaults.adapter = require('axios/lib/adapters/xhr')
// ===
// Configure Vue
// ===
// Don't warn about not using the production build of Vue, as
// we care more about the quality of errors than performance
// for tests.
Vue.config.productionTip = false
// ===
// Register global components
// ===
const globalComponentFiles = fs
.readdirSync(path.join(__dirname, '../../src/components'))
.filter((fileName) => /^_base-.+\.vue$/.test(fileName))
for (const fileName of globalComponentFiles) {
const componentName = _.pascalCase(fileName.match(/^_(base-.+)\.vue$/)[1])
const componentConfig = require('../../src/components/' + fileName)
Vue.component(componentName, componentConfig.default || componentConfig)
}
// ===
// Mock window properties not handled by jsdom
// ===
Object.defineProperty(window, 'localStorage', {
value: (function() {
let store = {}
return {
getItem: function(key) {
return store[key] || null
},
setItem: function(key, value) {
store[key] = value.toString()
},
clear: function() {
store = {}
},
}
})(),
})
// ===
// Console handlers
// ===
// Make console.error throw, so that Jest tests fail
const error = console.error
console.error = function(message) {
error.apply(console, arguments)
// NOTE: You can whitelist some `console.error` messages here
// by returning if the `message` value is acceptable.
throw message instanceof Error ? message : new Error(message)
}
// Make console.warn throw, so that Jest tests fail
const warn = console.warn
console.warn = function(message) {
warn.apply(console, arguments)
// NOTE: You can whitelist some `console.warn` messages here
// by returning if the `message` value is acceptable.
throw message instanceof Error ? message : new Error(message)
}
// ===
// Global helpers
// ===
// https://vue-test-utils.vuejs.org/api/#mount
global.mount = vueTestUtils.mount
// https://vue-test-utils.vuejs.org/api/#shallowmount
global.shallowMount = vueTestUtils.shallowMount
// A special version of `shallowMount` for view components
global.shallowMountView = (Component, options = {}) => {
return global.shallowMount(Component, {
...options,
stubs: {
Layout: {
functional: true,
render(h, { slots }) {
return <div>{slots().default}</div>
},
},
...(options.stubs || {}),
},
})
}
// A helper for creating Vue component mocks
global.createComponentMocks = ({ store, router, style, mocks, stubs }) => {
// Use a local version of Vue, to avoid polluting the global
// Vue and thereby affecting other tests.
// https://vue-test-utils.vuejs.org/api/#createlocalvue
const localVue = vueTestUtils.createLocalVue()
const returnOptions = { localVue }
// https://vue-test-utils.vuejs.org/api/options.html#stubs
returnOptions.stubs = stubs || {}
// https://vue-test-utils.vuejs.org/api/options.html#mocks
returnOptions.mocks = mocks || {}
// Converts a `store` option shaped like:
//
// store: {
// someModuleName: {
// state: { ... },
// getters: { ... },
// actions: { ... },
// },
// anotherModuleName: {
// getters: { ... },
// },
// },
//
// to a store instance, with each module namespaced by
// default, just like in our app.
if (store) {
localVue.use(Vuex)
returnOptions.store = new Vuex.Store({
modules: Object.keys(store)
.map((moduleName) => {
const storeModule = store[moduleName]
return {
[moduleName]: {
state: storeModule.state || {},
getters: storeModule.getters || {},
actions: storeModule.actions || {},
namespaced:
typeof storeModule.namespaced === 'undefined'
? true
: storeModule.namespaced,
},
}
})
.reduce((moduleA, moduleB) => Object.assign({}, moduleA, moduleB), {}),
})
}
// If using `router: true`, we'll automatically stub out
// components from Vue Router.
if (router) {
returnOptions.stubs['router-link'] = true
returnOptions.stubs['router-view'] = true
}
// If a `style` object is provided, mock some styles.
if (style) {
returnOptions.mocks.$style = style
}
return returnOptions
}
global.createModuleStore = (vuexModule, options = {}) => {
vueTestUtils.createLocalVue().use(Vuex)
const store = new Vuex.Store({
..._.cloneDeep(vuexModule),
modules: {
auth: {
namespaced: true,
state: {
currentUser: options.currentUser,
},
},
},
// Enable strict mode when testing Vuex modules so that
// mutating state outside of a mutation results in a
// failing test.
// https://vuex.vuejs.org/guide/strict.html
strict: true,
})
axios.defaults.headers.common.Authorization = options.currentUser
? options.currentUser.token
: ''
if (vuexModule.actions.init) {
store.dispatch('init')
}
return store
}