import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import {
mapVuexModuleActions,
mapVuexModuleGetters,
mapVuexModuleState,
REQUIRE_STRING_ERROR_MESSAGE,
} from '~/lib/utils/vuex_module_mappers';
const TEST_MODULE_NAME = 'testModuleName';
Vue.use(Vuex);
// setup test component and store ----------------------------------------------
//
// These are used to indirectly test `vuex_module_mappers`.
const TestComponent = {
props: {
vuexModule: {
type: String,
required: true,
},
},
computed: {
...mapVuexModuleState((vm) => vm.vuexModule, { name: 'name', value: 'count' }),
...mapVuexModuleGetters((vm) => vm.vuexModule, ['hasValue', 'hasName']),
stateJson() {
return JSON.stringify({
name: this.name,
value: this.value,
});
},
gettersJson() {
return JSON.stringify({
hasValue: this.hasValue,
hasName: this.hasName,
});
},
},
methods: {
...mapVuexModuleActions((vm) => vm.vuexModule, ['increment']),
},
template: `
{{ stateJson }}
{{ gettersJson }}
`,
};
const createTestStore = () => {
return new Vuex.Store({
modules: {
[TEST_MODULE_NAME]: {
namespaced: true,
state: {
name: 'Lorem',
count: 0,
},
mutations: {
INCREMENT: (state, amount) => {
state.count += amount;
},
},
actions: {
increment({ commit }, amount) {
commit('INCREMENT', amount);
},
},
getters: {
hasValue: (state) => state.count > 0,
hasName: (state) => Boolean(state.name.length),
},
},
},
});
};
describe('~/lib/utils/vuex_module_mappers', () => {
let store;
let wrapper;
const getJsonInTemplate = (testId) =>
JSON.parse(wrapper.find(`[data-testid="${testId}"]`).text());
const getMappedState = () => getJsonInTemplate('state');
const getMappedGetters = () => getJsonInTemplate('getters');
beforeEach(() => {
store = createTestStore();
wrapper = mount(TestComponent, {
propsData: {
vuexModule: TEST_MODULE_NAME,
},
store,
});
});
afterEach(() => {
wrapper.destroy();
});
describe('from module defined by prop', () => {
it('maps state', () => {
expect(getMappedState()).toEqual({
name: store.state[TEST_MODULE_NAME].name,
value: store.state[TEST_MODULE_NAME].count,
});
});
it('maps getters', () => {
expect(getMappedGetters()).toEqual({
hasName: true,
hasValue: false,
});
});
it('maps action', () => {
jest.spyOn(store, 'dispatch');
expect(store.dispatch).not.toHaveBeenCalled();
wrapper.vm.increment(10);
expect(store.dispatch).toHaveBeenCalledWith(`${TEST_MODULE_NAME}/increment`, 10);
});
});
describe('with non-string object value', () => {
it('throws helpful error', () => {
expect(() => mapVuexModuleActions((vm) => vm.bogus, { foo: () => {} })).toThrowError(
REQUIRE_STRING_ERROR_MESSAGE,
);
});
});
});