const noop = () => {}; /** * Helper for testing action with expected mutations inspired in * https://vuex.vuejs.org/en/testing.html * * @param {Function} action to be tested * @param {Object} payload will be provided to the action * @param {Object} state will be provided to the action * @param {Array} [expectedMutations=[]] mutations expected to be committed * @param {Array} [expectedActions=[]] actions expected to be dispatched * @param {Function} [done=noop] to be executed after the tests * @return {Promise} * * @example * testAction( * actions.actionName, // action * { }, // mocked payload * state, //state * // expected mutations * [ * { type: types.MUTATION} * { type: types.MUTATION_1, payload: jasmine.any(Number)} * ], * // expected actions * [ * { type: 'actionName', payload: {param: 'foobar'}}, * { type: 'actionName1'} * ] * done, * ); * * @example * testAction( * actions.actionName, // action * { }, // mocked payload * state, //state * [ { type: types.MUTATION} ], // expected mutations * [], // expected actions * ).then(done) * .catch(done.fail); */ export default ( action, payload, state, expectedMutations = [], expectedActions = [], done = noop, ) => { const mutations = []; const actions = []; // mock commit const commit = (type, mutationPayload) => { const mutation = { type }; if (typeof mutationPayload !== 'undefined') { mutation.payload = mutationPayload; } mutations.push(mutation); }; // mock dispatch const dispatch = (type, actionPayload) => { const dispatchedAction = { type }; if (typeof actionPayload !== 'undefined') { dispatchedAction.payload = actionPayload; } actions.push(dispatchedAction); }; const validateResults = () => { expect({ mutations, actions, }).toEqual({ mutations: expectedMutations, actions: expectedActions, }); done(); }; const result = action({ commit, state, dispatch, rootState: state, rootGetters: state }, payload); return new Promise(resolve => { setImmediate(resolve); }) .then(() => result) .catch(error => { validateResults(); throw error; }) .then(data => { validateResults(); return data; }); };