summaryrefslogtreecommitdiff
path: root/spec/frontend/__helpers__/vuex_action_helper.js
blob: bdd5a0a90344149e0e425a158c60104131a2f002 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// eslint-disable-next-line no-restricted-syntax
import { setImmediate } from 'timers';

/** Helper for testing action with expected mutations inspired in
 * https://vuex.vuejs.org/en/testing.html
 *
 * @param {(Function|Object)} action to be tested, or object of named parameters
 * @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
 * @return {Promise}
 *
 * @example
 * testAction(
 *   actions.actionName, // action
 *   { }, // mocked payload
 *   state, //state
 *   // expected mutations
 *   [
 *    { type: types.MUTATION}
 *    { type: types.MUTATION_1, payload: expect.any(Number)}
 *   ],
 *   // expected actions
 *   [
 *    { type: 'actionName', payload: {param: 'foobar'}},
 *    { type: 'actionName1'}
 *   ]
 * );
 *
 * @example
 * await testAction({
 *   action: actions.actionName,
 *   payload: { deleteListId: 1 },
 *   state: { lists: [1, 2, 3] },
 *   expectedMutations: [ { type: types.MUTATION} ],
 *   expectedActions: [],
 * })
 */

export default (
  actionArg,
  payloadArg,
  stateArg,
  expectedMutationsArg = [],
  expectedActionsArg = [],
) => {
  let action = actionArg;
  let payload = payloadArg;
  let state = stateArg;
  let expectedMutations = expectedMutationsArg;
  let expectedActions = expectedActionsArg;

  if (typeof actionArg !== 'function') {
    ({ action, payload, state, expectedMutations = [], expectedActions = [] } = actionArg);
  }

  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,
    });
  };

  const result = action(
    { commit, state, dispatch, rootState: state, rootGetters: state, getters: state },
    payload,
  );

  return (
    result ||
    new Promise((resolve) => {
      // eslint-disable-next-line no-restricted-syntax
      setImmediate(resolve);
    })
  )
    .catch((error) => {
      validateResults();
      throw error;
    })
    .then((data) => {
      validateResults();
      return data;
    });
};