diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-26 12:11:43 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-10-26 12:11:43 +0000 |
commit | c15582526dd15f5ea8fac0906624cc5cd2db03ab (patch) | |
tree | bb29128600d8df3a2d5730c8cd233342d06da562 /spec/frontend | |
parent | 51c18a25f2751911e134e73dbc946ee130fc6487 (diff) | |
download | gitlab-ce-c15582526dd15f5ea8fac0906624cc5cd2db03ab.tar.gz |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
6 files changed, 187 insertions, 20 deletions
diff --git a/spec/frontend/environments/environment_actions_spec.js b/spec/frontend/environments/environment_actions_spec.js index 68895b194a1..48483152f7a 100644 --- a/spec/frontend/environments/environment_actions_spec.js +++ b/spec/frontend/environments/environment_actions_spec.js @@ -10,11 +10,7 @@ import actionMutation from '~/environments/graphql/mutations/action.mutation.gra import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; import createMockApollo from 'helpers/mock_apollo_helper'; -jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal', () => { - return { - confirmAction: jest.fn(), - }; -}); +jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'); const scheduledJobAction = { name: 'scheduled action', diff --git a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_action_spec.js b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_action_spec.js new file mode 100644 index 00000000000..142c76f7bc0 --- /dev/null +++ b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_action_spec.js @@ -0,0 +1,103 @@ +import Vue, { nextTick } from 'vue'; +import { createWrapper } from '@vue/test-utils'; +import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; +import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; +import ConfirmModal from '~/lib/utils/confirm_via_gl_modal/confirm_modal.vue'; + +const originalMount = Vue.prototype.$mount; + +describe('confirmAction', () => { + let modalWrapper; + let confirActionPromise; + let modal; + + const findConfirmModal = () => modalWrapper.findComponent(ConfirmModal); + const renderRootComponent = async (message, opts) => { + confirActionPromise = confirmAction(message, opts); + // We have to wait for two ticks here. + // The first one is to wait for rendering of the root component + // The second one to wait for rendering of the dynamically + // loaded confirm-modal component + await nextTick(); + await nextTick(); + modal = findConfirmModal(); + }; + const mockMount = (vm, el) => { + originalMount.call(vm, el); + modalWrapper = createWrapper(vm); + return vm; + }; + + beforeEach(() => { + setHTMLFixture('<div id="component"></div>'); + const el = document.getElementById('component'); + // We mock the implementation only once to make sure that we mock + // it only for the root component in confirm_action. + // Mounting other components (like confirm-modal) should not be affected with + // this mock + jest.spyOn(Vue.prototype, '$mount').mockImplementationOnce(function mock() { + return mockMount(this, el); + }); + }); + + afterEach(() => { + resetHTMLFixture(); + Vue.prototype.$mount.mockRestore(); + modalWrapper?.destroy(); + modalWrapper = null; + modal?.destroy(); + modal = null; + }); + + it('creats a ConfirmModal with message as slot', async () => { + const message = 'Bonjour le monde!'; + await renderRootComponent(message); + + expect(modal.vm.$slots.default[0].text).toBe(message); + }); + + it('creats a ConfirmModal with props', async () => { + const options = { + primaryBtnText: 'primaryBtnText', + primaryBtnVariant: 'info', + secondaryBtnText: 'secondaryBtnText', + secondaryBtnVariant: 'success', + cancelBtnText: 'cancelBtnText', + cancelBtnVariant: 'danger', + modalHtmlMessage: '<strong>Hello</strong>', + title: 'title', + hideCancel: true, + }; + await renderRootComponent('', options); + expect(modal.props()).toEqual( + expect.objectContaining({ + primaryText: options.primaryBtnText, + primaryVariant: options.primaryBtnVariant, + secondaryText: options.secondaryBtnText, + secondaryVariant: options.secondaryBtnVariant, + cancelText: options.cancelBtnText, + cancelVariant: options.cancelBtnVariant, + modalHtmlMessage: options.modalHtmlMessage, + title: options.title, + hideCancel: options.hideCancel, + }), + ); + }); + + it('resolves promise when modal emit `closed`', async () => { + await renderRootComponent(''); + + modal.vm.$emit('closed'); + + await expect(confirActionPromise).resolves.toBe(false); + }); + + it('confirms when modal emit `confirmed` before `closed`', async () => { + await renderRootComponent(''); + + modal.vm.$emit('confirmed'); + modal.vm.$emit('closed'); + + await expect(confirActionPromise).resolves.toBe(true); + }); +}); diff --git a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal_spec.js b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal_spec.js new file mode 100644 index 00000000000..6966c79b232 --- /dev/null +++ b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal_spec.js @@ -0,0 +1,80 @@ +import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; +import { confirmViaGlModal } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; +import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_action'; + +jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_action'); + +describe('confirmViaGlModal', () => { + let el; + + afterEach(() => { + el = undefined; + resetHTMLFixture(); + jest.resetAllMocks(); + }); + + const createElement = (html) => { + setHTMLFixture(html); + return document.body.firstChild; + }; + + it('returns confirmAction result', async () => { + confirmAction.mockReturnValue(Promise.resolve(true)); + el = createElement(`<div/>`); + + await expect(confirmViaGlModal('', el)).resolves.toBe(true); + }); + + it('calls confirmAction with message', () => { + el = createElement(`<div/>`); + + confirmViaGlModal('message', el); + + expect(confirmAction).toHaveBeenCalledWith('message', {}); + }); + + it.each(['gl-sr-only', 'sr-only'])( + `uses slot.%s contentText as primaryBtnText`, + (srOnlyClass) => { + el = createElement( + `<a href="#"><span class="${srOnlyClass}">Delete merge request</span></a>`, + ); + + confirmViaGlModal('', el); + + expect(confirmAction).toHaveBeenCalledWith('', { + primaryBtnText: 'Delete merge request', + }); + }, + ); + + it('uses `aria-label` value as `primaryBtnText`', () => { + el = createElement(`<a aria-label="Delete merge request" href="#"></a>`); + + confirmViaGlModal('', el); + + expect(confirmAction).toHaveBeenCalledWith('', { + primaryBtnText: 'Delete merge request', + }); + }); + + it.each([ + ['title', 'title', 'Delete?'], + ['confirm-btn-variant', `primaryBtnVariant`, 'danger'], + ])('uses data-%s value as confirmAction config', (dataKey, configKey, value) => { + el = createElement(`<a data-${dataKey}="${value}" href="#"></a>`); + + confirmViaGlModal('message', el); + + expect(confirmAction).toHaveBeenCalledWith('message', { [configKey]: value }); + }); + + it('uses message as modalHtmlMessage value when data-is-html-message is true', () => { + el = createElement(`<a data-is-html-message="true" href="#"></a>`); + const message = 'Hola mundo!'; + + confirmViaGlModal(message, el); + + expect(confirmAction).toHaveBeenCalledWith(message, { modalHtmlMessage: message }); + }); +}); diff --git a/spec/frontend/pipelines/pipelines_actions_spec.js b/spec/frontend/pipelines/pipelines_actions_spec.js index 26e61efc4f6..a70ef10aa7b 100644 --- a/spec/frontend/pipelines/pipelines_actions_spec.js +++ b/spec/frontend/pipelines/pipelines_actions_spec.js @@ -13,11 +13,7 @@ import GlCountdown from '~/vue_shared/components/gl_countdown.vue'; import { TRACKING_CATEGORIES } from '~/pipelines/constants'; jest.mock('~/flash'); -jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal', () => { - return { - confirmAction: jest.fn(), - }; -}); +jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'); describe('Pipelines Actions dropdown', () => { let wrapper; diff --git a/spec/frontend/vue_merge_request_widget/deployment/deployment_actions_spec.js b/spec/frontend/vue_merge_request_widget/deployment/deployment_actions_spec.js index 58dadb2c679..41df485b0de 100644 --- a/spec/frontend/vue_merge_request_widget/deployment/deployment_actions_spec.js +++ b/spec/frontend/vue_merge_request_widget/deployment/deployment_actions_spec.js @@ -23,11 +23,7 @@ import { jest.mock('~/flash'); jest.mock('~/lib/utils/url_utility'); -jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal', () => { - return { - confirmAction: jest.fn(), - }; -}); +jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'); describe('DeploymentAction component', () => { let wrapper; diff --git a/spec/frontend/work_items/components/work_item_description_spec.js b/spec/frontend/work_items/components/work_item_description_spec.js index 0691fe25e0d..4a9978bbadf 100644 --- a/spec/frontend/work_items/components/work_item_description_spec.js +++ b/spec/frontend/work_items/components/work_item_description_spec.js @@ -18,11 +18,7 @@ import { workItemQueryResponse, } from '../mock_data'; -jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal', () => { - return { - confirmAction: jest.fn(), - }; -}); +jest.mock('~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'); jest.mock('~/lib/utils/autosave'); const workItemId = workItemQueryResponse.data.workItem.id; |