diff --git a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue new file mode 100644 index 0000000000000000000000000000000000000000..733d0f69f5d855b65a06134f410ea72d38916ccc --- /dev/null +++ b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_modal.vue @@ -0,0 +1,47 @@ + + + diff --git a/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js new file mode 100644 index 0000000000000000000000000000000000000000..f0908a60ac53d535869e407bb84474d111ae622d --- /dev/null +++ b/app/assets/javascripts/lib/utils/confirm_via_gl_modal/confirm_via_gl_modal.js @@ -0,0 +1,47 @@ +import Vue from 'vue'; + +export function confirmViaGlModal(message, element) { + return new Promise((resolve) => { + let confirmed = false; + + const props = {}; + + const confirmBtnVariant = element.getAttribute('data-confirm-btn-variant'); + + if (confirmBtnVariant) { + props.primaryVariant = confirmBtnVariant; + } + const screenReaderText = + element.querySelector('.gl-sr-only')?.textContent || + element.querySelector('.sr-only')?.textContent || + element.getAttribute('aria-label'); + + if (screenReaderText) { + props.primaryText = screenReaderText; + } + + const component = new Vue({ + components: { + ConfirmModal: () => import('./confirm_modal.vue'), + }, + render(h) { + return h( + 'confirm-modal', + { + props, + on: { + confirmed() { + confirmed = true; + }, + closed() { + component.$destroy(); + resolve(confirmed); + }, + }, + }, + [message], + ); + }, + }).$mount(); + }); +} diff --git a/app/assets/javascripts/lib/utils/rails_ujs.js b/app/assets/javascripts/lib/utils/rails_ujs.js index 8b40cc7bd111690bc38a33e2ae92e5a9af6bf455..6b1985a23baa4ac6ffb52208fdd1ffffd7fe8e3b 100644 --- a/app/assets/javascripts/lib/utils/rails_ujs.js +++ b/app/assets/javascripts/lib/utils/rails_ujs.js @@ -1,4 +1,42 @@ import Rails from '@rails/ujs'; +import { confirmViaGlModal } from './confirm_via_gl_modal/confirm_via_gl_modal'; + +function monkeyPatchConfirmModal() { + /** + * This function is used to replace the `Rails.confirm` which uses `window.confirm` + * + * This function opens a confirmation modal which will resolve in a promise. + * Because the `Rails.confirm` API is synchronous, we go with a little hack here: + * + * 1. User clicks on something with `data-confirm` + * 2. We open the modal and return `false`, ending the "Rails" event chain + * 3. If the modal is closed and the user "confirmed" the action + * 1. replace the `Rails.confirm` with a function that always returns `true` + * 2. click the same element programmatically + * + * @param message {String} Message to be shown in the modal + * @param element {HTMLElement} Element that was clicked on + * @returns {boolean} + */ + function confirmViaModal(message, element) { + confirmViaGlModal(message, element) + .then((confirmed) => { + if (confirmed) { + Rails.confirm = () => true; + element.click(); + Rails.confirm = confirmViaModal; + } + }) + .catch(() => {}); + return false; + } + + Rails.confirm = confirmViaModal; +} + +if (gon?.features?.bootstrapConfirmationModals) { + monkeyPatchConfirmModal(); +} export const initRails = () => { // eslint-disable-next-line no-underscore-dangle diff --git a/config/feature_flags/development/bootstrap_confirmation_modals.yml b/config/feature_flags/development/bootstrap_confirmation_modals.yml new file mode 100644 index 0000000000000000000000000000000000000000..e67fd03fea658c2a23d4ca6ebfcffa5d67e33950 --- /dev/null +++ b/config/feature_flags/development/bootstrap_confirmation_modals.yml @@ -0,0 +1,8 @@ +--- +name: bootstrap_confirmation_modals +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73167 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344658 +milestone: '14.5' +type: development +group: group::foundations +default_enabled: false diff --git a/ee/spec/features/admin/admin_settings_spec.rb b/ee/spec/features/admin/admin_settings_spec.rb index 70acb198c28e86c51c1a3007a68b13c11906de62..a772a4de3f2d4d3d9c1e15cc96e659b767045b53 100644 --- a/ee/spec/features/admin/admin_settings_spec.rb +++ b/ee/spec/features/admin/admin_settings_spec.rb @@ -6,6 +6,7 @@ include StubENV before do + stub_feature_flags(bootstrap_confirmation_modals: false) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') admin = create(:admin) sign_in(admin) diff --git a/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb b/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb index bc6c10101bd24309167cc0961bc9c1a598290bbb..c7bcdf1db0151e9e9aeca3b4021ea7d32a1b864e 100644 --- a/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb +++ b/ee/spec/features/admin/subscriptions/admin_views_subscription_spec.rb @@ -6,6 +6,7 @@ let_it_be(:admin) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) end diff --git a/ee/spec/features/epic_boards/epic_boards_spec.rb b/ee/spec/features/epic_boards/epic_boards_spec.rb index 227a7516611700789b33b563ade570599d5dcfc2..9c9e9fbb611d12f72a6c8064f1eba06b12575898 100644 --- a/ee/spec/features/epic_boards/epic_boards_spec.rb +++ b/ee/spec/features/epic_boards/epic_boards_spec.rb @@ -115,6 +115,8 @@ context 'lists' do let_it_be(:label_list2) { create(:epic_list, epic_board: epic_board, label: label2, position: 1) } + stub_feature_flags(bootstrap_confirmation_modals: false) + it 'changes position of list' do expect(find_board_list(2)).to have_content(label.title) expect(find_board_list(3)).to have_content(label2.title) diff --git a/ee/spec/features/groups/members/leave_group_spec.rb b/ee/spec/features/groups/members/leave_group_spec.rb index 4b2ccb0d2c5cf05bc35cf26426411799c27231c8..4b2a76e6d085d88a1bc16b00f18c3a456ba975e9 100644 --- a/ee/spec/features/groups/members/leave_group_spec.rb +++ b/ee/spec/features/groups/members/leave_group_spec.rb @@ -13,6 +13,7 @@ before do user.update!(provisioned_by_group: group) sign_in(user) + stub_feature_flags(bootstrap_confirmation_modals: false) end context 'with block_password_auth_for_saml_users feature flag switched on' do diff --git a/ee/spec/features/projects/path_locks_spec.rb b/ee/spec/features/projects/path_locks_spec.rb index 35c42ed7eedfb85c048bf701f302923508cc8b1a..60006abc568e4b30592825532327b6ddd62607e4 100644 --- a/ee/spec/features/projects/path_locks_spec.rb +++ b/ee/spec/features/projects/path_locks_spec.rb @@ -9,6 +9,7 @@ before do allow(project).to receive(:feature_available?).with(:file_locks) { true } + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) sign_in(user) diff --git a/ee/spec/features/projects/settings/protected_environments_spec.rb b/ee/spec/features/projects/settings/protected_environments_spec.rb index 08af51dbe7c4b5207bce315be91028c9f588408d..05d1f98b2cc2a80dd6f0af3d1b981c7acfe412a1 100644 --- a/ee/spec/features/projects/settings/protected_environments_spec.rb +++ b/ee/spec/features/projects/settings/protected_environments_spec.rb @@ -34,6 +34,7 @@ context 'logged in as a maintainer' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) visit project_settings_ci_cd_path(project) diff --git a/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb b/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb index 98431236cc890918d6191856edc4ca8df281eeda..9ad5f9b03eeb53d67297f4cd88bc92046a9ac962 100644 --- a/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb +++ b/ee/spec/support/shared_examples/features/protected_branches_access_control_shared_examples.rb @@ -173,6 +173,7 @@ def last_access_levels(git_operation) let!(:protected_branch) { create(:protected_branch, project: project) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) stub_licensed_features(unprotection_restrictions: true) end diff --git a/lib/gitlab/gon_helper.rb b/lib/gitlab/gon_helper.rb index 6faf3575bc1b927929a526c9cf6a01d3cfb33fc7..027551df15d0440bcd8d13042b11e1ede61482d1 100644 --- a/lib/gitlab/gon_helper.rb +++ b/lib/gitlab/gon_helper.rb @@ -58,6 +58,7 @@ def add_gon_variables push_frontend_feature_flag(:new_header_search, default_enabled: :yaml) push_frontend_feature_flag(:suppress_apollo_errors_during_navigation, current_user, default_enabled: :yaml) push_frontend_feature_flag(:configure_iac_scanning_via_mr, current_user, default_enabled: :yaml) + push_frontend_feature_flag(:bootstrap_confirmation_modals, default_enabled: :yaml) end # Exposes the state of a feature flag to the frontend code. diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb index 1f34c4ed17c6fbd798103de5436676bd9d39f018..f65e85b4cb62c6021b47af36285f17a941aeeaf1 100644 --- a/spec/features/admin/admin_disables_two_factor_spec.rb +++ b/spec/features/admin/admin_disables_two_factor_spec.rb @@ -4,6 +4,7 @@ RSpec.describe 'Admin disables 2FA for a user' do it 'successfully', :js do + stub_feature_flags(bootstrap_confirmation_modals: false) admin = create(:admin) sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index 8315b8f44b02225030d5a8a441180abb788cf0d1..8d4e7a7442c31c2ebc34b2328c7c8eac36dfc959 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -252,6 +252,7 @@ describe 'admin remove themself from a group', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222342' do it 'removes admin from the group' do + stub_feature_flags(bootstrap_confirmation_modals: false) group.add_user(current_user, Gitlab::Access::DEVELOPER) visit group_group_members_path(group) diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index a501efd82edd41e97182bb5b4ba21176b3af15d2..32e4d18227edcef3d4d7fda8cc372168224fd1ad 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -79,6 +79,7 @@ let(:hook_url) { generate(:url) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) create(:system_hook, url: hook_url) end diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index 08d81906d9f002645030b86deca3711870a002ea..65de1160cfdaa920dc20aeedff9327a72475b062 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -14,6 +14,7 @@ describe 'list' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit admin_labels_path end diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index ed8ea84fbf821c97f587faa0642d544d154b43d9..6643ebe82e69d7f3688084760b2be7fd79145e6f 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -74,6 +74,7 @@ def created_impersonation_token let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) } it "allows revocation of an active impersonation token" do + stub_feature_flags(bootstrap_confirmation_modals: false) visit admin_user_impersonation_tokens_path(user_id: user.username) accept_confirm { click_on "Revoke" } diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb index 0e4484460859669a3d25b9f48564cbc7217948c3..c13313609b595ba043345f14885c55b20f8248a7 100644 --- a/spec/features/admin/admin_uses_repository_checks_spec.rb +++ b/spec/features/admin/admin_uses_repository_checks_spec.rb @@ -8,6 +8,7 @@ let(:admin) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) end diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index 624bfde7359823bd7b106b5368aeab32caed6d04..73477fb93dd0dbc7c6cd0d7f46f39c316740bcce 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -9,6 +9,7 @@ let_it_be(:current_user) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(current_user) gitlab_enable_admin_mode_sign_in(current_user) end diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 119b01ff552e3d2deb81a2c609620590764f63f4..3968b055819a686e2d90f81527a844fa6405a9e5 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -9,6 +9,7 @@ let_it_be(:current_user) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(current_user) gitlab_enable_admin_mode_sign_in(current_user) end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 9a5b5bbfc343b492dca9bd8fd08d7132c7bf2501..2f21961d1fca9e485e1cd9d88550867309362919 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -536,6 +536,7 @@ let_it_be(:user_guest) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_guest(user_guest) sign_in(user_guest) visit project_board_path(project, board) diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb index b73313745e9c6537e9c8a77fb951087428fb204b..e6bf1ffc2f736645c5036e383e89df1d19722ce4 100644 --- a/spec/features/groups/members/leave_group_spec.rb +++ b/spec/features/groups/members/leave_group_spec.rb @@ -10,6 +10,7 @@ let(:group) { create(:group) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb index 54c3fe738d2f31a2839005a0d53c60d7d4105dc3..f9b554c5ed288fa4a833139b87a852edcb53c536 100644 --- a/spec/features/merge_request/user_comments_on_diff_spec.rb +++ b/spec/features/merge_request/user_comments_on_diff_spec.rb @@ -14,6 +14,7 @@ let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) sign_in(user) diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb index c339a7d9976ce2ffb982404884989d6c0d7e6985..dcd289c76270f73d368be9c32262f11aeaee80ab 100644 --- a/spec/features/merge_request/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb @@ -18,6 +18,7 @@ project.add_developer(user) sign_in(user) + stub_feature_flags(bootstrap_confirmation_modals: false) end context 'when hovering over a parallel view diff file' do diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb index 83d9388914b7c58f392893c87f1fd33b5e34be0e..0416474218fc80eb0447ca3effd99049ffe5862c 100644 --- a/spec/features/merge_request/user_posts_notes_spec.rb +++ b/spec/features/merge_request/user_posts_notes_spec.rb @@ -18,8 +18,10 @@ end before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) sign_in(user) + visit project_merge_request_path(project, merge_request) end diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb index 90cdc28d1bda4b38fdb82eecd0cb2fcb58989f13..64cd5aa2bb14708dea4051a662b55272fb4249c7 100644 --- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb +++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb @@ -79,6 +79,7 @@ %w(parallel).each do |view| context "#{view} view" do before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit diffs_project_merge_request_path(project, merge_request, view: view) wait_for_requests 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 873cc0a89c6491819651b4f53aecbf134d315cfa..345404cc28f4061ac2003f4075bf957fe1000557 100644 --- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb +++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb @@ -110,6 +110,7 @@ let(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') } before do + stub_feature_flags(bootstrap_confirmation_modals: false) build.success! deployment.update!(on_stop: manual.name) visit project_merge_request_path(project, merge_request) diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index 9a261c6d9c86336f0c959d5e673812efc93ba757..7d935298f38989274ef73e65692d0809eb649e82 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -6,6 +6,7 @@ let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end @@ -80,6 +81,7 @@ describe 'when I reset incoming email token' do before do allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) + stub_feature_flags(bootstrap_confirmation_modals: false) visit profile_personal_access_tokens_path end diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb index fd64704b7c8c68705669c012374ed65caf0d24b1..a515c7b1c1f51a351acf8179c012afa51a6f5486 100644 --- a/spec/features/profiles/active_sessions_spec.rb +++ b/spec/features/profiles/active_sessions_spec.rb @@ -11,6 +11,10 @@ let(:admin) { create(:admin) } + before do + stub_feature_flags(bootstrap_confirmation_modals: false) + end + it 'user sees their active sessions' do travel_to(Time.zone.parse('2018-03-12 09:06')) do Capybara::Session.new(:session1) diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb index 2735f60130733d785ce45473613db15ce9e98171..6827dff5434b8182751b9b8f3dfbfc7b4731894e 100644 --- a/spec/features/profiles/oauth_applications_spec.rb +++ b/spec/features/profiles/oauth_applications_spec.rb @@ -7,6 +7,7 @@ let(:application) { create(:oauth_application, owner: user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 8f44299b18fd87c558036985d48d101c355e4d74..74505633cae8ce39eb48364b04566e6068965c44 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -34,6 +34,7 @@ def disallow_personal_access_token_saves! end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb index 3b8f49accc5d61e11e766f5e7cea764b69af36ec..8fc5c3d2e1b417e38288886801b6d06d2ff353cf 100644 --- a/spec/features/projects/branches/user_deletes_branch_spec.rb +++ b/spec/features/projects/branches/user_deletes_branch_spec.rb @@ -35,6 +35,7 @@ context 'when the feature flag :delete_branch_confirmation_modals is disabled' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) stub_feature_flags(delete_branch_confirmation_modals: false) end diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 0a79719f14a5f12ceb6ce367446fb8a6ac924926..2725c6a91bec02848ef105b92d135b68f1b318d4 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -179,6 +179,7 @@ context 'when the delete_branch_confirmation_modals feature flag is disabled' do it 'removes branch after confirmation', :js do stub_feature_flags(delete_branch_confirmation_modals: false) + stub_feature_flags(bootstrap_confirmation_modals: false) visit project_branches_filtered_path(project, state: 'all') diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb index 431cbb4ffbb51876726ef40dd0af8bd8b12dc286..67d3276fc14690e4e2050d31fb65e53fb360b729 100644 --- a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb +++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb @@ -11,6 +11,7 @@ let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) project.add_developer(user) diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb index 6997c2d8338340f34b631272a622685218019c1d..b0be6edb24555d833e9431fe87dcbff4b7e43d06 100644 --- a/spec/features/projects/commit/user_comments_on_commit_spec.rb +++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb @@ -93,6 +93,8 @@ context "when deleting comment" do before do + stub_feature_flags(bootstrap_confirmation_modals: false) + visit(project_commit_path(project, sample_commit.id)) add_note(comment_text) diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 2404fbf01ca2d5f2bd885f935f54bd331b8bd779..3b83c25b6290fe24bde47da601146a4c3bdc05e3 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -143,6 +143,8 @@ def upcoming_deployment_content_selector create(:environment, project: project, state: :available) end + stub_feature_flags(bootstrap_confirmation_modals: false) + context 'when there are no deployments' do before do visit_environments(project) diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb index 5d7a761cb17bf36b18446fc6da0b8b8f4bb98ef7..12e88bbf6a53916e7924a4e1c84fbdfbdfaeed4c 100644 --- a/spec/features/projects/jobs/user_browses_job_spec.rb +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -12,6 +12,7 @@ before do project.add_maintainer(user) project.enable_ci + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb index c4bd0b81dc09ea0ae434e5fa0da1ec73f32c06e9..4881a7bdf1a5228f575f90481cc0828905e503ba 100644 --- a/spec/features/projects/members/member_leaves_project_spec.rb +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -9,6 +9,7 @@ before do project.add_developer(user) sign_in(user) + stub_feature_flags(bootstrap_confirmation_modals: false) end it 'user leaves project' do diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 113ba69249788e026bbb315b9cf858319a00457c..dcaef5f4ef0d265280dca0a3538635324fdb5193 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -11,6 +11,7 @@ before do sign_in(user) visit project_path(project) + stub_feature_flags(bootstrap_confirmation_modals: false) end it 'request access feature is disabled' do diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb index de9effe3dc7a40305c4fd2c9b5c4281d510bdcfc..06f130ae69c82e071e2f91bfc7ad3a0175dbf8bc 100644 --- a/spec/features/projects/pages/user_adds_domain_spec.rb +++ b/spec/features/projects/pages/user_adds_domain_spec.rb @@ -14,6 +14,8 @@ project.add_maintainer(user) sign_in(user) + + stub_feature_flags(bootstrap_confirmation_modals: false) end context 'when pages are exposed on external HTTP address', :http_pages_enabled do diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb index cf8438d5e6fa6aaedd41a71ab9cffa2c7fabf6db..a3fc5804e1325ffc6b67e892ade3f063a978a4d0 100644 --- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb @@ -14,6 +14,7 @@ before do allow(Gitlab.config.pages).to receive(:enabled).and_return(true) stub_lets_encrypt_settings + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_role(user, role) sign_in(user) diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb index 71d4cce278402bea7ea30ee4dbb927ff834834c9..1226e1dc2edce9662f9c8bee5626b791f0f1fe62 100644 --- a/spec/features/projects/pages/user_edits_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_settings_spec.rb @@ -176,6 +176,7 @@ describe 'Remove page' do context 'when pages are deployed' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.mark_pages_as_deployed end diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 94e3331b173a4533161d3c5825b483fd01a1e1d1..9df430c0f78ae33cbbf1d36fb0867a6edb2e0551 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -11,6 +11,7 @@ context 'logged in as maintainer' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) gitlab_sign_in(user) end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 3a60087818d2ee2f8354bc72c27f6483e15c0997..e38c4989f26f64e8f260a27a697e2ac29ec79064 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -317,6 +317,7 @@ end before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit_project_pipelines end diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb index 4941b936c0c68a8875d450d7df1edbb9f85b51b9..d8de9e0449eaad58b62c4da35ea5d06920a7fbf1 100644 --- a/spec/features/projects/settings/access_tokens_spec.rb +++ b/spec/features/projects/settings/access_tokens_spec.rb @@ -13,6 +13,7 @@ end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/projects/settings/user_searches_in_settings_spec.rb b/spec/features/projects/settings/user_searches_in_settings_spec.rb index 7ed96d01189d85df3b19c303611f4f7d85b84b03..44b5464a1b0e4772bbc4b555f200a75ed8b25909 100644 --- a/spec/features/projects/settings/user_searches_in_settings_spec.rb +++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb @@ -7,6 +7,7 @@ let_it_be(:project) { create(:project, :repository, namespace: user.namespace, pages_https_only: false) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index fc88cd9205c1aa909df66a4995197836b3d3ad87..6bd31d7314cdae39a4e46a8984a08a8ee7628233 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -18,6 +18,7 @@ end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in user visit snippet_path(snippet) diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index ca050daa62a32fdabebec7ab3a1c500571e2978a..82fe895d397b0c85ae571256ee9b8142432d042e 100644 --- a/spec/features/snippets/user_creates_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -16,6 +16,7 @@ let(:snippet_title_field) { 'snippet-title' } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) visit new_snippet_path diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index 6fa805d8c74611da3ea71a56026cbaf855d915cf..2ddd86dd8075fa7b6e22bc8253fc798224b22ec2 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -72,6 +72,7 @@ describe 'trigger "Revoke" workflow' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) create(:ci_trigger, owner: user2, project: @project, description: trigger_title) visit project_settings_ci_cd_path(@project) end diff --git a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js new file mode 100644 index 0000000000000000000000000000000000000000..d19f9352bbc816eb8b273c449048faf2bc04b825 --- /dev/null +++ b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js @@ -0,0 +1,59 @@ +import { GlModal } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; +import ConfirmModal from '~/lib/utils/confirm_via_gl_modal/confirm_modal.vue'; + +describe('Confirm Modal', () => { + let wrapper; + let modal; + + const createComponent = ({ primaryText, primaryVariant } = {}) => { + wrapper = mount(ConfirmModal, { + propsData: { + primaryText, + primaryVariant, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + const findGlModal = () => wrapper.findComponent(GlModal); + + describe('Modal events', () => { + beforeEach(() => { + createComponent(); + modal = findGlModal(); + }); + + it('should emit `confirmed` event on `primary` modal event', () => { + findGlModal().vm.$emit('primary'); + expect(wrapper.emitted('confirmed')).toBeTruthy(); + }); + + it('should emit closed` event on `hidden` modal event', () => { + modal.vm.$emit('hidden'); + expect(wrapper.emitted('closed')).toBeTruthy(); + }); + }); + + describe('Custom properties', () => { + it('should pass correct custom primary text & button variant to the modal when provided', () => { + const primaryText = "Let's do it!"; + const primaryVariant = 'danger'; + + createComponent({ primaryText, primaryVariant }); + const customProps = findGlModal().props('actionPrimary'); + expect(customProps.text).toBe(primaryText); + expect(customProps.attributes.variant).toBe(primaryVariant); + }); + + it('should pass default primary text & button variant to the modal if no custom values provided', () => { + createComponent(); + const customProps = findGlModal().props('actionPrimary'); + expect(customProps.text).toBe('OK'); + expect(customProps.attributes.variant).toBe('confirm'); + }); + }); +}); diff --git a/spec/support/shared_examples/features/2fa_shared_examples.rb b/spec/support/shared_examples/features/2fa_shared_examples.rb index ddc03e178ba8088173a46a6a34c4eb1ace8603f5..94c91556ea786665b248887e49b4cd346bb5aa80 100644 --- a/spec/support/shared_examples/features/2fa_shared_examples.rb +++ b/spec/support/shared_examples/features/2fa_shared_examples.rb @@ -18,6 +18,7 @@ def register_device(device_type, **kwargs) let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) gitlab_sign_in(user) user.update_attribute(:otp_required_for_login, true) end