Commit 4d1389e6 authored by Lukas Eipert's avatar Lukas Eipert

Add a helper to spy on window.location

The window.location interface is read only in newer versions of jest.
This breaks our manual mocks / spys on that interface.

With a helper which replaces `window.location` with a mocked interface
we are able to circumvent that problem.
parent 5383adc7
import testAction from 'helpers/vuex_action_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash';
......@@ -628,13 +629,13 @@ describe('Subscriptions Actions', () => {
});
describe('confirmOrderSuccess', () => {
useMockLocationHelper();
const params = { location: 'http://example.com', plan_id: 'x', quantity: 10 };
it('changes the window location', done => {
const spy = jest.spyOn(window.location, 'assign').mockImplementation();
testAction(actions.confirmOrderSuccess, params, {}, [], [], () => {
expect(spy).toHaveBeenCalledWith('http://example.com');
expect(window.location.assign).toHaveBeenCalledWith('http://example.com');
done();
});
});
......
import testAction from 'helpers/vuex_action_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import MockAdapter from 'axios-mock-adapter';
import createState from '~/create_cluster/eks_cluster/store/state';
import * as actions from '~/create_cluster/eks_cluster/store/actions';
......@@ -251,12 +252,7 @@ describe('EKS Cluster Store Actions', () => {
});
describe('createClusterSuccess', () => {
beforeEach(() => {
jest.spyOn(window.location, 'assign').mockImplementation(() => {});
});
afterEach(() => {
window.location.assign.mockRestore();
});
useMockLocationHelper();
it('redirects to the new cluster URL', () => {
actions.createClusterSuccess(null, newClusterUrl);
......
/**
* Manage the instance of a custom `window.location`
*
* This only encapsulates the setup / teardown logic so that it can easily be
* reused with different implementations (i.e. a spy or a [fake][1])
*
* [1]: https://stackoverflow.com/a/41434763/1708147
*
* @param {() => any} fn Function that returns the object to use for window.location
*/
const useMockLocation = fn => {
const origWindowLocation = window.location;
let currentWindowLocation;
Object.defineProperty(window, 'location', {
get: () => currentWindowLocation,
});
beforeEach(() => {
currentWindowLocation = fn();
});
afterEach(() => {
currentWindowLocation = origWindowLocation;
});
};
/**
* Create an object with the location interface but `jest.fn()` implementations.
*/
export const createWindowLocationSpy = () => {
return {
assign: jest.fn(),
reload: jest.fn(),
replace: jest.fn(),
toString: jest.fn(),
};
};
/**
* Before each test, overwrite `window.location` with a spy implementation.
*/
export const useMockLocationHelper = () => useMockLocation(createWindowLocationSpy);
......@@ -33,7 +33,7 @@ describe('setWindowLocation', () => {
it.each([null, 1, undefined, false, '', 'gitlab.com'])(
'throws an error when called with an invalid url: "%s"',
invalidUrl => {
expect(() => setWindowLocation(invalidUrl)).toThrow(new TypeError('Invalid URL'));
expect(() => setWindowLocation(invalidUrl)).toThrow(/Invalid URL/);
expect(window.location).toBe(originalLocation);
},
);
......
......@@ -12,7 +12,8 @@ import {
} from '~/ide/stores/actions';
import service from '~/ide/services';
import api from '~/api';
import testAction from '../../../helpers/vuex_action_helper';
import testAction from 'helpers/vuex_action_helper';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
const TEST_PROJECT_ID = 'abc/def';
......@@ -116,6 +117,8 @@ describe('IDE store project actions', () => {
});
describe('createNewBranchFromDefault', () => {
useMockLocationHelper();
beforeEach(() => {
jest.spyOn(api, 'createBranch').mockResolvedValue();
});
......@@ -170,8 +173,6 @@ describe('IDE store project actions', () => {
});
it('reloads window', done => {
jest.spyOn(window.location, 'reload').mockImplementation();
createNewBranchFromDefault(
{
state: {
......
......@@ -6,11 +6,14 @@ import SidebarService from '~/sidebar/services/sidebar_service';
import createFlash from '~/flash';
import RecaptchaModal from '~/vue_shared/components/recaptcha_modal.vue';
import createStore from '~/notes/stores';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
jest.mock('~/flash');
jest.mock('~/sidebar/services/sidebar_service');
describe('Confidential Issue Sidebar Block', () => {
useMockLocationHelper();
let wrapper;
const findRecaptchaModal = () => wrapper.find(RecaptchaModal);
......@@ -43,10 +46,6 @@ describe('Confidential Issue Sidebar Block', () => {
});
};
beforeEach(() => {
jest.spyOn(window.location, 'reload').mockImplementation();
});
afterEach(() => {
wrapper.destroy();
});
......
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