From b678d445835befcba9a6d7afa6abf37aba570a6d Mon Sep 17 00:00:00 2001 From: wortschi <mwortschack@gitlab.com> Date: Thu, 10 Feb 2022 08:13:53 +0100 Subject: [PATCH] Replace window.confirm with GlModa in deployment actions Changelog: changed --- .../deployment/deployment_actions.vue | 20 +++++- .../user_sees_deployment_widget_spec.rb | 6 +- .../deployment/deployment_actions_spec.js | 64 ++++++++++++------- .../deployment/deployment_mock_data.js | 3 + 4 files changed, 68 insertions(+), 25 deletions(-) diff --git a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue index 5ef7c2f72e034..7ba387c79b1d9 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/deployment/deployment_actions.vue @@ -1,5 +1,6 @@ <script> import createFlash from '~/flash'; +import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; import { visitUrl } from '~/lib/utils/url_utility'; import { __, s__ } from '~/locale'; import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; @@ -79,6 +80,7 @@ export default { [STOPPING]: { actionName: STOPPING, buttonText: s__('MrDeploymentActions|Stop environment'), + buttonVariant: 'danger', busyText: __('This environment is being deployed'), confirmMessage: __('Are you sure you want to stop this environment?'), errorMessage: __('Something went wrong while stopping this environment. Please try again.'), @@ -86,6 +88,7 @@ export default { [DEPLOYING]: { actionName: DEPLOYING, buttonText: s__('MrDeploymentActions|Deploy'), + buttonVariant: 'confirm', busyText: __('This environment is being deployed'), confirmMessage: __('Are you sure you want to deploy this environment?'), errorMessage: __('Something went wrong while deploying this environment. Please try again.'), @@ -93,14 +96,27 @@ export default { [REDEPLOYING]: { actionName: REDEPLOYING, buttonText: s__('MrDeploymentActions|Re-deploy'), + buttonVariant: 'confirm', busyText: __('This environment is being re-deployed'), confirmMessage: __('Are you sure you want to re-deploy this environment?'), errorMessage: __('Something went wrong while deploying this environment. Please try again.'), }, }, methods: { - executeAction(endpoint, { actionName, confirmMessage, errorMessage }) { - const isConfirmed = confirm(confirmMessage); //eslint-disable-line + async executeAction( + endpoint, + { + actionName, + buttonText: primaryBtnText, + buttonVariant: primaryBtnVariant, + confirmMessage, + errorMessage, + }, + ) { + const isConfirmed = await confirmAction(confirmMessage, { + primaryBtnVariant, + primaryBtnText, + }); if (isConfirmed) { this.actionInProgress = actionName; diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb index 345404cc28f40..01cc58777ba75 100644 --- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb +++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' RSpec.describe 'Merge request > User sees deployment widget', :js do + include Spec::Support::Helpers::ModalHelpers + describe 'when merge request has associated environments' do let(:user) { create(:user) } let(:project) { create(:project, :repository) } @@ -118,7 +120,9 @@ end it 'does start build when stop button clicked' do - accept_confirm { find('.js-stop-env').click } + accept_gl_confirm(button_text: 'Stop environment') do + find('.js-stop-env').click + end expect(page).to have_content('close_app') end diff --git a/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js b/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js index 31ade17e50a61..a285d26f4046e 100644 --- a/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js +++ b/spec/frontend/vue_mr_widget/deployment/deployment_actions_spec.js @@ -1,5 +1,7 @@ import { mount } from '@vue/test-utils'; +import waitForPromises from 'helpers/wait_for_promises'; import createFlash from '~/flash'; +import { confirmAction } from '~/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal'; import { visitUrl } from '~/lib/utils/url_utility'; import { CREATED, @@ -20,6 +22,11 @@ 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(), + }; +}); describe('DeploymentAction component', () => { let wrapper; @@ -51,6 +58,7 @@ describe('DeploymentAction component', () => { afterEach(() => { wrapper.destroy(); + confirmAction.mockReset(); }); describe('actions do not appear when conditions are unmet', () => { @@ -95,16 +103,6 @@ describe('DeploymentAction component', () => { '$configConst action', ({ configConst, computedDeploymentStatus, displayConditionChanges, finderFn, endpoint }) => { describe(`${configConst} action`, () => { - const confirmAction = () => { - jest.spyOn(window, 'confirm').mockReturnValueOnce(true); - finderFn().trigger('click'); - }; - - const rejectAction = () => { - jest.spyOn(window, 'confirm').mockReturnValueOnce(false); - finderFn().trigger('click'); - }; - beforeEach(() => { factory({ propsData: { @@ -125,13 +123,18 @@ describe('DeploymentAction component', () => { describe('should show a confirm dialog but not call executeInlineAction when declined', () => { beforeEach(() => { executeActionSpy.mockResolvedValueOnce(); - rejectAction(); + confirmAction.mockResolvedValueOnce(false); + finderFn().trigger('click'); }); it('should show the confirm dialog', () => { - expect(window.confirm).toHaveBeenCalled(); - expect(window.confirm).toHaveBeenCalledWith( + expect(confirmAction).toHaveBeenCalled(); + expect(confirmAction).toHaveBeenCalledWith( actionButtonMocks[configConst].confirmMessage, + { + primaryBtnVariant: actionButtonMocks[configConst].buttonVariant, + primaryBtnText: actionButtonMocks[configConst].buttonText, + }, ); }); @@ -143,13 +146,18 @@ describe('DeploymentAction component', () => { describe('should show a confirm dialog and call executeInlineAction when accepted', () => { beforeEach(() => { executeActionSpy.mockResolvedValueOnce(); - confirmAction(); + confirmAction.mockResolvedValueOnce(true); + finderFn().trigger('click'); }); it('should show the confirm dialog', () => { - expect(window.confirm).toHaveBeenCalled(); - expect(window.confirm).toHaveBeenCalledWith( + expect(confirmAction).toHaveBeenCalled(); + expect(confirmAction).toHaveBeenCalledWith( actionButtonMocks[configConst].confirmMessage, + { + primaryBtnVariant: actionButtonMocks[configConst].buttonVariant, + primaryBtnText: actionButtonMocks[configConst].buttonText, + }, ); }); @@ -164,11 +172,15 @@ describe('DeploymentAction component', () => { describe('response includes redirect_url', () => { const url = '/root/example'; - beforeEach(() => { + beforeEach(async () => { executeActionSpy.mockResolvedValueOnce({ data: { redirect_url: url }, }); - confirmAction(); + + await waitForPromises(); + + confirmAction.mockResolvedValueOnce(true); + finderFn().trigger('click'); }); it('calls visit url with the redirect_url', () => { @@ -178,9 +190,13 @@ describe('DeploymentAction component', () => { }); describe('it should call the executeAction method ', () => { - beforeEach(() => { + beforeEach(async () => { jest.spyOn(wrapper.vm, 'executeAction').mockImplementation(); - confirmAction(); + + await waitForPromises(); + + confirmAction.mockResolvedValueOnce(true); + finderFn().trigger('click'); }); it('calls with the expected arguments', () => { @@ -193,9 +209,13 @@ describe('DeploymentAction component', () => { }); describe('when executeInlineAction errors', () => { - beforeEach(() => { + beforeEach(async () => { executeActionSpy.mockRejectedValueOnce(); - confirmAction(); + + await waitForPromises(); + + confirmAction.mockResolvedValueOnce(true); + finderFn().trigger('click'); }); it('should call createFlash with error message', () => { diff --git a/spec/frontend/vue_mr_widget/deployment/deployment_mock_data.js b/spec/frontend/vue_mr_widget/deployment/deployment_mock_data.js index 2083dc8868161..e98b1160ae48a 100644 --- a/spec/frontend/vue_mr_widget/deployment/deployment_mock_data.js +++ b/spec/frontend/vue_mr_widget/deployment/deployment_mock_data.js @@ -9,6 +9,7 @@ const actionButtonMocks = { [STOPPING]: { actionName: STOPPING, buttonText: 'Stop environment', + buttonVariant: 'danger', busyText: 'This environment is being deployed', confirmMessage: 'Are you sure you want to stop this environment?', errorMessage: 'Something went wrong while stopping this environment. Please try again.', @@ -16,6 +17,7 @@ const actionButtonMocks = { [DEPLOYING]: { actionName: DEPLOYING, buttonText: 'Deploy', + buttonVariant: 'confirm', busyText: 'This environment is being deployed', confirmMessage: 'Are you sure you want to deploy this environment?', errorMessage: 'Something went wrong while deploying this environment. Please try again.', @@ -23,6 +25,7 @@ const actionButtonMocks = { [REDEPLOYING]: { actionName: REDEPLOYING, buttonText: 'Re-deploy', + buttonVariant: 'confirm', busyText: 'This environment is being re-deployed', confirmMessage: 'Are you sure you want to re-deploy this environment?', errorMessage: 'Something went wrong while deploying this environment. Please try again.', -- GitLab