Commit ac493c39 authored by Himanshu Kapoor's avatar Himanshu Kapoor

Migrate javascripts/* specs to Jest

Migrate some specs in spec/javascripts/* from Karma to Jest.
parent 42fce179
......@@ -4,7 +4,7 @@ import $ from 'jquery';
import { escape } from 'lodash';
import fuzzaldrinPlus from 'fuzzaldrin-plus';
import axios from './lib/utils/axios_utils';
import { visitUrl } from './lib/utils/url_utility';
import { visitUrl } from '~/lib/utils/url_utility';
import { isObject } from './lib/utils/type_utility';
import renderItem from './gl_dropdown/render';
......
import $ from 'jquery';
import { getParameterByName } from '~/lib/utils/common_utils';
import axios from './lib/utils/axios_utils';
import { removeParams } from './lib/utils/url_utility';
import axios from '~/lib/utils/axios_utils';
import { removeParams } from '~/lib/utils/url_utility';
const ENDLESS_SCROLL_BOTTOM_PX = 400;
const ENDLESS_SCROLL_FIRE_DELAY_MS = 1000;
......
......@@ -28,12 +28,20 @@ const useLocalStorage = fn => {
/**
* Create an object with the localStorage interface but `jest.fn()` implementations.
*/
export const createLocalStorageSpy = () => ({
clear: jest.fn(),
getItem: jest.fn(),
setItem: jest.fn(),
removeItem: jest.fn(),
});
export const createLocalStorageSpy = () => {
let storage = {};
return {
clear: jest.fn(() => {
storage = {};
}),
getItem: jest.fn(key => storage[key]),
setItem: jest.fn((key, value) => {
storage[key] = value;
}),
removeItem: jest.fn(key => delete storage[key]),
};
};
/**
* Before each test, overwrite `window.localStorage` with a spy implementation.
......
import { useLocalStorageSpy } from './local_storage_helper';
useLocalStorageSpy();
describe('localStorage helper', () => {
it('mocks localStorage but works exactly like original localStorage', () => {
localStorage.setItem('test', 'testing');
localStorage.setItem('test2', 'testing');
expect(localStorage.getItem('test')).toBe('testing');
localStorage.removeItem('test', 'testing');
expect(localStorage.getItem('test')).toBeUndefined();
expect(localStorage.getItem('test2')).toBe('testing');
localStorage.clear();
expect(localStorage.getItem('test2')).toBeUndefined();
});
});
......@@ -16,9 +16,8 @@ describe('Importer Status', () => {
describe('addToImport', () => {
const importUrl = '/import_url';
beforeEach(() => {
setFixtures(`
const fixtures = `
<table>
<tr id="repo_123">
<td class="import-target"></td>
<td class="import-actions job-status">
......@@ -26,9 +25,13 @@ describe('Importer Status', () => {
</button>
</td>
</tr>
`);
spyOn(ImporterStatus.prototype, 'initStatusPage').and.callFake(() => {});
spyOn(ImporterStatus.prototype, 'setAutoUpdate').and.callFake(() => {});
</table>
`;
beforeEach(() => {
setFixtures(fixtures);
jest.spyOn(ImporterStatus.prototype, 'initStatusPage').mockImplementation(() => {});
jest.spyOn(ImporterStatus.prototype, 'setAutoUpdate').mockImplementation(() => {});
instance = new ImporterStatus({
jobsUrl: '',
importUrl,
......@@ -53,7 +56,7 @@ describe('Importer Status', () => {
});
it('shows error message after failed POST request', done => {
appendSetFixtures('<div class="flash-container"></div>');
setFixtures(`${fixtures}<div class="flash-container"></div>`);
mock.onPost(importUrl).reply(422, {
errors: 'You forgot your lunch',
......@@ -89,8 +92,8 @@ describe('Importer Status', () => {
document.body.appendChild(div);
spyOn(ImporterStatus.prototype, 'initStatusPage').and.callFake(() => {});
spyOn(ImporterStatus.prototype, 'setAutoUpdate').and.callFake(() => {});
jest.spyOn(ImporterStatus.prototype, 'initStatusPage').mockImplementation(() => {});
jest.spyOn(ImporterStatus.prototype, 'setAutoUpdate').mockImplementation(() => {});
instance = new ImporterStatus({
jobsUrl,
});
......
......@@ -4,24 +4,26 @@ import axios from '~/lib/utils/axios_utils';
import MergeRequest from '~/merge_request';
import CloseReopenReportToggle from '~/close_reopen_report_toggle';
import IssuablesHelper from '~/helpers/issuables_helper';
import { TEST_HOST } from 'spec/test_constants';
describe('MergeRequest', function() {
describe('task lists', function() {
describe('MergeRequest', () => {
const test = {};
describe('task lists', () => {
let mock;
preloadFixtures('merge_requests/merge_request_with_task_list.html');
beforeEach(function() {
beforeEach(() => {
loadFixtures('merge_requests/merge_request_with_task_list.html');
spyOn(axios, 'patch').and.callThrough();
jest.spyOn(axios, 'patch');
mock = new MockAdapter(axios);
mock
.onPatch(`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`)
.onPatch(`${TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`)
.reply(200, {});
this.merge = new MergeRequest();
return this.merge;
test.merge = new MergeRequest();
return test.merge;
});
afterEach(() => {
......@@ -29,14 +31,14 @@ describe('MergeRequest', function() {
});
it('modifies the Markdown field', done => {
spyOn($, 'ajax').and.stub();
jest.spyOn($, 'ajax').mockImplementation();
const changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
$('input[type=checkbox]')
.first()
.attr('checked', true)[0]
.dispatchEvent(changeEvent);
setTimeout(() => {
setImmediate(() => {
expect($('.js-task-list-field').val()).toBe(
'- [x] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
);
......@@ -46,14 +48,14 @@ describe('MergeRequest', function() {
it('ensure that task with only spaces does not get checked incorrectly', done => {
// fixed in 'deckar01-task_list', '2.2.1' gem
spyOn($, 'ajax').and.stub();
jest.spyOn($, 'ajax').mockImplementation();
const changeEvent = document.createEvent('HTMLEvents');
changeEvent.initEvent('change', true, true);
$('input[type=checkbox]')
.last()
.attr('checked', true)[0]
.dispatchEvent(changeEvent);
setTimeout(() => {
setImmediate(() => {
expect($('.js-task-list-field').val()).toBe(
'- [ ] Task List Item\n- [ ] \n- [x] Task List Item 2\n',
);
......@@ -73,9 +75,9 @@ describe('MergeRequest', function() {
detail: { lineNumber, lineSource, index, checked },
});
setTimeout(() => {
setImmediate(() => {
expect(axios.patch).toHaveBeenCalledWith(
`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`,
`${TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`,
{
merge_request: {
description: '- [ ] Task List Item\n- [ ] \n- [ ] Task List Item 2\n',
......@@ -89,13 +91,9 @@ describe('MergeRequest', function() {
});
});
// https://gitlab.com/gitlab-org/gitlab/issues/34861
// eslint-disable-next-line jasmine/no-disabled-tests
xit('shows an error notification when tasklist update failed', done => {
it('shows an error notification when tasklist update failed', done => {
mock
.onPatch(
`${gl.TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`,
)
.onPatch(`${TEST_HOST}/frontend-fixtures/merge-requests-project/-/merge_requests/1.json`)
.reply(409, {});
$('.js-task-list-field').trigger({
......@@ -103,7 +101,7 @@ describe('MergeRequest', function() {
detail: { lineNumber, lineSource, index, checked },
});
setTimeout(() => {
setImmediate(() => {
expect(document.querySelector('.flash-container .flash-text').innerText.trim()).toBe(
'Someone edited this merge request at the same time you did. Please refresh the page to see changes.',
);
......@@ -116,11 +114,11 @@ describe('MergeRequest', function() {
describe('class constructor', () => {
beforeEach(() => {
spyOn($, 'ajax').and.stub();
jest.spyOn($, 'ajax').mockImplementation();
});
it('calls .initCloseReopenReport', () => {
spyOn(IssuablesHelper, 'initCloseReopenReport');
jest.spyOn(IssuablesHelper, 'initCloseReopenReport').mockImplementation(() => {});
new MergeRequest(); // eslint-disable-line no-new
......@@ -128,14 +126,20 @@ describe('MergeRequest', function() {
});
it('calls .initDroplab', () => {
const container = jasmine.createSpyObj('container', ['querySelector']);
const container = {
querySelector: jest.fn().mockName('container.querySelector'),
};
const dropdownTrigger = {};
const dropdownList = {};
const button = {};
spyOn(CloseReopenReportToggle.prototype, 'initDroplab');
spyOn(document, 'querySelector').and.returnValue(container);
container.querySelector.and.returnValues(dropdownTrigger, dropdownList, button);
jest.spyOn(CloseReopenReportToggle.prototype, 'initDroplab').mockImplementation(() => {});
jest.spyOn(document, 'querySelector').mockReturnValue(container);
container.querySelector
.mockReturnValueOnce(dropdownTrigger)
.mockReturnValueOnce(dropdownList)
.mockReturnValueOnce(button);
new MergeRequest(); // eslint-disable-line no-new
......@@ -151,15 +155,15 @@ describe('MergeRequest', function() {
describe('merge request of another user', () => {
beforeEach(() => {
loadFixtures('merge_requests/merge_request_with_task_list.html');
this.el = document.querySelector('.js-issuable-actions');
test.el = document.querySelector('.js-issuable-actions');
new MergeRequest(); // eslint-disable-line no-new
MergeRequest.hideCloseButton();
});
it('hides the dropdown close item and selects the next item', () => {
const closeItem = this.el.querySelector('li.close-item');
const smallCloseItem = this.el.querySelector('.js-close-item');
const reportItem = this.el.querySelector('li.report-item');
const closeItem = test.el.querySelector('li.close-item');
const smallCloseItem = test.el.querySelector('.js-close-item');
const reportItem = test.el.querySelector('li.report-item');
expect(closeItem).toHaveClass('hidden');
expect(smallCloseItem).toHaveClass('hidden');
......@@ -171,13 +175,13 @@ describe('MergeRequest', function() {
describe('merge request of current_user', () => {
beforeEach(() => {
loadFixtures('merge_requests/merge_request_of_current_user.html');
this.el = document.querySelector('.js-issuable-actions');
test.el = document.querySelector('.js-issuable-actions');
MergeRequest.hideCloseButton();
});
it('hides the close button', () => {
const closeButton = this.el.querySelector('.btn-close');
const smallCloseItem = this.el.querySelector('.js-close-item');
const closeButton = test.el.querySelector('.btn-close');
const smallCloseItem = test.el.querySelector('.js-close-item');
expect(closeButton).toHaveClass('hidden');
expect(smallCloseItem).toHaveClass('hidden');
......
......@@ -2,7 +2,7 @@ import $ from 'jquery';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import MiniPipelineGraph from '~/mini_pipeline_graph_dropdown';
import timeoutPromise from './helpers/set_timeout_promise_helper';
import waitForPromises from './helpers/wait_for_promises';
describe('Mini Pipeline Graph Dropdown', () => {
preloadFixtures('static/mini_dropdown_graph.html');
......@@ -39,9 +39,9 @@ describe('Mini Pipeline Graph Dropdown', () => {
});
it('should call getBuildsList', () => {
const getBuildsListSpy = spyOn(MiniPipelineGraph.prototype, 'getBuildsList').and.callFake(
function() {},
);
const getBuildsListSpy = jest
.spyOn(MiniPipelineGraph.prototype, 'getBuildsList')
.mockImplementation(() => {});
new MiniPipelineGraph({ container: '.js-builds-dropdown-tests' }).bindEvents();
......@@ -51,7 +51,7 @@ describe('Mini Pipeline Graph Dropdown', () => {
});
it('should make a request to the endpoint provided in the html', () => {
const ajaxSpy = spyOn(axios, 'get').and.callThrough();
const ajaxSpy = jest.spyOn(axios, 'get');
mock.onGet('foobar').reply(200, {
html: '',
......@@ -61,7 +61,7 @@ describe('Mini Pipeline Graph Dropdown', () => {
document.querySelector('.js-builds-dropdown-button').click();
expect(ajaxSpy.calls.allArgs()[0][0]).toEqual('foobar');
expect(ajaxSpy.mock.calls[0][0]).toEqual('foobar');
});
it('should not close when user uses cmd/ctrl + click', done => {
......@@ -78,11 +78,11 @@ describe('Mini Pipeline Graph Dropdown', () => {
document.querySelector('.js-builds-dropdown-button').click();
timeoutPromise()
waitForPromises()
.then(() => {
document.querySelector('a.mini-pipeline-graph-dropdown-item').click();
})
.then(timeoutPromise)
.then(waitForPromises)
.then(() => {
expect($('.js-builds-dropdown-list').is(':visible')).toEqual(true);
})
......@@ -97,7 +97,7 @@ describe('Mini Pipeline Graph Dropdown', () => {
document.querySelector('.js-builds-dropdown-button').click();
setTimeout(() => {
setImmediate(() => {
expect($('.js-builds-dropdown-tests .dropdown').hasClass('open')).toEqual(false);
done();
});
......
......@@ -2,6 +2,11 @@ import $ from 'jquery';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import Pager from '~/pager';
import { removeParams } from '~/lib/utils/url_utility';
jest.mock('~/lib/utils/url_utility', () => ({
removeParams: jest.fn().mockName('removeParams'),
}));
describe('pager', () => {
let axiosMock;
......@@ -19,7 +24,7 @@ describe('pager', () => {
beforeEach(() => {
setFixtures('<div class="content_list"></div><div class="loading"></div>');
spyOn($.fn, 'endlessScroll').and.stub();
jest.spyOn($.fn, 'endlessScroll').mockImplementation();
});
afterEach(() => {
......@@ -36,7 +41,7 @@ describe('pager', () => {
it('should use current url if data-href attribute not provided', () => {
const href = `${gl.TEST_HOST}/some_list`;
spyOnDependency(Pager, 'removeParams').and.returnValue(href);
removeParams.mockReturnValue(href);
Pager.init();
expect(Pager.url).toBe(href);
......@@ -52,7 +57,7 @@ describe('pager', () => {
it('keeps extra query parameters from url', () => {
window.history.replaceState({}, null, '?filter=test&offset=100');
const href = `${gl.TEST_HOST}/some_list?filter=test`;
const removeParams = spyOnDependency(Pager, 'removeParams').and.returnValue(href);
removeParams.mockReturnValue(href);
Pager.init();
expect(removeParams).toHaveBeenCalledWith(['limit', 'offset']);
......@@ -78,7 +83,7 @@ describe('pager', () => {
setFixtures(
'<div class="content_list" data-href="/some_list"></div><div class="loading"></div>',
);
spyOn(axios, 'get').and.callThrough();
jest.spyOn(axios, 'get');
Pager.init();
});
......@@ -86,10 +91,10 @@ describe('pager', () => {
it('shows loader while loading next page', done => {
mockSuccess();
spyOn(Pager.loading, 'show');
jest.spyOn(Pager.loading, 'show').mockImplementation(() => {});
Pager.getOld();
setTimeout(() => {
setImmediate(() => {
expect(Pager.loading.show).toHaveBeenCalled();
done();
......@@ -99,10 +104,10 @@ describe('pager', () => {
it('hides loader on success', done => {
mockSuccess();
spyOn(Pager.loading, 'hide');
jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
Pager.getOld();
setTimeout(() => {
setImmediate(() => {
expect(Pager.loading.hide).toHaveBeenCalled();
done();
......@@ -112,10 +117,10 @@ describe('pager', () => {
it('hides loader on error', done => {
mockError();
spyOn(Pager.loading, 'hide');
jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
Pager.getOld();
setTimeout(() => {
setImmediate(() => {
expect(Pager.loading.hide).toHaveBeenCalled();
done();
......@@ -127,8 +132,8 @@ describe('pager', () => {
Pager.limit = 20;
Pager.getOld();
setTimeout(() => {
const [url, params] = axios.get.calls.argsFor(0);
setImmediate(() => {
const [url, params] = axios.get.mock.calls[0];
expect(params).toEqual({
params: {
......@@ -148,10 +153,10 @@ describe('pager', () => {
Pager.limit = 20;
mockSuccess(1);
spyOn(Pager.loading, 'hide');
jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
Pager.getOld();
setTimeout(() => {
setImmediate(() => {
expect(Pager.loading.hide).toHaveBeenCalled();
expect(Pager.disable).toBe(true);
......
......@@ -5,6 +5,11 @@ import '~/lib/utils/common_utils';
import '~/gl_dropdown';
import axios from '~/lib/utils/axios_utils';
import { addDelimiter } from '~/lib/utils/text_utility';
import { visitUrl } from '~/lib/utils/url_utility';
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn().mockName('visitUrl'),
}));
const TEST_COUNT_BIG = 2000;
const TEST_DONE_COUNT_BIG = 7300;
......@@ -30,7 +35,7 @@ describe('Todos', () => {
it('opens the todo url', done => {
const todoLink = todoItem.dataset.url;
spyOnDependency(Todos, 'visitUrl').and.callFake(url => {
visitUrl.mockImplementation(url => {
expect(url).toEqual(todoLink);
done();
});
......@@ -39,14 +44,12 @@ describe('Todos', () => {
});
describe('meta click', () => {
let visitUrlSpy;
let windowOpenSpy;
let metakeyEvent;
beforeEach(() => {
metakeyEvent = $.Event('click', { keyCode: 91, ctrlKey: true });
visitUrlSpy = spyOnDependency(Todos, 'visitUrl').and.callFake(() => {});
windowOpenSpy = spyOn(window, 'open').and.callFake(() => {});
windowOpenSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
});
it('opens the todo url in another tab', () => {
......@@ -54,7 +57,7 @@ describe('Todos', () => {
$('.todos-list .todo').trigger(metakeyEvent);
expect(visitUrlSpy).not.toHaveBeenCalled();
expect(visitUrl).not.toHaveBeenCalled();
expect(windowOpenSpy).toHaveBeenCalledWith(todoLink, '_blank');
});
......@@ -62,7 +65,7 @@ describe('Todos', () => {
$('.todos-list a').on('click', e => e.preventDefault());
$('.todos-list img').trigger(metakeyEvent);
expect(visitUrlSpy).not.toHaveBeenCalled();
expect(visitUrl).not.toHaveBeenCalled();
expect(windowOpenSpy).not.toHaveBeenCalled();
});
});
......@@ -78,7 +81,7 @@ describe('Todos', () => {
mock
.onDelete(path)
.replyOnce(200, { count: TEST_COUNT_BIG, done_count: TEST_DONE_COUNT_BIG });
onToggleSpy = jasmine.createSpy('onToggle');
onToggleSpy = jest.fn();
$(document).on('todo:toggle', onToggleSpy);
// Act
......@@ -89,7 +92,7 @@ describe('Todos', () => {
});
it('dispatches todo:toggle', () => {
expect(onToggleSpy).toHaveBeenCalledWith(jasmine.anything(), TEST_COUNT_BIG);
expect(onToggleSpy).toHaveBeenCalledWith(expect.anything(), TEST_COUNT_BIG);
});
it('updates pending text', () => {
......
......@@ -2,6 +2,9 @@ import AccessorUtilities from '~/lib/utils/accessor';
import SigninTabsMemoizer from '~/pages/sessions/new/signin_tabs_memoizer';
import trackData from '~/pages/sessions/new/index';
import Tracking from '~/tracking';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
useLocalStorageSpy();
describe('SigninTabsMemoizer', () => {
const fixtureTemplate = 'static/signin_tabs.html';
......@@ -22,7 +25,7 @@ describe('SigninTabsMemoizer', () => {
beforeEach(() => {
loadFixtures(fixtureTemplate);
spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').and.returnValue(true);
jest.spyOn(AccessorUtilities, 'isLocalStorageAccessSafe').mockReturnValue(true);
});
it('does nothing if no tab was previously selected', () => {
......@@ -38,8 +41,8 @@ describe('SigninTabsMemoizer', () => {
const fakeTab = {
click: () => {},
};
spyOn(document, 'querySelector').and.returnValue(fakeTab);
spyOn(fakeTab, 'click');
jest.spyOn(document, 'querySelector').mockReturnValue(fakeTab);
jest.spyOn(fakeTab, 'click').mockImplementation(() => {});
memo.bootstrap();
......@@ -51,17 +54,18 @@ describe('SigninTabsMemoizer', () => {
it('clicks the first tab if value in local storage is bad', () => {
createMemoizer().saveData('#bogus');
const fakeTab = {
click: () => {},
click: jest.fn().mockName('fakeTab_click'),
};
spyOn(document, 'querySelector').and.callFake(selector =>
selector === `${tabSelector} a[href="#bogus"]` ? null : fakeTab,
);
spyOn(fakeTab, 'click');
jest
.spyOn(document, 'querySelector')
.mockImplementation(selector =>
selector === `${tabSelector} a[href="#bogus"]` ? null : fakeTab,
);
memo.bootstrap();
// verify that triggers click on stored selector and fallback
expect(document.querySelector.calls.allArgs()).toEqual([
expect(document.querySelector.mock.calls).toEqual([
['ul.new-session-tabs a[href="#bogus"]'],
['ul.new-session-tabs a'],
]);
......@@ -97,7 +101,7 @@ describe('SigninTabsMemoizer', () => {
describe('trackData', () => {
beforeEach(() => {
spyOn(Tracking, 'event');
jest.spyOn(Tracking, 'event').mockImplementation(() => {});
});
describe('with tracking data', () => {
......@@ -144,12 +148,10 @@ describe('SigninTabsMemoizer', () => {
memo = {
currentTabKey,
};
spyOn(localStorage, 'setItem');
});
describe('if .isLocalStorageAvailable is `false`', () => {
beforeEach(function() {
beforeEach(() => {
memo.isLocalStorageAvailable = false;
SigninTabsMemoizer.prototype.saveData.call(memo);
......@@ -163,7 +165,7 @@ describe('SigninTabsMemoizer', () => {
describe('if .isLocalStorageAvailable is `true`', () => {
const value = 'value';
beforeEach(function() {
beforeEach(() => {
memo.isLocalStorageAvailable = true;
SigninTabsMemoizer.prototype.saveData.call(memo, value);
......@@ -184,11 +186,11 @@ describe('SigninTabsMemoizer', () => {
currentTabKey,
};
spyOn(localStorage, 'getItem').and.returnValue(itemValue);
localStorage.getItem.mockReturnValue(itemValue);
});
describe('if .isLocalStorageAvailable is `false`', () => {
beforeEach(function() {
beforeEach(() => {
memo.isLocalStorageAvailable = false;
readData = SigninTabsMemoizer.prototype.readData.call(memo);
......@@ -201,7 +203,7 @@ describe('SigninTabsMemoizer', () => {
});
describe('if .isLocalStorageAvailable is `true`', () => {
beforeEach(function() {
beforeEach(() => {
memo.isLocalStorageAvailable = true;
readData = SigninTabsMemoizer.prototype.readData.call(memo);
......
import MockAdapter from 'axios-mock-adapter';
import setTimeoutPromise from 'spec/helpers/set_timeout_promise_helper';
import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import PersistentUserCallout from '~/persistent_user_callout';
import Flash from '~/flash';
jest.mock('~/flash');
describe('PersistentUserCallout', () => {
const dismissEndpoint = '/dismiss';
......@@ -51,44 +54,35 @@ describe('PersistentUserCallout', () => {
button = fixture.querySelector('.js-close');
mockAxios = new MockAdapter(axios);
persistentUserCallout = new PersistentUserCallout(container);
spyOn(persistentUserCallout.container, 'remove');
jest.spyOn(persistentUserCallout.container, 'remove').mockImplementation(() => {});
});
afterEach(() => {
mockAxios.restore();
});
it('POSTs endpoint and removes container when clicking close', done => {
it('POSTs endpoint and removes container when clicking close', () => {
mockAxios.onPost(dismissEndpoint).replyOnce(200);
button.click();
setTimeoutPromise()
.then(() => {
expect(persistentUserCallout.container.remove).toHaveBeenCalled();
expect(mockAxios.history.post[0].data).toBe(
JSON.stringify({ feature_name: featureName }),
);
})
.then(done)
.catch(done.fail);
return waitForPromises().then(() => {
expect(persistentUserCallout.container.remove).toHaveBeenCalled();
expect(mockAxios.history.post[0].data).toBe(JSON.stringify({ feature_name: featureName }));
});
});
it('invokes Flash when the dismiss request fails', done => {
const Flash = spyOnDependency(PersistentUserCallout, 'Flash');
it('invokes Flash when the dismiss request fails', () => {
mockAxios.onPost(dismissEndpoint).replyOnce(500);
button.click();
setTimeoutPromise()
.then(() => {
expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
expect(Flash).toHaveBeenCalledWith(
'An error occurred while dismissing the alert. Refresh the page and try again.',
);
})
.then(done)
.catch(done.fail);
return waitForPromises().then(() => {
expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
expect(Flash).toHaveBeenCalledWith(
'An error occurred while dismissing the alert. Refresh the page and try again.',
);
});
});
});
......@@ -108,56 +102,45 @@ describe('PersistentUserCallout', () => {
normalLink = fixture.querySelector('.normal-link');
mockAxios = new MockAdapter(axios);
persistentUserCallout = new PersistentUserCallout(container);
spyOn(persistentUserCallout.container, 'remove');
windowSpy = spyOn(window, 'open').and.callFake(() => {});
jest.spyOn(persistentUserCallout.container, 'remove').mockImplementation(() => {});
windowSpy = jest.spyOn(window, 'open').mockImplementation(() => {});
});
afterEach(() => {
mockAxios.restore();
});
it('defers loading of a link until callout is dismissed', done => {
it('defers loading of a link until callout is dismissed', () => {
const { href, target } = deferredLink;
mockAxios.onPost(dismissEndpoint).replyOnce(200);
deferredLink.click();
setTimeoutPromise()
.then(() => {
expect(windowSpy).toHaveBeenCalledWith(href, target);
expect(persistentUserCallout.container.remove).toHaveBeenCalled();
expect(mockAxios.history.post[0].data).toBe(
JSON.stringify({ feature_name: featureName }),
);
})
.then(done)
.catch(done.fail);
return waitForPromises().then(() => {
expect(windowSpy).toHaveBeenCalledWith(href, target);
expect(persistentUserCallout.container.remove).toHaveBeenCalled();
expect(mockAxios.history.post[0].data).toBe(JSON.stringify({ feature_name: featureName }));
});
});
it('does not dismiss callout on non-deferred links', done => {
it('does not dismiss callout on non-deferred links', () => {
normalLink.click();
setTimeoutPromise()
.then(() => {
expect(windowSpy).not.toHaveBeenCalled();
expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
return waitForPromises().then(() => {
expect(windowSpy).not.toHaveBeenCalled();
expect(persistentUserCallout.container.remove).not.toHaveBeenCalled();
});
});
it('does not follow link when notification is closed', done => {
it('does not follow link when notification is closed', () => {
mockAxios.onPost(dismissEndpoint).replyOnce(200);
button.click();
setTimeoutPromise()
.then(() => {
expect(windowSpy).not.toHaveBeenCalled();
expect(persistentUserCallout.container.remove).toHaveBeenCalled();
})
.then(done)
.catch(done.fail);
return waitForPromises().then(() => {
expect(windowSpy).not.toHaveBeenCalled();
expect(persistentUserCallout.container.remove).toHaveBeenCalled();
});
});
});
......
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