Commit d1923580 authored by Donald Cook's avatar Donald Cook Committed by Martin Wortschack

Refactor notes actions from Karma to Jest

parent 8633453d
// eslint-disable-next-line import/prefer-default-export
export const resetStore = store => {
store.replaceState({
notes: [],
targetNoteHash: null,
lastFetchedAt: null,
notesData: {},
userData: {},
noteableData: {},
});
};
import $ from 'jquery';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import AxiosMockAdapter from 'axios-mock-adapter'; import AxiosMockAdapter from 'axios-mock-adapter';
import Api from '~/api'; import Api from '~/api';
import actionsModule, * as actions from '~/notes/stores/actions'; import Flash from '~/flash';
import * as actions from '~/notes/stores/actions';
import * as mutationTypes from '~/notes/stores/mutation_types'; import * as mutationTypes from '~/notes/stores/mutation_types';
import * as notesConstants from '~/notes/constants'; import * as notesConstants from '~/notes/constants';
import createStore from '~/notes/stores'; import createStore from '~/notes/stores';
...@@ -19,21 +19,20 @@ import { ...@@ -19,21 +19,20 @@ import {
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
const TEST_ERROR_MESSAGE = 'Test error message'; const TEST_ERROR_MESSAGE = 'Test error message';
jest.mock('~/flash');
describe('Actions Notes Store', () => { describe('Actions Notes Store', () => {
let commit; let commit;
let dispatch; let dispatch;
let state; let state;
let store; let store;
let flashSpy;
let axiosMock; let axiosMock;
beforeEach(() => { beforeEach(() => {
store = createStore(); store = createStore();
commit = jasmine.createSpy('commit'); commit = jest.fn();
dispatch = jasmine.createSpy('dispatch'); dispatch = jest.fn();
state = {}; state = {};
flashSpy = spyOnDependency(actionsModule, 'Flash');
axiosMock = new AxiosMockAdapter(axios); axiosMock = new AxiosMockAdapter(axios);
}); });
...@@ -244,10 +243,10 @@ describe('Actions Notes Store', () => { ...@@ -244,10 +243,10 @@ describe('Actions Notes Store', () => {
}); });
describe('poll', () => { describe('poll', () => {
beforeEach(done => { jest.useFakeTimers();
jasmine.clock().install();
spyOn(axios, 'get').and.callThrough(); beforeEach(done => {
jest.spyOn(axios, 'get');
store store
.dispatch('setNotesData', notesDataMock) .dispatch('setNotesData', notesDataMock)
...@@ -255,10 +254,6 @@ describe('Actions Notes Store', () => { ...@@ -255,10 +254,6 @@ describe('Actions Notes Store', () => {
.catch(done.fail); .catch(done.fail);
}); });
afterEach(() => {
jasmine.clock().uninstall();
});
it('calls service with last fetched state', done => { it('calls service with last fetched state', done => {
axiosMock axiosMock
.onAny() .onAny()
...@@ -271,7 +266,7 @@ describe('Actions Notes Store', () => { ...@@ -271,7 +266,7 @@ describe('Actions Notes Store', () => {
expect(axios.get).toHaveBeenCalled(); expect(axios.get).toHaveBeenCalled();
expect(store.state.lastFetchedAt).toBe('123456'); expect(store.state.lastFetchedAt).toBe('123456');
jasmine.clock().tick(1500); jest.advanceTimersByTime(1500);
}) })
.then( .then(
() => () =>
...@@ -280,8 +275,8 @@ describe('Actions Notes Store', () => { ...@@ -280,8 +275,8 @@ describe('Actions Notes Store', () => {
}), }),
) )
.then(() => { .then(() => {
expect(axios.get.calls.count()).toBe(2); expect(axios.get.mock.calls.length).toBe(2);
expect(axios.get.calls.mostRecent().args[1].headers).toEqual({ expect(axios.get.mock.calls[axios.get.mock.calls.length - 1][1].headers).toEqual({
'X-Last-Fetched-At': '123456', 'X-Last-Fetched-At': '123456',
}); });
}) })
...@@ -310,13 +305,13 @@ describe('Actions Notes Store', () => { ...@@ -310,13 +305,13 @@ describe('Actions Notes Store', () => {
beforeEach(() => { beforeEach(() => {
axiosMock.onDelete(endpoint).replyOnce(200, {}); axiosMock.onDelete(endpoint).replyOnce(200, {});
$('body').attr('data-page', ''); document.body.setAttribute('data-page', '');
}); });
afterEach(() => { afterEach(() => {
axiosMock.restore(); axiosMock.restore();
$('body').attr('data-page', ''); document.body.setAttribute('data-page', '');
}); });
it('commits DELETE_NOTE and dispatches updateMergeRequestWidget', done => { it('commits DELETE_NOTE and dispatches updateMergeRequestWidget', done => {
...@@ -347,7 +342,7 @@ describe('Actions Notes Store', () => { ...@@ -347,7 +342,7 @@ describe('Actions Notes Store', () => {
it('dispatches removeDiscussionsFromDiff on merge request page', done => { it('dispatches removeDiscussionsFromDiff on merge request page', done => {
const note = { path: endpoint, id: 1 }; const note = { path: endpoint, id: 1 };
$('body').attr('data-page', 'projects:merge_requests:show'); document.body.setAttribute('data-page', 'projects:merge_requests:show');
testAction( testAction(
actions.removeNote, actions.removeNote,
...@@ -381,13 +376,13 @@ describe('Actions Notes Store', () => { ...@@ -381,13 +376,13 @@ describe('Actions Notes Store', () => {
beforeEach(() => { beforeEach(() => {
axiosMock.onDelete(endpoint).replyOnce(200, {}); axiosMock.onDelete(endpoint).replyOnce(200, {});
$('body').attr('data-page', ''); document.body.setAttribute('data-page', '');
}); });
afterEach(() => { afterEach(() => {
axiosMock.restore(); axiosMock.restore();
$('body').attr('data-page', ''); document.body.setAttribute('data-page', '');
}); });
it('dispatches removeNote', done => { it('dispatches removeNote', done => {
...@@ -534,7 +529,7 @@ describe('Actions Notes Store', () => { ...@@ -534,7 +529,7 @@ describe('Actions Notes Store', () => {
describe('updateMergeRequestWidget', () => { describe('updateMergeRequestWidget', () => {
it('calls mrWidget checkStatus', () => { it('calls mrWidget checkStatus', () => {
spyOn(mrWidgetEventHub, '$emit'); jest.spyOn(mrWidgetEventHub, '$emit').mockImplementation(() => {});
actions.updateMergeRequestWidget(); actions.updateMergeRequestWidget();
...@@ -589,7 +584,7 @@ describe('Actions Notes Store', () => { ...@@ -589,7 +584,7 @@ describe('Actions Notes Store', () => {
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [note]); actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [note]);
expect(commit.calls.allArgs()).toEqual([[mutationTypes.UPDATE_NOTE, note]]); expect(commit.mock.calls).toEqual([[mutationTypes.UPDATE_NOTE, note]]);
}); });
it('Creates a new note if none exisits', () => { it('Creates a new note if none exisits', () => {
...@@ -597,7 +592,7 @@ describe('Actions Notes Store', () => { ...@@ -597,7 +592,7 @@ describe('Actions Notes Store', () => {
const getters = { notesById: {} }; const getters = { notesById: {} };
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [note]); actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [note]);
expect(commit.calls.allArgs()).toEqual([[mutationTypes.ADD_NEW_NOTE, note]]); expect(commit.mock.calls).toEqual([[mutationTypes.ADD_NEW_NOTE, note]]);
}); });
describe('Discussion notes', () => { describe('Discussion notes', () => {
...@@ -619,7 +614,7 @@ describe('Actions Notes Store', () => { ...@@ -619,7 +614,7 @@ describe('Actions Notes Store', () => {
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [discussionNote]); actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [discussionNote]);
expect(commit.calls.allArgs()).toEqual([ expect(commit.mock.calls).toEqual([
[mutationTypes.ADD_NEW_REPLY_TO_DISCUSSION, discussionNote], [mutationTypes.ADD_NEW_REPLY_TO_DISCUSSION, discussionNote],
]); ]);
}); });
...@@ -630,7 +625,7 @@ describe('Actions Notes Store', () => { ...@@ -630,7 +625,7 @@ describe('Actions Notes Store', () => {
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [diffNote]); actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [diffNote]);
expect(dispatch.calls.allArgs()).toEqual([ expect(dispatch.mock.calls).toEqual([
['fetchDiscussions', { path: state.notesData.discussionsPath }], ['fetchDiscussions', { path: state.notesData.discussionsPath }],
]); ]);
}); });
...@@ -645,7 +640,7 @@ describe('Actions Notes Store', () => { ...@@ -645,7 +640,7 @@ describe('Actions Notes Store', () => {
actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [discussionNote]); actions.updateOrCreateNotes({ commit, state, getters, dispatch }, [discussionNote]);
expect(commit.calls.allArgs()).toEqual([[mutationTypes.ADD_NEW_NOTE, discussionNote]]); expect(commit.mock.calls).toEqual([[mutationTypes.ADD_NEW_NOTE, discussionNote]]);
}); });
}); });
}); });
...@@ -770,7 +765,7 @@ describe('Actions Notes Store', () => { ...@@ -770,7 +765,7 @@ describe('Actions Notes Store', () => {
.then(() => done.fail('Expected error to be thrown!')) .then(() => done.fail('Expected error to be thrown!'))
.catch(err => { .catch(err => {
expect(err).toBe(error); expect(err).toBe(error);
expect(flashSpy).not.toHaveBeenCalled(); expect(Flash).not.toHaveBeenCalled();
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -792,7 +787,7 @@ describe('Actions Notes Store', () => { ...@@ -792,7 +787,7 @@ describe('Actions Notes Store', () => {
) )
.then(resp => { .then(resp => {
expect(resp.hasFlash).toBe(true); expect(resp.hasFlash).toBe(true);
expect(flashSpy).toHaveBeenCalledWith( expect(Flash).toHaveBeenCalledWith(
'Your comment could not be submitted because something went wrong', 'Your comment could not be submitted because something went wrong',
'alert', 'alert',
flashContainer, flashContainer,
...@@ -818,7 +813,7 @@ describe('Actions Notes Store', () => { ...@@ -818,7 +813,7 @@ describe('Actions Notes Store', () => {
) )
.then(data => { .then(data => {
expect(data).toBe(res); expect(data).toBe(res);
expect(flashSpy).not.toHaveBeenCalled(); expect(Flash).not.toHaveBeenCalled();
}) })
.then(done) .then(done)
.catch(done.fail); .catch(done.fail);
...@@ -833,9 +828,8 @@ describe('Actions Notes Store', () => { ...@@ -833,9 +828,8 @@ describe('Actions Notes Store', () => {
let flashContainer; let flashContainer;
beforeEach(() => { beforeEach(() => {
spyOn(Api, 'applySuggestion'); jest.spyOn(Api, 'applySuggestion').mockReturnValue(Promise.resolve());
dispatch.and.returnValue(Promise.resolve()); dispatch.mockReturnValue(Promise.resolve());
Api.applySuggestion.and.returnValue(Promise.resolve());
flashContainer = {}; flashContainer = {};
}); });
...@@ -852,32 +846,32 @@ describe('Actions Notes Store', () => { ...@@ -852,32 +846,32 @@ describe('Actions Notes Store', () => {
it('when service success, commits and resolves discussion', done => { it('when service success, commits and resolves discussion', done => {
testSubmitSuggestion(done, () => { testSubmitSuggestion(done, () => {
expect(commit.calls.allArgs()).toEqual([ expect(commit.mock.calls).toEqual([
[mutationTypes.APPLY_SUGGESTION, { discussionId, noteId, suggestionId }], [mutationTypes.APPLY_SUGGESTION, { discussionId, noteId, suggestionId }],
]); ]);
expect(dispatch.calls.allArgs()).toEqual([['resolveDiscussion', { discussionId }]]); expect(dispatch.mock.calls).toEqual([['resolveDiscussion', { discussionId }]]);
expect(flashSpy).not.toHaveBeenCalled(); expect(Flash).not.toHaveBeenCalled();
}); });
}); });
it('when service fails, flashes error message', done => { it('when service fails, flashes error message', done => {
const response = { response: { data: { message: TEST_ERROR_MESSAGE } } }; const response = { response: { data: { message: TEST_ERROR_MESSAGE } } };
Api.applySuggestion.and.returnValue(Promise.reject(response)); Api.applySuggestion.mockReturnValue(Promise.reject(response));
testSubmitSuggestion(done, () => { testSubmitSuggestion(done, () => {
expect(commit).not.toHaveBeenCalled(); expect(commit).not.toHaveBeenCalled();
expect(dispatch).not.toHaveBeenCalled(); expect(dispatch).not.toHaveBeenCalled();
expect(flashSpy).toHaveBeenCalledWith(`${TEST_ERROR_MESSAGE}.`, 'alert', flashContainer); expect(Flash).toHaveBeenCalledWith(`${TEST_ERROR_MESSAGE}.`, 'alert', flashContainer);
}); });
}); });
it('when resolve discussion fails, fail gracefully', done => { it('when resolve discussion fails, fail gracefully', done => {
dispatch.and.returnValue(Promise.reject()); dispatch.mockReturnValue(Promise.reject());
testSubmitSuggestion(done, () => { testSubmitSuggestion(done, () => {
expect(flashSpy).not.toHaveBeenCalled(); expect(Flash).not.toHaveBeenCalled();
}); });
}); });
}); });
...@@ -887,13 +881,13 @@ describe('Actions Notes Store', () => { ...@@ -887,13 +881,13 @@ describe('Actions Notes Store', () => {
const filter = 0; const filter = 0;
beforeEach(() => { beforeEach(() => {
dispatch.and.returnValue(new Promise(() => {})); dispatch.mockReturnValue(new Promise(() => {}));
}); });
it('fetches discussions with filter and persistFilter false', () => { it('fetches discussions with filter and persistFilter false', () => {
actions.filterDiscussion({ dispatch }, { path, filter, persistFilter: false }); actions.filterDiscussion({ dispatch }, { path, filter, persistFilter: false });
expect(dispatch.calls.allArgs()).toEqual([ expect(dispatch.mock.calls).toEqual([
['setLoadingState', true], ['setLoadingState', true],
['fetchDiscussions', { path, filter, persistFilter: false }], ['fetchDiscussions', { path, filter, persistFilter: false }],
]); ]);
...@@ -902,7 +896,7 @@ describe('Actions Notes Store', () => { ...@@ -902,7 +896,7 @@ describe('Actions Notes Store', () => {
it('fetches discussions with filter and persistFilter true', () => { it('fetches discussions with filter and persistFilter true', () => {
actions.filterDiscussion({ dispatch }, { path, filter, persistFilter: true }); actions.filterDiscussion({ dispatch }, { path, filter, persistFilter: true });
expect(dispatch.calls.allArgs()).toEqual([ expect(dispatch.mock.calls).toEqual([
['setLoadingState', true], ['setLoadingState', true],
['fetchDiscussions', { path, filter, persistFilter: true }], ['fetchDiscussions', { path, filter, persistFilter: true }],
]); ]);
......
// eslint-disable-next-line import/prefer-default-export export * from '../../frontend/notes/helpers.js';
export const resetStore = store => {
store.replaceState({
notes: [],
targetNoteHash: null,
lastFetchedAt: null,
notesData: {},
userData: {},
noteableData: {},
});
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment