Commit f92ff8a0 authored by Lukas Eipert's avatar Lukas Eipert Committed by Ezekiel Kigbo

Stop exposing Flash on window Object

Adding APIs to the window object is problematic due to side effects and
needing to make sure that the API is loaded. It makes it harder to
reason about where a file is used and how to refactor it.

This moves the remaining window.Flash usages to direct imports.
parent a4925e7d
/* global createFlash */
import $ from 'jquery';
import createFlash from './flash';
import axios from './lib/utils/axios_utils';
import { n__, s__ } from './locale';
......
......@@ -133,4 +133,3 @@ export {
removeFlashClickListener,
FLASH_TYPES,
};
window.Flash = createFlash;
import $ from 'jquery';
import { escape } from 'lodash';
import initDeprecatedJQueryDropdown from '~/deprecated_jquery_dropdown';
import createFlash from '~/flash';
import { __ } from '~/locale';
function isValidProjectId(id) {
......@@ -42,8 +43,10 @@ class SidebarMoveIssue {
this.mediator
.fetchAutocompleteProjects(searchTerm)
.then(callback)
.catch(
() => new window.Flash(__('An error occurred while fetching projects autocomplete.')),
.catch(() =>
createFlash({
message: __('An error occurred while fetching projects autocomplete.'),
}),
);
},
renderRow: (project) => `
......@@ -76,7 +79,7 @@ class SidebarMoveIssue {
this.$confirmButton.disable().addClass('is-loading');
this.mediator.moveIssue().catch(() => {
window.Flash(__('An error occurred while moving the issue.'));
createFlash({ message: __('An error occurred while moving the issue.') });
this.$confirmButton.enable().removeClass('is-loading');
});
}
......
......@@ -8,10 +8,12 @@ import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered
import RecentSearchesRoot from '~/filtered_search/recent_searches_root';
import RecentSearchesService from '~/filtered_search/services/recent_searches_service';
import RecentSearchesServiceError from '~/filtered_search/services/recent_searches_service_error';
import createFlash from '~/flash';
import * as commonUtils from '~/lib/utils/common_utils';
import { BACKSPACE_KEY_CODE, DELETE_KEY_CODE } from '~/lib/utils/keycodes';
import { visitUrl } from '~/lib/utils/url_utility';
jest.mock('~/flash');
jest.mock('~/lib/utils/url_utility', () => ({
...jest.requireActual('~/lib/utils/url_utility'),
visitUrl: jest.fn(),
......@@ -127,11 +129,10 @@ describe('Filtered Search Manager', () => {
jest
.spyOn(RecentSearchesService.prototype, 'fetch')
.mockImplementation(() => Promise.reject(new RecentSearchesServiceError()));
jest.spyOn(window, 'Flash').mockImplementation();
manager.setup();
expect(window.Flash).not.toHaveBeenCalled();
expect(createFlash).not.toHaveBeenCalled();
});
});
......
import { escape } from 'lodash';
import FilteredSearchSpecHelper from 'helpers/filtered_search_spec_helper';
import { TEST_HOST } from 'helpers/test_constants';
import DropdownUtils from '~/filtered_search//dropdown_utils';
import DropdownUtils from '~/filtered_search/dropdown_utils';
import VisualTokenValue from '~/filtered_search/visual_token_value';
import createFlash from '~/flash';
import AjaxCache from '~/lib/utils/ajax_cache';
import UsersCache from '~/lib/utils/users_cache';
jest.mock('~/flash');
describe('Filtered Search Visual Tokens', () => {
const findElements = (tokenElement) => {
const tokenNameElement = tokenElement.querySelector('.name');
......@@ -43,7 +46,6 @@ describe('Filtered Search Visual Tokens', () => {
});
it('ignores error if UsersCache throws', (done) => {
jest.spyOn(window, 'Flash').mockImplementation(() => {});
const dummyError = new Error('Earth rotated backwards');
const { subject, tokenValueContainer, tokenValueElement } = findElements(authorToken);
const tokenValue = tokenValueElement.innerText;
......@@ -55,7 +57,7 @@ describe('Filtered Search Visual Tokens', () => {
subject
.updateUserTokenAppearance(tokenValueContainer, tokenValueElement, tokenValue)
.then(() => {
expect(window.Flash.mock.calls.length).toBe(0);
expect(createFlash.mock.calls.length).toBe(0);
})
.then(done)
.catch(done.fail);
......
import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import createFlash from '~/flash';
import axios from '~/lib/utils/axios_utils';
import SidebarMoveIssue from '~/sidebar/lib/sidebar_move_issue';
import SidebarService from '~/sidebar/services/sidebar_service';
......@@ -7,6 +8,8 @@ import SidebarMediator from '~/sidebar/sidebar_mediator';
import SidebarStore from '~/sidebar/stores/sidebar_store';
import Mock from './mock_data';
jest.mock('~/flash');
describe('SidebarMoveIssue', () => {
let mock;
const test = {};
......@@ -99,7 +102,6 @@ describe('SidebarMoveIssue', () => {
});
it('should remove loading state from confirm button on failure', (done) => {
jest.spyOn(window, 'Flash').mockImplementation(() => {});
jest.spyOn(test.mediator, 'moveIssue').mockReturnValue(Promise.reject());
test.mediator.setMoveToProjectId(7);
......@@ -108,7 +110,7 @@ describe('SidebarMoveIssue', () => {
expect(test.mediator.moveIssue).toHaveBeenCalled();
// Wait for the move issue request to fail
setImmediate(() => {
expect(window.Flash).toHaveBeenCalled();
expect(createFlash).toHaveBeenCalled();
expect(test.$confirmButton.prop('disabled')).toBeFalsy();
expect(test.$confirmButton.hasClass('is-loading')).toBe(false);
done();
......
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