Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-08-15 18:10:07 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-08-15 18:10:07 +0300
commit12a224d5db7aebdb30cda8ffb75c69fc66d07096 (patch)
treeb76fd3f006aef2f6cc81a2df18fc73dcf1727bb8 /spec
parent8470023ba6ca065d0491c37c33e2348e499df8b3 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin/labels_controller_spec.rb57
-rw-r--r--spec/controllers/groups/labels_controller_spec.rb7
-rw-r--r--spec/controllers/projects/labels_controller_spec.rb46
-rw-r--r--spec/features/incidents/user_views_incident_spec.rb31
-rw-r--r--spec/features/issues/incident_issue_spec.rb4
-rw-r--r--spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js1
-rw-r--r--spec/frontend/admin/statistics_panel/components/app_spec.js1
-rw-r--r--spec/frontend/analytics/cycle_analytics/components/base_spec.js1
-rw-r--r--spec/frontend/analytics/cycle_analytics/components/filter_bar_spec.js1
-rw-r--r--spec/frontend/badges/components/badge_form_spec.js1
-rw-r--r--spec/frontend/badges/components/badge_list_spec.js1
-rw-r--r--spec/frontend/badges/components/badge_settings_spec.js1
-rw-r--r--spec/frontend/batch_comments/components/diff_file_drafts_spec.js1
-rw-r--r--spec/frontend/batch_comments/components/preview_dropdown_spec.js1
-rw-r--r--spec/frontend/batch_comments/components/publish_dropdown_spec.js1
-rw-r--r--spec/frontend/batch_comments/components/submit_dropdown_spec.js1
-rw-r--r--spec/frontend/batch_comments/create_batch_comments_store.js1
-rw-r--r--spec/frontend/boards/board_card_inner_spec.js1
-rw-r--r--spec/frontend/boards/board_list_helper.js1
-rw-r--r--spec/frontend/boards/components/board_add_new_column_form_spec.js1
-rw-r--r--spec/frontend/boards/components/board_add_new_column_spec.js1
-rw-r--r--spec/frontend/boards/components/board_add_new_column_trigger_spec.js1
-rw-r--r--spec/frontend/boards/components/board_app_spec.js1
-rw-r--r--spec/frontend/boards/components/board_card_move_to_position_spec.js1
-rw-r--r--spec/frontend/boards/components/board_card_spec.js1
-rw-r--r--spec/frontend/boards/components/board_content_sidebar_spec.js1
-rw-r--r--spec/frontend/boards/components/board_content_spec.js1
-rw-r--r--spec/frontend/boards/components/board_filtered_search_spec.js1
-rw-r--r--spec/frontend/boards/components/board_form_spec.js1
-rw-r--r--spec/frontend/boards/components/board_list_header_spec.js1
-rw-r--r--spec/frontend/boards/components/board_new_issue_spec.js1
-rw-r--r--spec/frontend/boards/components/board_settings_sidebar_spec.js1
-rw-r--r--spec/frontend/boards/components/board_top_bar_spec.js1
-rw-r--r--spec/frontend/boards/components/boards_selector_spec.js1
-rw-r--r--spec/frontend/boards/components/config_toggle_spec.js1
-rw-r--r--spec/frontend/boards/stores/actions_spec.js1
-rw-r--r--spec/frontend/clusters/forms/components/integration_form_spec.js1
-rw-r--r--spec/frontend/clusters_list/components/clusters_view_all_spec.js1
-rw-r--r--spec/frontend/clusters_list/components/install_agent_modal_spec.js114
-rw-r--r--spec/frontend/code_navigation/components/app_spec.js1
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js1
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js1
-rw-r--r--spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js1
-rw-r--r--spec/frontend/diffs/components/app_spec.js1
-rw-r--r--spec/frontend/diffs/components/collapsed_files_warning_spec.js1
-rw-r--r--spec/frontend/diffs/components/diff_content_spec.js1
-rw-r--r--spec/frontend/diffs/components/diff_discussion_reply_spec.js1
-rw-r--r--spec/frontend/diffs/components/diff_file_header_spec.js1
-rw-r--r--spec/frontend/diffs/components/diff_file_spec.js1
-rw-r--r--spec/frontend/diffs/components/diff_row_spec.js1
-rw-r--r--spec/frontend/diffs/components/diff_view_spec.js1
-rw-r--r--spec/frontend/diffs/components/tree_list_spec.js1
-rw-r--r--spec/frontend/diffs/create_diffs_store.js1
-rw-r--r--spec/frontend/error_tracking/components/error_details_spec.js1
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_list_spec.js1
-rw-r--r--spec/frontend/error_tracking_settings/components/app_spec.js1
-rw-r--r--spec/frontend/error_tracking_settings/components/error_tracking_form_spec.js1
-rw-r--r--spec/frontend/error_tracking_settings/components/project_dropdown_spec.js1
-rw-r--r--spec/frontend/feature_flags/components/edit_feature_flag_spec.js1
-rw-r--r--spec/frontend/feature_flags/components/feature_flags_spec.js1
-rw-r--r--spec/frontend/feature_flags/components/new_feature_flag_spec.js1
-rw-r--r--spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js1
-rw-r--r--spec/frontend/feature_flags/components/strategy_spec.js1
-rw-r--r--spec/frontend/frequent_items/components/app_spec.js1
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_list_item_spec.js1
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_list_spec.js1
-rw-r--r--spec/frontend/frequent_items/components/frequent_items_search_input_spec.js1
-rw-r--r--spec/frontend/header_search/components/app_spec.js1
-rw-r--r--spec/frontend/header_search/components/header_search_autocomplete_items_spec.js1
-rw-r--r--spec/frontend/header_search/components/header_search_default_items_spec.js1
-rw-r--r--spec/frontend/header_search/components/header_search_scoped_items_spec.js1
-rw-r--r--spec/frontend/ide/components/branches/search_list_spec.js1
-rw-r--r--spec/frontend/ide/components/commit_sidebar/editor_header_spec.js1
-rw-r--r--spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js1
-rw-r--r--spec/frontend/ide/components/error_message_spec.js1
-rw-r--r--spec/frontend/ide/components/file_row_extra_spec.js1
-rw-r--r--spec/frontend/ide/components/file_templates/dropdown_spec.js1
-rw-r--r--spec/frontend/ide/components/ide_file_row_spec.js1
-rw-r--r--spec/frontend/ide/components/ide_review_spec.js1
-rw-r--r--spec/frontend/ide/components/ide_side_bar_spec.js1
-rw-r--r--spec/frontend/ide/components/ide_spec.js1
-rw-r--r--spec/frontend/ide/components/ide_status_list_spec.js1
-rw-r--r--spec/frontend/ide/components/ide_tree_spec.js1
-rw-r--r--spec/frontend/ide/components/jobs/list_spec.js1
-rw-r--r--spec/frontend/ide/components/merge_requests/item_spec.js1
-rw-r--r--spec/frontend/ide/components/merge_requests/list_spec.js1
-rw-r--r--spec/frontend/ide/components/new_dropdown/index_spec.js1
-rw-r--r--spec/frontend/ide/components/panes/collapsible_sidebar_spec.js1
-rw-r--r--spec/frontend/ide/components/panes/right_spec.js1
-rw-r--r--spec/frontend/ide/components/pipelines/list_spec.js1
-rw-r--r--spec/frontend/ide/components/repo_editor_spec.js1
-rw-r--r--spec/frontend/ide/components/repo_tab_spec.js1
-rw-r--r--spec/frontend/ide/components/repo_tabs_spec.js1
-rw-r--r--spec/frontend/ide/components/resizable_panel_spec.js1
-rw-r--r--spec/frontend/ide/components/terminal/session_spec.js1
-rw-r--r--spec/frontend/ide/components/terminal/terminal_spec.js1
-rw-r--r--spec/frontend/ide/components/terminal/view_spec.js1
-rw-r--r--spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js1
-rw-r--r--spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js1
-rw-r--r--spec/frontend/ide/stores/modules/editor/setup_spec.js1
-rw-r--r--spec/frontend/ide/stores/plugins/terminal_spec.js1
-rw-r--r--spec/frontend/import_entities/import_projects/components/github_status_table_spec.js1
-rw-r--r--spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js1
-rw-r--r--spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js1
-rw-r--r--spec/frontend/issues/show/components/app_spec.js70
-rw-r--r--spec/frontend/issues/show/components/header_actions_spec.js1
-rw-r--r--spec/frontend/issues/show/components/issue_header_spec.js1
-rw-r--r--spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js1
-rw-r--r--spec/frontend/jobs/components/job/job_app_spec.js1
-rw-r--r--spec/frontend/jobs/components/log/log_spec.js1
-rw-r--r--spec/frontend/lib/utils/vuex_module_mappers_spec.js1
-rw-r--r--spec/frontend/members/components/action_buttons/approve_access_request_button_spec.js1
-rw-r--r--spec/frontend/members/components/action_buttons/remove_group_link_button_spec.js1
-rw-r--r--spec/frontend/members/components/action_buttons/remove_member_button_spec.js1
-rw-r--r--spec/frontend/members/components/action_buttons/resend_invite_button_spec.js1
-rw-r--r--spec/frontend/members/components/action_dropdowns/remove_member_dropdown_item_spec.js1
-rw-r--r--spec/frontend/members/components/app_spec.js1
-rw-r--r--spec/frontend/members/components/filter_sort/filter_sort_container_spec.js1
-rw-r--r--spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js1
-rw-r--r--spec/frontend/members/components/filter_sort/sort_dropdown_spec.js1
-rw-r--r--spec/frontend/members/components/members_tabs_spec.js1
-rw-r--r--spec/frontend/members/components/modals/leave_modal_spec.js1
-rw-r--r--spec/frontend/members/components/modals/remove_group_link_modal_spec.js1
-rw-r--r--spec/frontend/members/components/modals/remove_member_modal_spec.js1
-rw-r--r--spec/frontend/members/components/table/expiration_datepicker_spec.js1
-rw-r--r--spec/frontend/members/components/table/members_table_cell_spec.js1
-rw-r--r--spec/frontend/members/components/table/members_table_spec.js1
-rw-r--r--spec/frontend/members/components/table/role_dropdown_spec.js1
-rw-r--r--spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js1
-rw-r--r--spec/frontend/milestones/components/milestone_combobox_spec.js1
-rw-r--r--spec/frontend/notes/components/comment_form_spec.js1
-rw-r--r--spec/frontend/notes/components/discussion_counter_spec.js1
-rw-r--r--spec/frontend/notes/components/discussion_filter_spec.js1
-rw-r--r--spec/frontend/notes/components/mr_discussion_filter_spec.js1
-rw-r--r--spec/frontend/notes/components/multiline_comment_form_spec.js1
-rw-r--r--spec/frontend/notes/components/note_awards_list_spec.js1
-rw-r--r--spec/frontend/notes/components/note_body_spec.js1
-rw-r--r--spec/frontend/notes/components/note_header_spec.js1
-rw-r--r--spec/frontend/notes/components/noteable_discussion_spec.js1
-rw-r--r--spec/frontend/notes/components/noteable_note_spec.js1
-rw-r--r--spec/frontend/notes/components/timeline_toggle_spec.js1
-rw-r--r--spec/frontend/notes/mixins/discussion_navigation_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/group_empty_state_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/project_empty_state_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_search_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js1
-rw-r--r--spec/frontend/pipelines/pipelines_spec.js15
-rw-r--r--spec/frontend/pipelines/test_reports/test_reports_spec.js1
-rw-r--r--spec/frontend/pipelines/test_reports/test_suite_table_spec.js1
-rw-r--r--spec/frontend/pipelines/test_reports/test_summary_table_spec.js1
-rw-r--r--spec/frontend/projects/commit/components/branches_dropdown_spec.js1
-rw-r--r--spec/frontend/projects/commit/components/projects_dropdown_spec.js1
-rw-r--r--spec/frontend/projects/commits/components/author_select_spec.js1
-rw-r--r--spec/frontend/ref/components/ref_selector_spec.js1
-rw-r--r--spec/frontend/releases/components/app_edit_new_spec.js1
-rw-r--r--spec/frontend/releases/components/asset_links_form_spec.js1
-rw-r--r--spec/frontend/releases/components/confirm_delete_modal_spec.js1
-rw-r--r--spec/frontend/releases/components/tag_field_exsting_spec.js1
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/app_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/archived_filter_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/checkbox_filter_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/confidentiality_filter_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/filters_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/filters_template_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/issues_filters_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/label_dropdown_items_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/label_filter_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/language_filter_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/radio_filter_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/scope_legacy_navigation_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/scope_sidebar_navigation_spec.js1
-rw-r--r--spec/frontend/search/sidebar/components/status_filter_spec.js1
-rw-r--r--spec/frontend/search/sort/components/app_spec.js1
-rw-r--r--spec/frontend/search/topbar/components/app_spec.js1
-rw-r--r--spec/frontend/search/topbar/components/group_filter_spec.js1
-rw-r--r--spec/frontend/search/topbar/components/project_filter_spec.js1
-rw-r--r--spec/frontend/search/topbar/components/searchable_dropdown_spec.js1
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_button_spec.js1
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_create_view_spec.js1
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js1
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_spec.js1
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_title_spec.js1
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_value_spec.js1
-rw-r--r--spec/frontend/sidebar/components/labels/labels_select_vue/labels_select_root_spec.js1
-rw-r--r--spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js1
-rw-r--r--spec/frontend/super_sidebar/components/global_search/components/global_search_autocomplete_items_spec.js1
-rw-r--r--spec/frontend/super_sidebar/components/global_search/components/global_search_default_issuables_spec.js1
-rw-r--r--spec/frontend/super_sidebar/components/global_search/components/global_search_default_items_spec.js1
-rw-r--r--spec/frontend/super_sidebar/components/global_search/components/global_search_scoped_items_spec.js1
-rw-r--r--spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js1
-rw-r--r--spec/frontend/super_sidebar/components/user_bar_spec.js1
-rw-r--r--spec/frontend/user_lists/components/edit_user_list_spec.js1
-rw-r--r--spec/frontend/user_lists/components/new_user_list_spec.js1
-rw-r--r--spec/frontend/user_lists/components/user_list_spec.js1
-rw-r--r--spec/frontend/user_lists/components/user_lists_spec.js1
-rw-r--r--spec/frontend/vue_merge_request_widget/components/artifacts_list_app_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/gl_modal_vuex_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/metric_images/metric_images_table_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/metric_images/store/actions_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/notes/placeholder_note_spec.js1
-rw-r--r--spec/frontend/whats_new/components/app_spec.js1
-rw-r--r--spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb259
-rw-r--r--spec/lib/gitlab/ci/input/arguments/base_spec.rb19
-rw-r--r--spec/lib/gitlab/ci/input/arguments/default_spec.rb53
-rw-r--r--spec/lib/gitlab/ci/input/arguments/options_spec.rb54
-rw-r--r--spec/lib/gitlab/ci/input/arguments/required_spec.rb45
-rw-r--r--spec/lib/gitlab/ci/input/arguments/unknown_spec.rb18
-rw-r--r--spec/lib/gitlab/ci/input/inputs_spec.rb126
-rw-r--r--spec/migrations/20230810123044_swap_snippet_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb125
-rw-r--r--spec/migrations/20230811103941_swap_vulnerability_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb133
-rw-r--r--spec/models/label_spec.rb1
-rw-r--r--spec/models/project_authorizations/changes_spec.rb40
-rw-r--r--spec/requests/api/labels_spec.rb12
-rw-r--r--spec/services/issues/import_csv_service_spec.rb10
-rw-r--r--spec/services/members/create_service_spec.rb7
-rw-r--r--spec/services/merge_requests/ff_merge_service_spec.rb1
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb799
-rw-r--r--spec/services/merge_requests/merge_strategies/from_source_branch_spec.rb87
-rw-r--r--spec/services/spam/spam_action_service_spec.rb14
-rw-r--r--spec/support/shared_examples/services/import_csv_service_shared_examples.rb12
228 files changed, 1407 insertions, 953 deletions
diff --git a/spec/controllers/admin/labels_controller_spec.rb b/spec/controllers/admin/labels_controller_spec.rb
new file mode 100644
index 00000000000..c753426326d
--- /dev/null
+++ b/spec/controllers/admin/labels_controller_spec.rb
@@ -0,0 +1,57 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Admin::LabelsController, feature_category: :team_planning do
+ let_it_be(:admin) { create(:admin) }
+
+ before do
+ sign_in(admin)
+ end
+
+ describe 'DELETE #destroy' do
+ context 'when current user has ability to destroy the label' do
+ it 'removes the label' do
+ label = create(:admin_label)
+ delete :destroy, params: { id: label.to_param }
+
+ expect { label.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'does not remove the label if it is locked' do
+ label = create(:admin_label, lock_on_merge: true)
+ delete :destroy, params: { id: label.to_param }
+
+ expect(label.reload).to eq label
+ end
+
+ context 'when label is succesfuly destroyed' do
+ it 'redirects to the admin labels page' do
+ label = create(:admin_label)
+ delete :destroy, params: { id: label.to_param }
+
+ expect(response).to redirect_to(admin_labels_path)
+ end
+ end
+ end
+
+ context 'when current_user does not have ability to destroy the label' do
+ let(:group) { create(:group) }
+ let(:project) { create(:project, namespace: group) }
+ let(:another_user) { create(:user) }
+
+ before do
+ project.add_maintainer(another_user)
+
+ sign_in(another_user)
+ end
+
+ it 'responds with status 404' do
+ label = create(:admin_label)
+ delete :destroy, params: { id: label.to_param }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/groups/labels_controller_spec.rb b/spec/controllers/groups/labels_controller_spec.rb
index 916b2cf10dd..ebe379d948c 100644
--- a/spec/controllers/groups/labels_controller_spec.rb
+++ b/spec/controllers/groups/labels_controller_spec.rb
@@ -89,6 +89,13 @@ RSpec.describe Groups::LabelsController, feature_category: :team_planning do
expect { label.reload }.to raise_error(ActiveRecord::RecordNotFound)
end
+ it 'does not remove the label if it is locked' do
+ label = create(:group_label, group: group, lock_on_merge: true)
+ delete :destroy, params: { group_id: group.to_param, id: label.to_param }
+
+ expect(label.reload).to eq label
+ end
+
context 'when label is succesfuly destroyed' do
it 'redirects to the group labels page' do
label = create(:group_label, group: group)
diff --git a/spec/controllers/projects/labels_controller_spec.rb b/spec/controllers/projects/labels_controller_spec.rb
index 98982856d6c..74c16621fc5 100644
--- a/spec/controllers/projects/labels_controller_spec.rb
+++ b/spec/controllers/projects/labels_controller_spec.rb
@@ -297,6 +297,52 @@ RSpec.describe Projects::LabelsController, feature_category: :team_planning do
end
end
+ describe 'DELETE #destroy' do
+ context 'when current user has ability to destroy the label' do
+ before do
+ sign_in(user)
+ end
+
+ it 'removes the label' do
+ label = create(:label, project: project)
+ delete :destroy, params: { namespace_id: group.to_param, project_id: project.to_param, id: label.to_param }
+
+ expect { label.reload }.to raise_error(ActiveRecord::RecordNotFound)
+ end
+
+ it 'does not remove the label if it is locked' do
+ label = create(:label, project: project, lock_on_merge: true)
+ delete :destroy, params: { namespace_id: group.to_param, project_id: project.to_param, id: label.to_param }
+
+ expect(label.reload).to eq label
+ end
+
+ context 'when label is succesfuly destroyed' do
+ it 'redirects to the project labels page' do
+ label = create(:label, project: project)
+ delete :destroy, params: { namespace_id: group.to_param, project_id: project.to_param, id: label.to_param }
+
+ expect(response).to redirect_to(project_labels_path(project))
+ end
+ end
+ end
+
+ context 'when current_user does not have ability to destroy the label' do
+ let(:another_user) { create(:user) }
+
+ before do
+ sign_in(another_user)
+ end
+
+ it 'responds with status 404' do
+ label = create(:label, project: project)
+ delete :destroy, params: { namespace_id: group.to_param, project_id: project.to_param, id: label.to_param }
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
def project_moved_message(redirect_route, project)
"Project '#{redirect_route.path}' was moved to '#{project.full_path}'. Please update any links and bookmarks that may still have the old path."
end
diff --git a/spec/features/incidents/user_views_incident_spec.rb b/spec/features/incidents/user_views_incident_spec.rb
index bbf579b09a8..65bd88582db 100644
--- a/spec/features/incidents/user_views_incident_spec.rb
+++ b/spec/features/incidents/user_views_incident_spec.rb
@@ -75,35 +75,4 @@ RSpec.describe "User views incident", feature_category: :incident_management do
expect(page).not_to have_button('Incident actions')
end
end
-
- describe 'user status' do
- context 'when showing status of the author of the incident' do
- subject { visit(incident_project_issues_path(project, incident)) }
-
- it_behaves_like 'showing user status' do
- let(:user_with_status) { user }
- end
- end
-
- context 'when status message has an emoji', :js do
- let_it_be(:message) { 'My status with an emoji' }
- let_it_be(:message_emoji) { 'basketball' }
- let_it_be(:status) { create(:user_status, user: user, emoji: 'smirk', message: "#{message} :#{message_emoji}:") }
-
- it 'correctly renders the emoji' do
- wait_for_requests
-
- tooltip_span = page.first(".user-status-emoji[title^='#{message}']")
- tooltip_span.hover
-
- wait_for_requests
-
- tooltip = page.find('.tooltip .tooltip-inner')
-
- page.within(tooltip) do
- expect(page).to have_emoji(message_emoji)
- end
- end
- end
- end
end
diff --git a/spec/features/issues/incident_issue_spec.rb b/spec/features/issues/incident_issue_spec.rb
index 145b51d207a..5197f5d1e33 100644
--- a/spec/features/issues/incident_issue_spec.rb
+++ b/spec/features/issues/incident_issue_spec.rb
@@ -70,10 +70,6 @@ RSpec.describe 'Incident Detail', :js, feature_category: :team_planning do
# Linked Issues/MRs and comment box are hidden on page
expect(hidden_items.count).to eq(0)
-
- # does not show the edit title and description button
- edit_button = find_all('[aria-label="Edit title and description"]', wait: false)
- expect(edit_button.count).to eq(0)
end
end
end
diff --git a/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js b/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js
index fa051f7a43a..68225468941 100644
--- a/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js
+++ b/spec/frontend/add_context_commits_modal/components/add_context_commits_modal_spec.js
@@ -1,6 +1,7 @@
import { GlModal, GlFilteredSearch } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import getDiffWithCommit from 'test_fixtures/merge_request_diffs/with_commit.json';
import AddReviewItemsModal from '~/add_context_commits_modal/components/add_context_commits_modal_wrapper.vue';
diff --git a/spec/frontend/admin/statistics_panel/components/app_spec.js b/spec/frontend/admin/statistics_panel/components/app_spec.js
index 60e46cddd7e..febc049b812 100644
--- a/spec/frontend/admin/statistics_panel/components/app_spec.js
+++ b/spec/frontend/admin/statistics_panel/components/app_spec.js
@@ -2,6 +2,7 @@ import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import StatisticsPanelApp from '~/admin/statistics_panel/components/app.vue';
import statisticsLabels from '~/admin/statistics_panel/constants';
diff --git a/spec/frontend/analytics/cycle_analytics/components/base_spec.js b/spec/frontend/analytics/cycle_analytics/components/base_spec.js
index 87f3117c7f9..653934000b3 100644
--- a/spec/frontend/analytics/cycle_analytics/components/base_spec.js
+++ b/spec/frontend/analytics/cycle_analytics/components/base_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlEmptyState } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ValueStreamMetrics from '~/analytics/shared/components/value_stream_metrics.vue';
diff --git a/spec/frontend/analytics/cycle_analytics/components/filter_bar_spec.js b/spec/frontend/analytics/cycle_analytics/components/filter_bar_spec.js
index f57d8559ddf..387d0b453ee 100644
--- a/spec/frontend/analytics/cycle_analytics/components/filter_bar_spec.js
+++ b/spec/frontend/analytics/cycle_analytics/components/filter_bar_spec.js
@@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import {
filterMilestones,
diff --git a/spec/frontend/badges/components/badge_form_spec.js b/spec/frontend/badges/components/badge_form_spec.js
index 9609a29b7ed..d3d2544dc4f 100644
--- a/spec/frontend/badges/components/badge_form_spec.js
+++ b/spec/frontend/badges/components/badge_form_spec.js
@@ -1,5 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mount } from '@vue/test-utils';
import { DUMMY_IMAGE_URL, TEST_HOST } from 'helpers/test_constants';
diff --git a/spec/frontend/badges/components/badge_list_spec.js b/spec/frontend/badges/components/badge_list_spec.js
index 388e091d059..612e9bdc41f 100644
--- a/spec/frontend/badges/components/badge_list_spec.js
+++ b/spec/frontend/badges/components/badge_list_spec.js
@@ -1,5 +1,6 @@
import { GlTable, GlButton } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import { GROUP_BADGE, PROJECT_BADGE } from '~/badges/constants';
diff --git a/spec/frontend/badges/components/badge_settings_spec.js b/spec/frontend/badges/components/badge_settings_spec.js
index dcba895edf6..af7389b4240 100644
--- a/spec/frontend/badges/components/badge_settings_spec.js
+++ b/spec/frontend/badges/components/badge_settings_spec.js
@@ -1,6 +1,7 @@
import { GlCard, GlTable } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import BadgeSettings from '~/badges/components/badge_settings.vue';
import BadgeList from '~/badges/components/badge_list.vue';
diff --git a/spec/frontend/batch_comments/components/diff_file_drafts_spec.js b/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
index 014e28b7509..e779309e3d8 100644
--- a/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
+++ b/spec/frontend/batch_comments/components/diff_file_drafts_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DiffFileDrafts from '~/batch_comments/components/diff_file_drafts.vue';
import DraftNote from '~/batch_comments/components/draft_note.vue';
diff --git a/spec/frontend/batch_comments/components/preview_dropdown_spec.js b/spec/frontend/batch_comments/components/preview_dropdown_spec.js
index 3a28bf4ade8..608e9c82961 100644
--- a/spec/frontend/batch_comments/components/preview_dropdown_spec.js
+++ b/spec/frontend/batch_comments/components/preview_dropdown_spec.js
@@ -1,4 +1,5 @@
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mount } from '@vue/test-utils';
import { TEST_HOST } from 'helpers/test_constants';
diff --git a/spec/frontend/batch_comments/components/publish_dropdown_spec.js b/spec/frontend/batch_comments/components/publish_dropdown_spec.js
index 44d7b56c14f..2fe73f30a4c 100644
--- a/spec/frontend/batch_comments/components/publish_dropdown_spec.js
+++ b/spec/frontend/batch_comments/components/publish_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlDisclosureDropdown } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import PreviewDropdown from '~/batch_comments/components/preview_dropdown.vue';
import { createStore } from '~/mr_notes/stores';
diff --git a/spec/frontend/batch_comments/components/submit_dropdown_spec.js b/spec/frontend/batch_comments/components/submit_dropdown_spec.js
index 4f2df0e9bf7..19be3fb7d31 100644
--- a/spec/frontend/batch_comments/components/submit_dropdown_spec.js
+++ b/spec/frontend/batch_comments/components/submit_dropdown_spec.js
@@ -1,5 +1,6 @@
import { GlDropdown } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import SubmitDropdown from '~/batch_comments/components/submit_dropdown.vue';
diff --git a/spec/frontend/batch_comments/create_batch_comments_store.js b/spec/frontend/batch_comments/create_batch_comments_store.js
index 10dc6fe196e..2adaae6a9e1 100644
--- a/spec/frontend/batch_comments/create_batch_comments_store.js
+++ b/spec/frontend/batch_comments/create_batch_comments_store.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import batchCommentsModule from '~/batch_comments/stores/modules/batch_comments';
import notesModule from '~/notes/stores/modules';
diff --git a/spec/frontend/boards/board_card_inner_spec.js b/spec/frontend/boards/board_card_inner_spec.js
index 36556ba00af..1740676161f 100644
--- a/spec/frontend/boards/board_card_inner_spec.js
+++ b/spec/frontend/boards/board_card_inner_spec.js
@@ -2,6 +2,7 @@ import { GlLabel, GlLoadingIcon, GlTooltip } from '@gitlab/ui';
import { range } from 'lodash';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
import setWindowLocation from 'helpers/set_window_location_helper';
diff --git a/spec/frontend/boards/board_list_helper.js b/spec/frontend/boards/board_list_helper.js
index e3cdec1ab6e..7367b34c4df 100644
--- a/spec/frontend/boards/board_list_helper.js
+++ b/spec/frontend/boards/board_list_helper.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import BoardCard from '~/boards/components/board_card.vue';
diff --git a/spec/frontend/boards/components/board_add_new_column_form_spec.js b/spec/frontend/boards/components/board_add_new_column_form_spec.js
index 35296f36b89..719e36629c2 100644
--- a/spec/frontend/boards/components/board_add_new_column_form_spec.js
+++ b/spec/frontend/boards/components/board_add_new_column_form_spec.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import BoardAddNewColumnForm from '~/boards/components/board_add_new_column_form.vue';
diff --git a/spec/frontend/boards/components/board_add_new_column_spec.js b/spec/frontend/boards/components/board_add_new_column_spec.js
index af76ad7bcac..1a847d35900 100644
--- a/spec/frontend/boards/components/board_add_new_column_spec.js
+++ b/spec/frontend/boards/components/board_add_new_column_spec.js
@@ -1,6 +1,7 @@
import { GlCollapsibleListbox } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/boards/components/board_add_new_column_trigger_spec.js b/spec/frontend/boards/components/board_add_new_column_trigger_spec.js
index 825cfc9453a..396ec7d67cd 100644
--- a/spec/frontend/boards/components/board_add_new_column_trigger_spec.js
+++ b/spec/frontend/boards/components/board_add_new_column_trigger_spec.js
@@ -1,5 +1,6 @@
import { GlButton } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import BoardAddNewColumnTrigger from '~/boards/components/board_add_new_column_trigger.vue';
diff --git a/spec/frontend/boards/components/board_app_spec.js b/spec/frontend/boards/components/board_app_spec.js
index 77ec260745c..b16f9b26f40 100644
--- a/spec/frontend/boards/components/board_app_spec.js
+++ b/spec/frontend/boards/components/board_app_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
diff --git a/spec/frontend/boards/components/board_card_move_to_position_spec.js b/spec/frontend/boards/components/board_card_move_to_position_spec.js
index 5f308be5580..20beaf2e9bd 100644
--- a/spec/frontend/boards/components/board_card_move_to_position_spec.js
+++ b/spec/frontend/boards/components/board_card_move_to_position_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { GlDisclosureDropdown, GlDisclosureDropdownItem } from '@gitlab/ui';
import {
diff --git a/spec/frontend/boards/components/board_card_spec.js b/spec/frontend/boards/components/board_card_spec.js
index 897219303b5..167efb94fcc 100644
--- a/spec/frontend/boards/components/board_card_spec.js
+++ b/spec/frontend/boards/components/board_card_spec.js
@@ -1,5 +1,6 @@
import { GlLabel } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import VueApollo from 'vue-apollo';
diff --git a/spec/frontend/boards/components/board_content_sidebar_spec.js b/spec/frontend/boards/components/board_content_sidebar_spec.js
index 9be2696de56..01eea12bf0a 100644
--- a/spec/frontend/boards/components/board_content_sidebar_spec.js
+++ b/spec/frontend/boards/components/board_content_sidebar_spec.js
@@ -2,6 +2,7 @@ import { GlDrawer } from '@gitlab/ui';
import { MountingPortal } from 'portal-vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import SidebarDropdownWidget from 'ee_else_ce/sidebar/components/sidebar_dropdown_widget.vue';
import createMockApollo from 'helpers/mock_apollo_helper';
diff --git a/spec/frontend/boards/components/board_content_spec.js b/spec/frontend/boards/components/board_content_spec.js
index 38daef28149..675b79a8b1a 100644
--- a/spec/frontend/boards/components/board_content_spec.js
+++ b/spec/frontend/boards/components/board_content_spec.js
@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import VueApollo from 'vue-apollo';
import Vue, { nextTick } from 'vue';
import Draggable from 'vuedraggable';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
diff --git a/spec/frontend/boards/components/board_filtered_search_spec.js b/spec/frontend/boards/components/board_filtered_search_spec.js
index 5a976816f74..0bd936c9abd 100644
--- a/spec/frontend/boards/components/board_filtered_search_spec.js
+++ b/spec/frontend/boards/components/board_filtered_search_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import BoardFilteredSearch from '~/boards/components/board_filtered_search.vue';
import { updateHistory } from '~/lib/utils/url_utility';
diff --git a/spec/frontend/boards/components/board_form_spec.js b/spec/frontend/boards/components/board_form_spec.js
index 5604c589e37..15ee3976fb1 100644
--- a/spec/frontend/boards/components/board_form_spec.js
+++ b/spec/frontend/boards/components/board_form_spec.js
@@ -1,5 +1,6 @@
import { GlModal } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import VueApollo from 'vue-apollo';
import setWindowLocation from 'helpers/set_window_location_helper';
diff --git a/spec/frontend/boards/components/board_list_header_spec.js b/spec/frontend/boards/components/board_list_header_spec.js
index 7c2ebede320..76e969f1725 100644
--- a/spec/frontend/boards/components/board_list_header_spec.js
+++ b/spec/frontend/boards/components/board_list_header_spec.js
@@ -1,6 +1,7 @@
import { GlButtonGroup } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/boards/components/board_new_issue_spec.js b/spec/frontend/boards/components/board_new_issue_spec.js
index a1088f1e8f7..bf2608d0594 100644
--- a/spec/frontend/boards/components/board_new_issue_spec.js
+++ b/spec/frontend/boards/components/board_new_issue_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
diff --git a/spec/frontend/boards/components/board_settings_sidebar_spec.js b/spec/frontend/boards/components/board_settings_sidebar_spec.js
index 7314386477b..f6ed483dfc5 100644
--- a/spec/frontend/boards/components/board_settings_sidebar_spec.js
+++ b/spec/frontend/boards/components/board_settings_sidebar_spec.js
@@ -3,6 +3,7 @@ import { shallowMount } from '@vue/test-utils';
import { MountingPortal } from 'portal-vue';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
diff --git a/spec/frontend/boards/components/board_top_bar_spec.js b/spec/frontend/boards/components/board_top_bar_spec.js
index ae2d589a34f..87abe630688 100644
--- a/spec/frontend/boards/components/board_top_bar_spec.js
+++ b/spec/frontend/boards/components/board_top_bar_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/boards/components/boards_selector_spec.js b/spec/frontend/boards/components/boards_selector_spec.js
index 50860c6e45b..b17a5589c07 100644
--- a/spec/frontend/boards/components/boards_selector_spec.js
+++ b/spec/frontend/boards/components/boards_selector_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlLoadingIcon, GlDropdownSectionHeader } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import { TEST_HOST } from 'spec/test_constants';
diff --git a/spec/frontend/boards/components/config_toggle_spec.js b/spec/frontend/boards/components/config_toggle_spec.js
index 9f006ebf01d..3d505038331 100644
--- a/spec/frontend/boards/components/config_toggle_spec.js
+++ b/spec/frontend/boards/components/config_toggle_spec.js
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Vue from 'vue';
import { shallowMount } from '@vue/test-utils';
diff --git a/spec/frontend/boards/stores/actions_spec.js b/spec/frontend/boards/stores/actions_spec.js
index a2961fb1302..5b4b79c650a 100644
--- a/spec/frontend/boards/stores/actions_spec.js
+++ b/spec/frontend/boards/stores/actions_spec.js
@@ -1,6 +1,7 @@
import * as Sentry from '@sentry/browser';
import { cloneDeep } from 'lodash';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { inactiveId, ISSUABLE, ListType, DraggableItemTypes } from 'ee_else_ce/boards/constants';
import issueMoveListMutation from 'ee_else_ce/boards/graphql/issue_move_list.mutation.graphql';
diff --git a/spec/frontend/clusters/forms/components/integration_form_spec.js b/spec/frontend/clusters/forms/components/integration_form_spec.js
index 396f8215b9f..9c9e07dee15 100644
--- a/spec/frontend/clusters/forms/components/integration_form_spec.js
+++ b/spec/frontend/clusters/forms/components/integration_form_spec.js
@@ -1,6 +1,7 @@
import { GlToggle, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import IntegrationForm from '~/clusters/forms/components/integration_form.vue';
import { createStore } from '~/clusters/forms/stores/index';
diff --git a/spec/frontend/clusters_list/components/clusters_view_all_spec.js b/spec/frontend/clusters_list/components/clusters_view_all_spec.js
index e81b242dd90..e86cd1019a9 100644
--- a/spec/frontend/clusters_list/components/clusters_view_all_spec.js
+++ b/spec/frontend/clusters_list/components/clusters_view_all_spec.js
@@ -1,5 +1,6 @@
import { GlCard, GlLoadingIcon, GlSprintf, GlBadge } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ClustersViewAll from '~/clusters_list/components/clusters_view_all.vue';
diff --git a/spec/frontend/clusters_list/components/install_agent_modal_spec.js b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
index e1306e2738f..0cf6b8fbff9 100644
--- a/spec/frontend/clusters_list/components/install_agent_modal_spec.js
+++ b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
@@ -1,7 +1,7 @@
import { GlAlert, GlButton, GlFormInputGroup, GlSprintf } from '@gitlab/ui';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import { sprintf } from '~/locale';
+import { sprintf, s__ } from '~/locale';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { mockTracking } from 'helpers/tracking_helper';
import AvailableAgentsDropdown from '~/clusters_list/components/available_agents_dropdown.vue';
@@ -48,15 +48,26 @@ describe('InstallAgentModal', () => {
let trackingSpy;
const configurations = [{ agentName: 'agent-name' }];
- const apolloQueryResponse = {
+ const apolloQueryResponse = (configurationsNodes = configurations) => ({
data: {
project: {
__typename: 'Project',
id: 'project-1',
clusterAgents: { nodes: [] },
- agentConfigurations: { nodes: configurations },
+ agentConfigurations: { nodes: configurationsNodes },
},
},
+ });
+
+ const provide = {
+ projectPath,
+ kasAddress,
+ emptyStateImage,
+ };
+
+ const propsData = {
+ defaultBranchName,
+ maxAgents,
};
const findModal = () => wrapper.findComponent(ModalStub);
@@ -80,17 +91,12 @@ describe('InstallAgentModal', () => {
}
};
- const createWrapper = () => {
- const provide = {
- projectPath,
- kasAddress,
- emptyStateImage,
- };
-
- const propsData = {
- defaultBranchName,
- maxAgents,
- };
+ const createWrapper = (mockApolloProvider) => {
+ apolloProvider =
+ mockApolloProvider ||
+ createMockApollo([
+ [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse())],
+ ]);
wrapper = shallowMountExtended(InstallAgentModal, {
attachTo: document.body,
@@ -102,6 +108,8 @@ describe('InstallAgentModal', () => {
provide,
propsData,
});
+
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
};
const writeQuery = () => {
@@ -117,33 +125,26 @@ describe('InstallAgentModal', () => {
});
};
- const mockSelectedAgentResponse = async () => {
- createWrapper();
+ const mockSelectedAgentResponse = (mockApolloProvider) => {
+ createWrapper(mockApolloProvider);
writeQuery();
- await waitForPromises();
-
wrapper.vm.setAgentName('agent-name');
findActionButton().vm.$emit('click');
return waitForPromises();
};
- beforeEach(async () => {
- apolloProvider = createMockApollo([
- [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)],
- ]);
- createWrapper();
- await waitForPromises();
- trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
- });
-
afterEach(() => {
apolloProvider = null;
});
describe('when KAS is enabled', () => {
describe('initial state', () => {
+ beforeEach(() => {
+ createWrapper();
+ });
+
it('renders the dropdown for available agents', () => {
expect(findAgentDropdown().isVisible()).toBe(true);
});
@@ -173,8 +174,45 @@ describe('InstallAgentModal', () => {
});
});
+ describe('when there are 10 or more available agent configurations', () => {
+ it('displays an alert with Terraform instructions', async () => {
+ const configurationsNodes = Array(10).fill(configurations);
+ const mockApolloProvider = createMockApollo([
+ [
+ getAgentConfigurations,
+ jest.fn().mockResolvedValue(apolloQueryResponse(configurationsNodes)),
+ ],
+ ]);
+
+ createWrapper(mockApolloProvider);
+ await waitForPromises();
+
+ expect(findAlert().text()).toMatchInterpolatedText(
+ s__('ClusterAgents|To manage more agents, %{linkStart}use Terraform%{linkEnd}.'),
+ );
+ });
+
+ it('displays an alert with a warning when there are 100 or more configurations', async () => {
+ const configurationsNodes = Array(100).fill(configurations);
+ const mockApolloProvider = createMockApollo([
+ [
+ getAgentConfigurations,
+ jest.fn().mockResolvedValue(apolloQueryResponse(configurationsNodes)),
+ ],
+ ]);
+
+ createWrapper(mockApolloProvider);
+ await waitForPromises();
+
+ expect(findAlert().text()).toContain(
+ s__('ClusterAgents|We only support 100 agents on the UI.'),
+ );
+ });
+ });
+
describe('an agent is selected', () => {
beforeEach(() => {
+ createWrapper();
findAgentDropdown().vm.$emit('agentSelected');
});
@@ -195,13 +233,13 @@ describe('InstallAgentModal', () => {
const createAgentTokenHandler = jest.fn().mockResolvedValue(createAgentTokenResponse);
beforeEach(() => {
- apolloProvider = createMockApollo([
- [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)],
+ const mockApolloProvider = createMockApollo([
+ [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse())],
[createAgentMutation, createAgentHandler],
[createAgentTokenMutation, createAgentTokenHandler],
]);
- return mockSelectedAgentResponse();
+ return mockSelectedAgentResponse(mockApolloProvider);
});
it('creates an agent and token', () => {
@@ -230,12 +268,12 @@ describe('InstallAgentModal', () => {
describe('error creating agent', () => {
beforeEach(() => {
- apolloProvider = createMockApollo([
- [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)],
+ const mockApolloProvider = createMockApollo([
+ [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse())],
[createAgentMutation, jest.fn().mockResolvedValue(createAgentErrorResponse)],
]);
- return mockSelectedAgentResponse();
+ return mockSelectedAgentResponse(mockApolloProvider);
});
it('displays the error message', () => {
@@ -247,13 +285,13 @@ describe('InstallAgentModal', () => {
describe('error creating token', () => {
beforeEach(() => {
- apolloProvider = createMockApollo([
- [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)],
+ const mockApolloProvider = createMockApollo([
+ [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse())],
[createAgentMutation, jest.fn().mockResolvedValue(createAgentResponse)],
[createAgentTokenMutation, jest.fn().mockResolvedValue(createAgentTokenErrorResponse)],
]);
- return mockSelectedAgentResponse();
+ return mockSelectedAgentResponse(mockApolloProvider);
});
it('displays the error message', () => {
@@ -267,11 +305,11 @@ describe('InstallAgentModal', () => {
describe('when KAS is disabled', () => {
beforeEach(async () => {
- apolloProvider = createMockApollo([
+ const mockApolloProvider = createMockApollo([
[getAgentConfigurations, jest.fn().mockResolvedValue(kasDisabledErrorResponse)],
]);
- createWrapper();
+ createWrapper(mockApolloProvider);
await waitForPromises();
});
diff --git a/spec/frontend/code_navigation/components/app_spec.js b/spec/frontend/code_navigation/components/app_spec.js
index 88861b0d08a..27e211466b1 100644
--- a/spec/frontend/code_navigation/components/app_spec.js
+++ b/spec/frontend/code_navigation/components/app_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js
index 1cd16e39417..c210880cbdc 100644
--- a/spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_modal_spec.js
@@ -1,6 +1,7 @@
import { GlButton, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Api from '~/api';
import DeployFreezeModal from '~/deploy_freeze/components/deploy_freeze_modal.vue';
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js
index 883cc6a344a..4068493a3b7 100644
--- a/spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_settings_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DeployFreezeModal from '~/deploy_freeze/components/deploy_freeze_modal.vue';
import DeployFreezeSettings from '~/deploy_freeze/components/deploy_freeze_settings.vue';
diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
index e9e7f7fdb88..e69a486ea78 100644
--- a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
+++ b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DeployFreezeTable from '~/deploy_freeze/components/deploy_freeze_table.vue';
import createStore from '~/deploy_freeze/store';
diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js
index 2ad04a7c371..c1f0966f9c6 100644
--- a/spec/frontend/diffs/components/app_spec.js
+++ b/spec/frontend/diffs/components/app_spec.js
@@ -2,6 +2,7 @@ import { GlLoadingIcon, GlPagination } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
import { TEST_HOST } from 'spec/test_constants';
diff --git a/spec/frontend/diffs/components/collapsed_files_warning_spec.js b/spec/frontend/diffs/components/collapsed_files_warning_spec.js
index ae40f6c898d..4e34691f72b 100644
--- a/spec/frontend/diffs/components/collapsed_files_warning_spec.js
+++ b/spec/frontend/diffs/components/collapsed_files_warning_spec.js
@@ -1,5 +1,6 @@
import { shallowMount, mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import CollapsedFilesWarning from '~/diffs/components/collapsed_files_warning.vue';
import { EVT_EXPAND_ALL_FILES } from '~/diffs/constants';
diff --git a/spec/frontend/diffs/components/diff_content_spec.js b/spec/frontend/diffs/components/diff_content_spec.js
index 4fcc8720176..be085ba1525 100644
--- a/spec/frontend/diffs/components/diff_content_spec.js
+++ b/spec/frontend/diffs/components/diff_content_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import { sprintf } from '~/locale';
diff --git a/spec/frontend/diffs/components/diff_discussion_reply_spec.js b/spec/frontend/diffs/components/diff_discussion_reply_spec.js
index 348439d6006..1e542c413b2 100644
--- a/spec/frontend/diffs/components/diff_discussion_reply_spec.js
+++ b/spec/frontend/diffs/components/diff_discussion_reply_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import { GlButton } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DiffDiscussionReply from '~/diffs/components/diff_discussion_reply.vue';
import NoteSignedOutWidget from '~/notes/components/note_signed_out_widget.vue';
diff --git a/spec/frontend/diffs/components/diff_file_header_spec.js b/spec/frontend/diffs/components/diff_file_header_spec.js
index d3afaab492d..b089825090b 100644
--- a/spec/frontend/diffs/components/diff_file_header_spec.js
+++ b/spec/frontend/diffs/components/diff_file_header_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import { cloneDeep } from 'lodash';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
diff --git a/spec/frontend/diffs/components/diff_file_spec.js b/spec/frontend/diffs/components/diff_file_spec.js
index d0b490198bc..53f135471b7 100644
--- a/spec/frontend/diffs/components/diff_file_spec.js
+++ b/spec/frontend/diffs/components/diff_file_spec.js
@@ -1,5 +1,6 @@
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/diffs/components/diff_row_spec.js b/spec/frontend/diffs/components/diff_row_spec.js
index 119b8f9ad7f..8a67d7b152c 100644
--- a/spec/frontend/diffs/components/diff_row_spec.js
+++ b/spec/frontend/diffs/components/diff_row_spec.js
@@ -1,6 +1,7 @@
import { getByTestId, fireEvent } from '@testing-library/dom';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DiffRow from '~/diffs/components/diff_row.vue';
import { mapParallel } from '~/diffs/components/diff_row_utils';
diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js
index 25d1935c7cd..2c8f751804e 100644
--- a/spec/frontend/diffs/components/diff_view_spec.js
+++ b/spec/frontend/diffs/components/diff_view_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { throttle } from 'lodash';
import DiffView from '~/diffs/components/diff_view.vue';
diff --git a/spec/frontend/diffs/components/tree_list_spec.js b/spec/frontend/diffs/components/tree_list_spec.js
index f56dd28ce9c..a54cf9b8bff 100644
--- a/spec/frontend/diffs/components/tree_list_spec.js
+++ b/spec/frontend/diffs/components/tree_list_spec.js
@@ -1,4 +1,5 @@
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import TreeList from '~/diffs/components/tree_list.vue';
import createStore from '~/diffs/store/modules';
diff --git a/spec/frontend/diffs/create_diffs_store.js b/spec/frontend/diffs/create_diffs_store.js
index 92f38858ca5..6ffba1fe035 100644
--- a/spec/frontend/diffs/create_diffs_store.js
+++ b/spec/frontend/diffs/create_diffs_store.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import batchCommentsModule from '~/batch_comments/stores/modules/batch_comments';
import diffsModule from '~/diffs/store/modules';
diff --git a/spec/frontend/error_tracking/components/error_details_spec.js b/spec/frontend/error_tracking/components/error_details_spec.js
index 6ef34504da7..d6cf12587b9 100644
--- a/spec/frontend/error_tracking/components/error_details_spec.js
+++ b/spec/frontend/error_tracking/components/error_details_spec.js
@@ -12,6 +12,7 @@ import {
} from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { severityLevel, severityLevelVariant, errorStatus } from '~/error_tracking/constants';
import ErrorDetails from '~/error_tracking/components/error_details.vue';
diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
index 49f365e8c60..a9cd407f758 100644
--- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js
+++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
@@ -8,6 +8,7 @@ import {
} from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children';
import ErrorTrackingActions from '~/error_tracking/components/error_tracking_actions.vue';
diff --git a/spec/frontend/error_tracking_settings/components/app_spec.js b/spec/frontend/error_tracking_settings/components/app_spec.js
index 9b7701d46bc..2e50e3aa90a 100644
--- a/spec/frontend/error_tracking_settings/components/app_spec.js
+++ b/spec/frontend/error_tracking_settings/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlFormRadioGroup, GlFormRadio, GlFormInputGroup } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import { TEST_HOST } from 'helpers/test_constants';
diff --git a/spec/frontend/error_tracking_settings/components/error_tracking_form_spec.js b/spec/frontend/error_tracking_settings/components/error_tracking_form_spec.js
index b1cf5d673f1..57c06eae2aa 100644
--- a/spec/frontend/error_tracking_settings/components/error_tracking_form_spec.js
+++ b/spec/frontend/error_tracking_settings/components/error_tracking_form_spec.js
@@ -1,6 +1,7 @@
import { GlFormInput, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import ErrorTrackingForm from '~/error_tracking_settings/components/error_tracking_form.vue';
import createStore from '~/error_tracking_settings/store';
diff --git a/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js b/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
index 03d090c5314..6449fc8643c 100644
--- a/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
+++ b/spec/frontend/error_tracking_settings/components/project_dropdown_spec.js
@@ -2,6 +2,7 @@ import { GlCollapsibleListbox } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import { pick, clone } from 'lodash';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import ProjectDropdown from '~/error_tracking_settings/components/project_dropdown.vue';
import { defaultProps, projectList, staleProject } from '../mock';
diff --git a/spec/frontend/feature_flags/components/edit_feature_flag_spec.js b/spec/frontend/feature_flags/components/edit_feature_flag_spec.js
index b8d058e7bc5..813316ef437 100644
--- a/spec/frontend/feature_flags/components/edit_feature_flag_spec.js
+++ b/spec/frontend/feature_flags/components/edit_feature_flag_spec.js
@@ -2,6 +2,7 @@ import { GlToggle, GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking } from 'helpers/tracking_helper';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/feature_flags/components/feature_flags_spec.js b/spec/frontend/feature_flags/components/feature_flags_spec.js
index 790568b2450..de07e9b4588 100644
--- a/spec/frontend/feature_flags/components/feature_flags_spec.js
+++ b/spec/frontend/feature_flags/components/feature_flags_spec.js
@@ -1,6 +1,7 @@
import { GlAlert, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import Vue from 'vue';
import MockAdapter from 'axios-mock-adapter';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import { mountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/feature_flags/components/new_feature_flag_spec.js b/spec/frontend/feature_flags/components/new_feature_flag_spec.js
index c5418477661..7663110893b 100644
--- a/spec/frontend/feature_flags/components/new_feature_flag_spec.js
+++ b/spec/frontend/feature_flags/components/new_feature_flag_spec.js
@@ -1,6 +1,7 @@
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { TEST_HOST } from 'spec/test_constants';
import Form from '~/feature_flags/components/form.vue';
diff --git a/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js b/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
index 133796df3e4..45440d7568b 100644
--- a/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
+++ b/spec/frontend/feature_flags/components/strategies/gitlab_user_list_spec.js
@@ -1,6 +1,7 @@
import { GlCollapsibleListbox, GlListboxItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Api from '~/api';
import GitlabUserList from '~/feature_flags/components/strategies/gitlab_user_list.vue';
diff --git a/spec/frontend/feature_flags/components/strategy_spec.js b/spec/frontend/feature_flags/components/strategy_spec.js
index 1428d99aa76..ca6e338ac6c 100644
--- a/spec/frontend/feature_flags/components/strategy_spec.js
+++ b/spec/frontend/feature_flags/components/strategy_spec.js
@@ -2,6 +2,7 @@ import { GlAlert, GlFormSelect, GlLink, GlToken, GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import { last } from 'lodash';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Api from '~/api';
import NewEnvironmentsDropdown from '~/feature_flags/components/new_environments_dropdown.vue';
diff --git a/spec/frontend/frequent_items/components/app_spec.js b/spec/frontend/frequent_items/components/app_spec.js
index a8ae72eb4b3..122155a5d3f 100644
--- a/spec/frontend/frequent_items/components/app_spec.js
+++ b/spec/frontend/frequent_items/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlButton, GlIcon } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js b/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js
index 7c8592fdf0c..55d20ad603c 100644
--- a/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_list_item_spec.js
@@ -1,5 +1,6 @@
import { GlIcon } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { trimText } from 'helpers/text_helper';
diff --git a/spec/frontend/frequent_items/components/frequent_items_list_spec.js b/spec/frontend/frequent_items/components/frequent_items_list_spec.js
index dd6dd80af4f..8055b7a9c13 100644
--- a/spec/frontend/frequent_items/components/frequent_items_list_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_list_spec.js
@@ -1,4 +1,5 @@
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import frequentItemsListComponent from '~/frequent_items/components/frequent_items_list.vue';
diff --git a/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
index dfce88ca0a8..d6aa0f4e221 100644
--- a/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
+++ b/spec/frontend/frequent_items/components/frequent_items_search_input_spec.js
@@ -1,6 +1,7 @@
import { GlSearchBoxByType } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import searchComponent from '~/frequent_items/components/frequent_items_search_input.vue';
diff --git a/spec/frontend/header_search/components/app_spec.js b/spec/frontend/header_search/components/app_spec.js
index ad56b2dde24..0d0b6628bdf 100644
--- a/spec/frontend/header_search/components/app_spec.js
+++ b/spec/frontend/header_search/components/app_spec.js
@@ -1,5 +1,6 @@
import { GlSearchBoxByType, GlToken, GlIcon } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { mockTracking } from 'helpers/tracking_helper';
diff --git a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
index e77a9231b7a..868edb3e651 100644
--- a/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
+++ b/spec/frontend/header_search/components/header_search_autocomplete_items_spec.js
@@ -1,6 +1,7 @@
import { GlDropdownItem, GlLoadingIcon, GlAvatar, GlAlert, GlDropdownDivider } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import HeaderSearchAutocompleteItems from '~/header_search/components/header_search_autocomplete_items.vue';
import { LARGE_AVATAR_PX, SMALL_AVATAR_PX } from '~/header_search/constants';
diff --git a/spec/frontend/header_search/components/header_search_default_items_spec.js b/spec/frontend/header_search/components/header_search_default_items_spec.js
index 3768862d83e..acaad251bec 100644
--- a/spec/frontend/header_search/components/header_search_default_items_spec.js
+++ b/spec/frontend/header_search/components/header_search_default_items_spec.js
@@ -1,6 +1,7 @@
import { GlDropdownItem, GlDropdownSectionHeader } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import HeaderSearchDefaultItems from '~/header_search/components/header_search_default_items.vue';
import { MOCK_SEARCH_CONTEXT, MOCK_DEFAULT_SEARCH_OPTIONS } from '../mock_data';
diff --git a/spec/frontend/header_search/components/header_search_scoped_items_spec.js b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
index 51d67198f04..78ea148caac 100644
--- a/spec/frontend/header_search/components/header_search_scoped_items_spec.js
+++ b/spec/frontend/header_search/components/header_search_scoped_items_spec.js
@@ -1,6 +1,7 @@
import { GlDropdownItem, GlToken, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { trimText } from 'helpers/text_helper';
import HeaderSearchScopedItems from '~/header_search/components/header_search_scoped_items.vue';
diff --git a/spec/frontend/ide/components/branches/search_list_spec.js b/spec/frontend/ide/components/branches/search_list_spec.js
index eeab26f7559..a2c3044a291 100644
--- a/spec/frontend/ide/components/branches/search_list_spec.js
+++ b/spec/frontend/ide/components/branches/search_list_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Item from '~/ide/components/branches/item.vue';
import List from '~/ide/components/branches/search_list.vue';
diff --git a/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js b/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js
index ce43e648b43..2313c177bb6 100644
--- a/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/editor_header_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import EditorHeader from '~/ide/components/commit_sidebar/editor_header.vue';
import { stubComponent } from 'helpers/stub_component';
diff --git a/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js b/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js
index ce26519abc9..c5e540c3ea7 100644
--- a/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js
+++ b/spec/frontend/ide/components/commit_sidebar/new_merge_request_option_spec.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { GlFormCheckbox } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/ide/components/error_message_spec.js b/spec/frontend/ide/components/error_message_spec.js
index 5f6579654bc..0ffcce8e834 100644
--- a/spec/frontend/ide/components/error_message_spec.js
+++ b/spec/frontend/ide/components/error_message_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import ErrorMessage from '~/ide/components/error_message.vue';
diff --git a/spec/frontend/ide/components/file_row_extra_spec.js b/spec/frontend/ide/components/file_row_extra_spec.js
index f5a6e7222f9..2ce4ea8a808 100644
--- a/spec/frontend/ide/components/file_row_extra_spec.js
+++ b/spec/frontend/ide/components/file_row_extra_spec.js
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mount } from '@vue/test-utils';
import FileRowExtra from '~/ide/components/file_row_extra.vue';
diff --git a/spec/frontend/ide/components/file_templates/dropdown_spec.js b/spec/frontend/ide/components/file_templates/dropdown_spec.js
index 72fdd05eb2c..9ccdaf8b916 100644
--- a/spec/frontend/ide/components/file_templates/dropdown_spec.js
+++ b/spec/frontend/ide/components/file_templates/dropdown_spec.js
@@ -2,6 +2,7 @@ import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import $ from 'jquery';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Dropdown from '~/ide/components/file_templates/dropdown.vue';
diff --git a/spec/frontend/ide/components/ide_file_row_spec.js b/spec/frontend/ide/components/ide_file_row_spec.js
index 331877ff112..c9d4c23b475 100644
--- a/spec/frontend/ide/components/ide_file_row_spec.js
+++ b/spec/frontend/ide/components/ide_file_row_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import FileRowExtra from '~/ide/components/file_row_extra.vue';
import IdeFileRow from '~/ide/components/ide_file_row.vue';
diff --git a/spec/frontend/ide/components/ide_review_spec.js b/spec/frontend/ide/components/ide_review_spec.js
index 59b87144e70..01d5ef763ad 100644
--- a/spec/frontend/ide/components/ide_review_spec.js
+++ b/spec/frontend/ide/components/ide_review_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { keepAlive } from 'helpers/keep_alive_component_helper';
import { trimText } from 'helpers/text_helper';
diff --git a/spec/frontend/ide/components/ide_side_bar_spec.js b/spec/frontend/ide/components/ide_side_bar_spec.js
index c258c5312d8..fe92bd2c51e 100644
--- a/spec/frontend/ide/components/ide_side_bar_spec.js
+++ b/spec/frontend/ide/components/ide_side_bar_spec.js
@@ -1,6 +1,7 @@
import { GlSkeletonLoader } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import IdeReview from '~/ide/components/ide_review.vue';
diff --git a/spec/frontend/ide/components/ide_spec.js b/spec/frontend/ide/components/ide_spec.js
index eb8f2a5e4ac..26bd6d468e7 100644
--- a/spec/frontend/ide/components/ide_spec.js
+++ b/spec/frontend/ide/components/ide_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import { stubPerformanceWebAPI } from 'helpers/performance';
diff --git a/spec/frontend/ide/components/ide_status_list_spec.js b/spec/frontend/ide/components/ide_status_list_spec.js
index 344a1fbc4f6..e353a4de054 100644
--- a/spec/frontend/ide/components/ide_status_list_spec.js
+++ b/spec/frontend/ide/components/ide_status_list_spec.js
@@ -1,6 +1,7 @@
import { GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import IdeStatusList from '~/ide/components/ide_status_list.vue';
import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue';
diff --git a/spec/frontend/ide/components/ide_tree_spec.js b/spec/frontend/ide/components/ide_tree_spec.js
index bcfa6809eca..1d6158d1e96 100644
--- a/spec/frontend/ide/components/ide_tree_spec.js
+++ b/spec/frontend/ide/components/ide_tree_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { viewerTypes } from '~/ide/constants';
import IdeTree from '~/ide/components/ide_tree.vue';
diff --git a/spec/frontend/ide/components/jobs/list_spec.js b/spec/frontend/ide/components/jobs/list_spec.js
index 0ece42bce51..c466ef8e96f 100644
--- a/spec/frontend/ide/components/jobs/list_spec.js
+++ b/spec/frontend/ide/components/jobs/list_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import StageList from '~/ide/components/jobs/list.vue';
import Stage from '~/ide/components/jobs/stage.vue';
diff --git a/spec/frontend/ide/components/merge_requests/item_spec.js b/spec/frontend/ide/components/merge_requests/item_spec.js
index 2fbb6919b8b..4bfcdebb8f6 100644
--- a/spec/frontend/ide/components/merge_requests/item_spec.js
+++ b/spec/frontend/ide/components/merge_requests/item_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Item from '~/ide/components/merge_requests/item.vue';
import { createRouter } from '~/ide/ide_router';
diff --git a/spec/frontend/ide/components/merge_requests/list_spec.js b/spec/frontend/ide/components/merge_requests/list_spec.js
index 3b0e8c632fb..b123ea13966 100644
--- a/spec/frontend/ide/components/merge_requests/list_spec.js
+++ b/spec/frontend/ide/components/merge_requests/list_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Item from '~/ide/components/merge_requests/item.vue';
import List from '~/ide/components/merge_requests/list.vue';
diff --git a/spec/frontend/ide/components/new_dropdown/index_spec.js b/spec/frontend/ide/components/new_dropdown/index_spec.js
index a2371abe955..a26ebec6824 100644
--- a/spec/frontend/ide/components/new_dropdown/index_spec.js
+++ b/spec/frontend/ide/components/new_dropdown/index_spec.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import NewDropdown from '~/ide/components/new_dropdown/index.vue';
diff --git a/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js b/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js
index 42eb5b3fc7a..56e62829971 100644
--- a/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js
+++ b/spec/frontend/ide/components/panes/collapsible_sidebar_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import IdeSidebarNav from '~/ide/components/ide_sidebar_nav.vue';
import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
diff --git a/spec/frontend/ide/components/panes/right_spec.js b/spec/frontend/ide/components/panes/right_spec.js
index 832983edf21..fc75eadbfe0 100644
--- a/spec/frontend/ide/components/panes/right_spec.js
+++ b/spec/frontend/ide/components/panes/right_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
import RightPane from '~/ide/components/panes/right.vue';
diff --git a/spec/frontend/ide/components/pipelines/list_spec.js b/spec/frontend/ide/components/pipelines/list_spec.js
index e913fa84d56..9c11ae9334b 100644
--- a/spec/frontend/ide/components/pipelines/list_spec.js
+++ b/spec/frontend/ide/components/pipelines/list_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlTab } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { pipelines } from 'jest/ide/mock_data';
import JobsList from '~/ide/components/jobs/list.vue';
diff --git a/spec/frontend/ide/components/repo_editor_spec.js b/spec/frontend/ide/components/repo_editor_spec.js
index aa99b1cacef..33fa5bc799f 100644
--- a/spec/frontend/ide/components/repo_editor_spec.js
+++ b/spec/frontend/ide/components/repo_editor_spec.js
@@ -2,6 +2,7 @@ import { GlTab } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
import { editor as monacoEditor, Range } from 'monaco-editor';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMount } from '@vue/test-utils';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/ide/components/repo_tab_spec.js b/spec/frontend/ide/components/repo_tab_spec.js
index d4f29b16a88..08e8062a45a 100644
--- a/spec/frontend/ide/components/repo_tab_spec.js
+++ b/spec/frontend/ide/components/repo_tab_spec.js
@@ -1,5 +1,6 @@
import { GlTab } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { stubComponent } from 'helpers/stub_component';
import RepoTab from '~/ide/components/repo_tab.vue';
diff --git a/spec/frontend/ide/components/repo_tabs_spec.js b/spec/frontend/ide/components/repo_tabs_spec.js
index 06ad162d398..9ced4babf1d 100644
--- a/spec/frontend/ide/components/repo_tabs_spec.js
+++ b/spec/frontend/ide/components/repo_tabs_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import RepoTabs from '~/ide/components/repo_tabs.vue';
import { createStore } from '~/ide/stores';
diff --git a/spec/frontend/ide/components/resizable_panel_spec.js b/spec/frontend/ide/components/resizable_panel_spec.js
index 240e675a38e..0529ea1918d 100644
--- a/spec/frontend/ide/components/resizable_panel_spec.js
+++ b/spec/frontend/ide/components/resizable_panel_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import ResizablePanel from '~/ide/components/resizable_panel.vue';
import { SIDE_LEFT, SIDE_RIGHT } from '~/ide/constants';
diff --git a/spec/frontend/ide/components/terminal/session_spec.js b/spec/frontend/ide/components/terminal/session_spec.js
index 7e4a56b0610..c7d9663834d 100644
--- a/spec/frontend/ide/components/terminal/session_spec.js
+++ b/spec/frontend/ide/components/terminal/session_spec.js
@@ -1,6 +1,7 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import TerminalSession from '~/ide/components/terminal/session.vue';
import Terminal from '~/ide/components/terminal/terminal.vue';
diff --git a/spec/frontend/ide/components/terminal/terminal_spec.js b/spec/frontend/ide/components/terminal/terminal_spec.js
index 0500c116d23..cc11c1f2f32 100644
--- a/spec/frontend/ide/components/terminal/terminal_spec.js
+++ b/spec/frontend/ide/components/terminal/terminal_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Terminal from '~/ide/components/terminal/terminal.vue';
import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
diff --git a/spec/frontend/ide/components/terminal/view_spec.js b/spec/frontend/ide/components/terminal/view_spec.js
index b8ffaa89047..2db3a163e3d 100644
--- a/spec/frontend/ide/components/terminal/view_spec.js
+++ b/spec/frontend/ide/components/terminal/view_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import { TEST_HOST } from 'spec/test_constants';
diff --git a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js
index e420e28c7b6..c5ec64ba6b2 100644
--- a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js
+++ b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_safe_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue';
import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue';
diff --git a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js
index 4541c3b5ec8..a39ceefdd3e 100644
--- a/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js
+++ b/spec/frontend/ide/components/terminal_sync/terminal_sync_status_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue';
import {
diff --git a/spec/frontend/ide/stores/modules/editor/setup_spec.js b/spec/frontend/ide/stores/modules/editor/setup_spec.js
index 659bfb2742f..df0dfb6f260 100644
--- a/spec/frontend/ide/stores/modules/editor/setup_spec.js
+++ b/spec/frontend/ide/stores/modules/editor/setup_spec.js
@@ -1,4 +1,5 @@
import { cloneDeep } from 'lodash';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import eventHub from '~/ide/eventhub';
import { createStoreOptions } from '~/ide/stores';
diff --git a/spec/frontend/ide/stores/plugins/terminal_spec.js b/spec/frontend/ide/stores/plugins/terminal_spec.js
index 193300540fd..b2d5d85e005 100644
--- a/spec/frontend/ide/stores/plugins/terminal_spec.js
+++ b/spec/frontend/ide/stores/plugins/terminal_spec.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants';
import terminalModule from '~/ide/stores/modules/terminal';
diff --git a/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js b/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js
index 7eebff7364c..0b9e7a8cb73 100644
--- a/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/github_status_table_spec.js
@@ -1,6 +1,7 @@
import { GlTabs, GlSearchBoxByClick } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { stubComponent } from 'helpers/stub_component';
diff --git a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
index 351bbe5ea28..92d064846bd 100644
--- a/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/import_projects_table_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon, GlButton, GlIntersectionObserver, GlSearchBoxByClick } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { STATUSES } from '~/import_entities/constants';
import ImportProjectsTable from '~/import_entities/import_projects/components/import_projects_table.vue';
diff --git a/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js b/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
index 9e4838ed020..b4890c09fe2 100644
--- a/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
+++ b/spec/frontend/import_entities/import_projects/components/provider_repo_table_row_spec.js
@@ -1,5 +1,6 @@
import { GlBadge, GlButton } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/issues/show/components/app_spec.js b/spec/frontend/issues/show/components/app_spec.js
index ecca3e69ef6..de183f94277 100644
--- a/spec/frontend/issues/show/components/app_spec.js
+++ b/spec/frontend/issues/show/components/app_spec.js
@@ -1,5 +1,6 @@
import { GlIcon, GlIntersectionObserver } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
+import { nextTick } from 'vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -10,6 +11,7 @@ import {
STATUS_OPEN,
STATUS_REOPENED,
TYPE_EPIC,
+ TYPE_INCIDENT,
TYPE_ISSUE,
} from '~/issues/constants';
import IssuableApp from '~/issues/show/components/app.vue';
@@ -79,6 +81,13 @@ describe('Issuable output', () => {
return waitForPromises();
};
+ const createComponentAndScroll = async (props) => {
+ await createComponent({ props });
+ global.pageYOffset = 100;
+ wrapper.findComponent(GlIntersectionObserver).vm.$emit('disappear');
+ await nextTick();
+ };
+
const emitHubEvent = (event) => {
eventHub.$emit(event);
return waitForPromises();
@@ -320,57 +329,51 @@ describe('Issuable output', () => {
});
describe('sticky header', () => {
- beforeEach(async () => {
- await createComponent();
- });
-
describe('when title is in view', () => {
- it('is not shown', () => {
+ it('is not shown', async () => {
+ await createComponent();
wrapper.findComponent(GlIntersectionObserver).vm.$emit('disappear');
+
expect(findStickyHeader().exists()).toBe(false);
});
});
describe('when title is not in view', () => {
- beforeEach(() => {
- global.pageYOffset = 100;
- wrapper.findComponent(GlIntersectionObserver).vm.$emit('disappear');
- });
-
- it('shows with title', () => {
- expect(findStickyHeader().text()).toContain(initialRequest.title_text);
- });
-
- it('shows with title for an epic', async () => {
- await wrapper.setProps({ issuableType: 'epic' });
+ it.each([TYPE_INCIDENT, TYPE_ISSUE, TYPE_EPIC])(
+ 'shows with title when issuableType="%s"',
+ async (issuableType) => {
+ await createComponentAndScroll({ issuableType });
- expect(findStickyHeader().text()).toContain(' this is a title');
- });
+ expect(findStickyHeader().text()).toContain('this is a title');
+ },
+ );
it.each`
- issuableType | issuableStatus | statusIcon
- ${TYPE_ISSUE} | ${STATUS_OPEN} | ${'issues'}
- ${TYPE_ISSUE} | ${STATUS_CLOSED} | ${'issue-closed'}
- ${TYPE_EPIC} | ${STATUS_OPEN} | ${'epic'}
- ${TYPE_EPIC} | ${STATUS_CLOSED} | ${'epic-closed'}
+ issuableType | issuableStatus | statusIcon
+ ${TYPE_INCIDENT} | ${STATUS_OPEN} | ${'issues'}
+ ${TYPE_INCIDENT} | ${STATUS_CLOSED} | ${'issue-closed'}
+ ${TYPE_ISSUE} | ${STATUS_OPEN} | ${'issues'}
+ ${TYPE_ISSUE} | ${STATUS_CLOSED} | ${'issue-closed'}
+ ${TYPE_EPIC} | ${STATUS_OPEN} | ${'epic'}
+ ${TYPE_EPIC} | ${STATUS_CLOSED} | ${'epic-closed'}
`(
'shows with state icon "$statusIcon" for $issuableType when status is $issuableStatus',
async ({ issuableType, issuableStatus, statusIcon }) => {
- await wrapper.setProps({ issuableType, issuableStatus });
+ await createComponentAndScroll({ issuableType, issuableStatus });
expect(findStickyHeader().findComponent(GlIcon).props('name')).toBe(statusIcon);
},
);
it.each`
- title | state
+ title | issuableStatus
${'shows with Open when status is opened'} | ${STATUS_OPEN}
${'shows with Closed when status is closed'} | ${STATUS_CLOSED}
${'shows with Open when status is reopened'} | ${STATUS_REOPENED}
- `('$title', async ({ state }) => {
- await wrapper.setProps({ issuableStatus: state });
+ `('$title', async ({ issuableStatus }) => {
+ await createComponentAndScroll({ issuableStatus });
- expect(findStickyHeader().text()).toContain(issuableStatusText[state]);
+ expect(findStickyHeader().text()).toContain(issuableStatusText[issuableStatus]);
});
it.each`
@@ -378,10 +381,11 @@ describe('Issuable output', () => {
${'does not show confidential badge when issue is not confidential'} | ${false}
${'shows confidential badge when issue is confidential'} | ${true}
`('$title', async ({ isConfidential }) => {
- await wrapper.setProps({ isConfidential });
-
+ await createComponentAndScroll({ isConfidential });
const confidentialEl = findConfidentialBadge();
+
expect(confidentialEl.exists()).toBe(isConfidential);
+
if (isConfidential) {
expect(confidentialEl.props()).toMatchObject({
workspaceType: 'project',
@@ -395,8 +399,7 @@ describe('Issuable output', () => {
${'does not show locked badge when issue is not locked'} | ${false}
${'shows locked badge when issue is locked'} | ${true}
`('$title', async ({ isLocked }) => {
- await wrapper.setProps({ isLocked });
-
+ await createComponentAndScroll({ isLocked });
const lockedBadge = findLockedBadge();
expect(lockedBadge.exists()).toBe(isLocked);
@@ -414,8 +417,7 @@ describe('Issuable output', () => {
${'does not show hidden badge when issue is not hidden'} | ${false}
${'shows hidden badge when issue is hidden'} | ${true}
`('$title', async ({ isHidden }) => {
- await wrapper.setProps({ isHidden });
-
+ await createComponentAndScroll({ isHidden });
const hiddenBadge = findHiddenBadge();
expect(hiddenBadge.exists()).toBe(isHidden);
diff --git a/spec/frontend/issues/show/components/header_actions_spec.js b/spec/frontend/issues/show/components/header_actions_spec.js
index 8a98b2b702a..ce2161f4670 100644
--- a/spec/frontend/issues/show/components/header_actions_spec.js
+++ b/spec/frontend/issues/show/components/header_actions_spec.js
@@ -1,6 +1,7 @@
import Vue, { nextTick } from 'vue';
import { GlDropdown, GlDropdownItem, GlLink, GlModal, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import VueApollo from 'vue-apollo';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/issues/show/components/issue_header_spec.js b/spec/frontend/issues/show/components/issue_header_spec.js
index 721801714aa..6acc7004576 100644
--- a/spec/frontend/issues/show/components/issue_header_spec.js
+++ b/spec/frontend/issues/show/components/issue_header_spec.js
@@ -22,6 +22,7 @@ describe('IssueHeader component', () => {
isHidden: false,
isLocked: false,
issuableState: 'opened',
+ issuableType: 'issue',
movedToIssueUrl: '',
promotedToEpicUrl: '',
...props,
diff --git a/spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js b/spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js
index 02b20b9e7b7..6fa84432032 100644
--- a/spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js
+++ b/spec/frontend/issues/show/components/sentry_error_stack_trace_spec.js
@@ -1,6 +1,7 @@
import Vue from 'vue';
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Stacktrace from '~/error_tracking/components/stacktrace.vue';
import SentryErrorStackTrace from '~/issues/show/components/sentry_error_stack_trace.vue';
diff --git a/spec/frontend/jobs/components/job/job_app_spec.js b/spec/frontend/jobs/components/job/job_app_spec.js
index c925131dd9c..8f5700ee22d 100644
--- a/spec/frontend/jobs/components/job/job_app_spec.js
+++ b/spec/frontend/jobs/components/job/job_app_spec.js
@@ -1,4 +1,5 @@
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui';
import MockAdapter from 'axios-mock-adapter';
diff --git a/spec/frontend/jobs/components/log/log_spec.js b/spec/frontend/jobs/components/log/log_spec.js
index 20638b13169..9407b340950 100644
--- a/spec/frontend/jobs/components/log/log_spec.js
+++ b/spec/frontend/jobs/components/log/log_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import { scrollToElement } from '~/lib/utils/common_utils';
diff --git a/spec/frontend/lib/utils/vuex_module_mappers_spec.js b/spec/frontend/lib/utils/vuex_module_mappers_spec.js
index abd5095c1d2..9070903728b 100644
--- a/spec/frontend/lib/utils/vuex_module_mappers_spec.js
+++ b/spec/frontend/lib/utils/vuex_module_mappers_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import {
mapVuexModuleActions,
diff --git a/spec/frontend/members/components/action_buttons/approve_access_request_button_spec.js b/spec/frontend/members/components/action_buttons/approve_access_request_button_spec.js
index 7a4cd844425..3e88246ada0 100644
--- a/spec/frontend/members/components/action_buttons/approve_access_request_button_spec.js
+++ b/spec/frontend/members/components/action_buttons/approve_access_request_button_spec.js
@@ -1,6 +1,7 @@
import { GlButton, GlForm } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import ApproveAccessRequestButton from '~/members/components/action_buttons/approve_access_request_button.vue';
diff --git a/spec/frontend/members/components/action_buttons/remove_group_link_button_spec.js b/spec/frontend/members/components/action_buttons/remove_group_link_button_spec.js
index 1d83a2e0e71..24a936abc99 100644
--- a/spec/frontend/members/components/action_buttons/remove_group_link_button_spec.js
+++ b/spec/frontend/members/components/action_buttons/remove_group_link_button_spec.js
@@ -1,6 +1,7 @@
import { GlButton } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import RemoveGroupLinkButton from '~/members/components/action_buttons/remove_group_link_button.vue';
diff --git a/spec/frontend/members/components/action_buttons/remove_member_button_spec.js b/spec/frontend/members/components/action_buttons/remove_member_button_spec.js
index 3879279b559..84393cb64ea 100644
--- a/spec/frontend/members/components/action_buttons/remove_member_button_spec.js
+++ b/spec/frontend/members/components/action_buttons/remove_member_button_spec.js
@@ -1,6 +1,7 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { modalData } from 'jest/members/mock_data';
diff --git a/spec/frontend/members/components/action_buttons/resend_invite_button_spec.js b/spec/frontend/members/components/action_buttons/resend_invite_button_spec.js
index a6b5978b566..50facbf7f5d 100644
--- a/spec/frontend/members/components/action_buttons/resend_invite_button_spec.js
+++ b/spec/frontend/members/components/action_buttons/resend_invite_button_spec.js
@@ -1,6 +1,7 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import ResendInviteButton from '~/members/components/action_buttons/resend_invite_button.vue';
diff --git a/spec/frontend/members/components/action_dropdowns/remove_member_dropdown_item_spec.js b/spec/frontend/members/components/action_dropdowns/remove_member_dropdown_item_spec.js
index 2f0d4b8e655..be53c48c9fd 100644
--- a/spec/frontend/members/components/action_dropdowns/remove_member_dropdown_item_spec.js
+++ b/spec/frontend/members/components/action_dropdowns/remove_member_dropdown_item_spec.js
@@ -1,6 +1,7 @@
import { GlDisclosureDropdownItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { modalData } from 'jest/members/mock_data';
import RemoveMemberDropdownItem from '~/members/components/action_dropdowns/remove_member_dropdown_item.vue';
diff --git a/spec/frontend/members/components/app_spec.js b/spec/frontend/members/components/app_spec.js
index b2147163233..929a5a054e6 100644
--- a/spec/frontend/members/components/app_spec.js
+++ b/spec/frontend/members/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlAlert } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import * as commonUtils from '~/lib/utils/common_utils';
import MembersApp from '~/members/components/app.vue';
diff --git a/spec/frontend/members/components/filter_sort/filter_sort_container_spec.js b/spec/frontend/members/components/filter_sort/filter_sort_container_spec.js
index de2f6e6dd47..6bb51b4633c 100644
--- a/spec/frontend/members/components/filter_sort/filter_sort_container_spec.js
+++ b/spec/frontend/members/components/filter_sort/filter_sort_container_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import FilterSortContainer from '~/members/components/filter_sort/filter_sort_container.vue';
import MembersFilteredSearchBar from '~/members/components/filter_sort/members_filtered_search_bar.vue';
diff --git a/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js b/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js
index 29b7ceae0e3..107bd2f0985 100644
--- a/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js
+++ b/spec/frontend/members/components/filter_sort/members_filtered_search_bar_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
import { redirectTo } from '~/lib/utils/url_utility'; // eslint-disable-line import/no-deprecated
diff --git a/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js b/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js
index 526f839ece8..849a84b1a6f 100644
--- a/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js
+++ b/spec/frontend/members/components/filter_sort/sort_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlSorting, GlSortingItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
import * as urlUtilities from '~/lib/utils/url_utility';
diff --git a/spec/frontend/members/components/members_tabs_spec.js b/spec/frontend/members/components/members_tabs_spec.js
index 9078bd87d62..de2f8c9f4c6 100644
--- a/spec/frontend/members/components/members_tabs_spec.js
+++ b/spec/frontend/members/components/members_tabs_spec.js
@@ -1,5 +1,6 @@
import { GlTabs, GlButton } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/members/components/modals/leave_modal_spec.js b/spec/frontend/members/components/modals/leave_modal_spec.js
index cec5f192e59..95a4fb07853 100644
--- a/spec/frontend/members/components/modals/leave_modal_spec.js
+++ b/spec/frontend/members/components/modals/leave_modal_spec.js
@@ -1,6 +1,7 @@
import { GlModal, GlForm } from '@gitlab/ui';
import { cloneDeep } from 'lodash';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import LeaveModal from '~/members/components/modals/leave_modal.vue';
diff --git a/spec/frontend/members/components/modals/remove_group_link_modal_spec.js b/spec/frontend/members/components/modals/remove_group_link_modal_spec.js
index e4782ac7f2e..bde33528eb8 100644
--- a/spec/frontend/members/components/modals/remove_group_link_modal_spec.js
+++ b/spec/frontend/members/components/modals/remove_group_link_modal_spec.js
@@ -2,6 +2,7 @@ import { GlModal, GlForm } from '@gitlab/ui';
import { within } from '@testing-library/dom';
import { mount, createWrapper } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import RemoveGroupLinkModal from '~/members/components/modals/remove_group_link_modal.vue';
import { REMOVE_GROUP_LINK_MODAL_ID, MEMBER_TYPES } from '~/members/constants';
diff --git a/spec/frontend/members/components/modals/remove_member_modal_spec.js b/spec/frontend/members/components/modals/remove_member_modal_spec.js
index baef0b30b02..01138ff845d 100644
--- a/spec/frontend/members/components/modals/remove_member_modal_spec.js
+++ b/spec/frontend/members/components/modals/remove_member_modal_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import RemoveMemberModal from '~/members/components/modals/remove_member_modal.vue';
import {
diff --git a/spec/frontend/members/components/table/expiration_datepicker_spec.js b/spec/frontend/members/components/table/expiration_datepicker_spec.js
index 9176a02a447..d9847abda52 100644
--- a/spec/frontend/members/components/table/expiration_datepicker_spec.js
+++ b/spec/frontend/members/components/table/expiration_datepicker_spec.js
@@ -1,6 +1,7 @@
import { GlDatepicker } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { useFakeDate } from 'helpers/fake_date';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/members/components/table/members_table_cell_spec.js b/spec/frontend/members/components/table/members_table_cell_spec.js
index 1c6f1b086cf..099fe7b4b8a 100644
--- a/spec/frontend/members/components/table/members_table_cell_spec.js
+++ b/spec/frontend/members/components/table/members_table_cell_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import MembersTableCell from '~/members/components/table/members_table_cell.vue';
import { MEMBER_TYPES } from '~/members/constants';
diff --git a/spec/frontend/members/components/table/members_table_spec.js b/spec/frontend/members/components/table/members_table_spec.js
index efc8c9b4459..4539478bf9a 100644
--- a/spec/frontend/members/components/table/members_table_spec.js
+++ b/spec/frontend/members/components/table/members_table_spec.js
@@ -1,5 +1,6 @@
import { GlBadge, GlPagination, GlTable } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
import { mountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/members/components/table/role_dropdown_spec.js b/spec/frontend/members/components/table/role_dropdown_spec.js
index fa188f50d54..5204ac2fdbe 100644
--- a/spec/frontend/members/components/table/role_dropdown_spec.js
+++ b/spec/frontend/members/components/table/role_dropdown_spec.js
@@ -3,6 +3,7 @@ import { GlBreakpointInstance as bp } from '@gitlab/ui/dist/utils';
import * as Sentry from '@sentry/browser';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import RoleDropdown from '~/members/components/table/role_dropdown.vue';
diff --git a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
index ab913b30f3c..edd18c57f43 100644
--- a/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
+++ b/spec/frontend/merge_conflicts/components/merge_conflict_resolver_app_spec.js
@@ -1,5 +1,6 @@
import { GlSprintf } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended, extendedWrapper } from 'helpers/vue_test_utils_helper';
import InlineConflictLines from '~/merge_conflicts/components/inline_conflict_lines.vue';
diff --git a/spec/frontend/milestones/components/milestone_combobox_spec.js b/spec/frontend/milestones/components/milestone_combobox_spec.js
index 748e01d4291..53abf6dc544 100644
--- a/spec/frontend/milestones/components/milestone_combobox_spec.js
+++ b/spec/frontend/milestones/components/milestone_combobox_spec.js
@@ -3,6 +3,7 @@ import { mount } from '@vue/test-utils';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { HTTP_STATUS_INTERNAL_SERVER_ERROR, HTTP_STATUS_OK } from '~/lib/utils/http_status';
import { ENTER_KEY } from '~/lib/utils/keys';
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index b68e68eb4fe..0728646246d 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -3,6 +3,7 @@ import { mount, shallowMount } from '@vue/test-utils';
import Autosize from 'autosize';
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { useLocalStorageSpy } from 'helpers/local_storage_helper';
diff --git a/spec/frontend/notes/components/discussion_counter_spec.js b/spec/frontend/notes/components/discussion_counter_spec.js
index e52dd87f784..64cb42af316 100644
--- a/spec/frontend/notes/components/discussion_counter_spec.js
+++ b/spec/frontend/notes/components/discussion_counter_spec.js
@@ -1,6 +1,7 @@
import { GlDisclosureDropdown, GlDisclosureDropdownItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DiscussionCounter from '~/notes/components/discussion_counter.vue';
import notesModule from '~/notes/stores/modules';
diff --git a/spec/frontend/notes/components/discussion_filter_spec.js b/spec/frontend/notes/components/discussion_filter_spec.js
index 7d8347b20d4..87ccb5b7394 100644
--- a/spec/frontend/notes/components/discussion_filter_spec.js
+++ b/spec/frontend/notes/components/discussion_filter_spec.js
@@ -2,6 +2,7 @@ import { GlDisclosureDropdown, GlDisclosureDropdownItem } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import AxiosMockAdapter from 'axios-mock-adapter';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants';
import createEventHub from '~/helpers/event_hub_factory';
diff --git a/spec/frontend/notes/components/mr_discussion_filter_spec.js b/spec/frontend/notes/components/mr_discussion_filter_spec.js
index 2bb47fd3c9e..05576d2ccc6 100644
--- a/spec/frontend/notes/components/mr_discussion_filter_spec.js
+++ b/spec/frontend/notes/components/mr_discussion_filter_spec.js
@@ -1,6 +1,7 @@
import { mount } from '@vue/test-utils';
import { GlCollapsibleListbox, GlListboxItem, GlButton } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DiscussionFilter from '~/notes/components/mr_discussion_filter.vue';
import { MR_FILTER_OPTIONS } from '~/notes/constants';
diff --git a/spec/frontend/notes/components/multiline_comment_form_spec.js b/spec/frontend/notes/components/multiline_comment_form_spec.js
index 8446bba340f..feba016e427 100644
--- a/spec/frontend/notes/components/multiline_comment_form_spec.js
+++ b/spec/frontend/notes/components/multiline_comment_form_spec.js
@@ -1,6 +1,7 @@
import { GlFormSelect } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import MultilineCommentForm from '~/notes/components/multiline_comment_form.vue';
import notesModule from '~/notes/stores/modules';
diff --git a/spec/frontend/notes/components/note_awards_list_spec.js b/spec/frontend/notes/components/note_awards_list_spec.js
index 0107b27f980..fd4d04129ea 100644
--- a/spec/frontend/notes/components/note_awards_list_spec.js
+++ b/spec/frontend/notes/components/note_awards_list_spec.js
@@ -1,5 +1,6 @@
import AxiosMockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants';
import { mountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/notes/components/note_body_spec.js b/spec/frontend/notes/components/note_body_spec.js
index c4f8e50b969..622038171b3 100644
--- a/spec/frontend/notes/components/note_body_spec.js
+++ b/spec/frontend/notes/components/note_body_spec.js
@@ -1,3 +1,4 @@
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/notes/components/note_header_spec.js b/spec/frontend/notes/components/note_header_spec.js
index 9535e98b79f..54f2bcd09ed 100644
--- a/spec/frontend/notes/components/note_header_spec.js
+++ b/spec/frontend/notes/components/note_header_spec.js
@@ -1,4 +1,5 @@
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import NoteHeader from '~/notes/components/note_header.vue';
diff --git a/spec/frontend/notes/components/noteable_discussion_spec.js b/spec/frontend/notes/components/noteable_discussion_spec.js
index 36f89e479e6..1b1b64f34d7 100644
--- a/spec/frontend/notes/components/noteable_discussion_spec.js
+++ b/spec/frontend/notes/components/noteable_discussion_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import MockAdapter from 'axios-mock-adapter';
import discussionWithTwoUnresolvedNotes from 'test_fixtures/merge_requests/resolved_diff_discussion.json';
diff --git a/spec/frontend/notes/components/noteable_note_spec.js b/spec/frontend/notes/components/noteable_note_spec.js
index 059972df56b..825a856e5fa 100644
--- a/spec/frontend/notes/components/noteable_note_spec.js
+++ b/spec/frontend/notes/components/noteable_note_spec.js
@@ -1,4 +1,5 @@
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { GlAvatarLink, GlAvatar } from '@gitlab/ui';
import { clone } from 'lodash';
diff --git a/spec/frontend/notes/components/timeline_toggle_spec.js b/spec/frontend/notes/components/timeline_toggle_spec.js
index caa6f95d5da..a8411584c8d 100644
--- a/spec/frontend/notes/components/timeline_toggle_spec.js
+++ b/spec/frontend/notes/components/timeline_toggle_spec.js
@@ -1,6 +1,7 @@
import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import TimelineToggle, {
timelineEnabledTooltip,
diff --git a/spec/frontend/notes/mixins/discussion_navigation_spec.js b/spec/frontend/notes/mixins/discussion_navigation_spec.js
index bef8ed8e659..128fa0979f7 100644
--- a/spec/frontend/notes/mixins/discussion_navigation_spec.js
+++ b/spec/frontend/notes/mixins/discussion_navigation_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures';
import createEventHub from '~/helpers/event_hub_factory';
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/group_empty_state_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/group_empty_state_spec.js
index 900ea61e4ea..e512edea554 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/group_empty_state_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/group_empty_state_spec.js
@@ -1,6 +1,7 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import groupEmptyState from '~/packages_and_registries/container_registry/explorer/components/list_page/group_empty_state.vue';
import { GlEmptyState } from '../../stubs';
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/project_empty_state_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/project_empty_state_spec.js
index e4d13143484..23e7a9e1982 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/project_empty_state_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/project_empty_state_spec.js
@@ -1,6 +1,7 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import projectEmptyState from '~/packages_and_registries/container_registry/explorer/components/list_page/project_empty_state.vue';
import { dockerCommands } from '../../mock_data';
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
index f8130287c12..204134f1ee9 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlEmptyState } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
import stubChildren from 'helpers/stub_children';
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
index 7f56d3e216c..8e5386fc954 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/details_title_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import component from '~/packages_and_registries/infrastructure_registry/details/components/details_title.vue';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js
index 94797f01d16..9bdd0e438d3 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/terraform_installation_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import TerraformInstallation from '~/packages_and_registries/infrastructure_registry/details/components/terraform_installation.vue';
import CodeInstructions from '~/vue_shared/components/registry/code_instruction.vue';
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_search_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_search_spec.js
index a89247c0a97..2f252047d82 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_search_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/infrastructure_search_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import component from '~/packages_and_registries/infrastructure_registry/list/components/infrastructure_search.vue';
import RegistrySearch from '~/vue_shared/components/registry/registry_search.vue';
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js
index 47d36d11e35..eb905fbec40 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_app_spec.js
@@ -1,6 +1,7 @@
import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import setWindowLocation from 'helpers/set_window_location_helper';
import { createAlert, VARIANT_INFO } from '~/alert';
diff --git a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
index 51445942eaa..ad906d41435 100644
--- a/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
+++ b/spec/frontend/packages_and_registries/infrastructure_registry/components/list/components/packages_list_spec.js
@@ -2,6 +2,7 @@ import { GlTable, GlPagination } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
import { last } from 'lodash';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import stubChildren from 'helpers/stub_children';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
diff --git a/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js b/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
index 41482e6e681..328f83394f9 100644
--- a/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
+++ b/spec/frontend/packages_and_registries/shared/components/cli_commands_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import QuickstartDropdown from '~/packages_and_registries/shared/components/cli_commands.vue';
import {
diff --git a/spec/frontend/pipelines/pipelines_spec.js b/spec/frontend/pipelines/pipelines_spec.js
index 5b77d44c5bd..cc85d6d99e0 100644
--- a/spec/frontend/pipelines/pipelines_spec.js
+++ b/spec/frontend/pipelines/pipelines_spec.js
@@ -744,9 +744,8 @@ describe('Pipelines', () => {
createComponent();
- stopMock = jest.spyOn(wrapper.vm.poll, 'stop');
- restartMock = jest.spyOn(wrapper.vm.poll, 'restart');
- cancelMock = jest.spyOn(wrapper.vm.service.cancelationSource, 'cancel');
+ stopMock = jest.spyOn(window, 'clearTimeout');
+ restartMock = jest.spyOn(axios, 'get');
});
describe('when a request is being made', () => {
@@ -765,13 +764,15 @@ describe('Pipelines', () => {
// cancelMock is getting overwritten in pipelines_service.js#L29
// so we have to spy on it again here
- cancelMock = jest.spyOn(wrapper.vm.service.cancelationSource, 'cancel');
+ cancelMock = jest.spyOn(axios.CancelToken, 'source');
await waitForPromises();
expect(cancelMock).toHaveBeenCalled();
expect(stopMock).toHaveBeenCalled();
- expect(restartMock).toHaveBeenCalled();
+ expect(restartMock).toHaveBeenCalledWith(
+ `${mockPipelinesResponse.pipelines[0].path}/stage.json?stage=build`,
+ );
});
it('stops polling & restarts polling', async () => {
@@ -781,7 +782,9 @@ describe('Pipelines', () => {
expect(cancelMock).not.toHaveBeenCalled();
expect(stopMock).toHaveBeenCalled();
- expect(restartMock).toHaveBeenCalled();
+ expect(restartMock).toHaveBeenCalledWith(
+ `${mockPipelinesResponse.pipelines[0].path}/stage.json?stage=build`,
+ );
});
});
});
diff --git a/spec/frontend/pipelines/test_reports/test_reports_spec.js b/spec/frontend/pipelines/test_reports/test_reports_spec.js
index c8c917a1b9e..de16f496eff 100644
--- a/spec/frontend/pipelines/test_reports/test_reports_spec.js
+++ b/spec/frontend/pipelines/test_reports/test_reports_spec.js
@@ -1,6 +1,7 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import testReports from 'test_fixtures/pipelines/test_report.json';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js b/spec/frontend/pipelines/test_reports/test_suite_table_spec.js
index 8eb83f17f4d..08b430fa703 100644
--- a/spec/frontend/pipelines/test_reports/test_suite_table_spec.js
+++ b/spec/frontend/pipelines/test_reports/test_suite_table_spec.js
@@ -1,5 +1,6 @@
import { GlButton, GlFriendlyWrap, GlLink, GlPagination, GlEmptyState } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import testReports from 'test_fixtures/pipelines/test_report.json';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/pipelines/test_reports/test_summary_table_spec.js b/spec/frontend/pipelines/test_reports/test_summary_table_spec.js
index cfe9ff564dc..a45946d5a03 100644
--- a/spec/frontend/pipelines/test_reports/test_summary_table_spec.js
+++ b/spec/frontend/pipelines/test_reports/test_summary_table_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import testReports from 'test_fixtures/pipelines/test_report.json';
import SummaryTable from '~/pipelines/components/test_reports/test_summary_table.vue';
diff --git a/spec/frontend/projects/commit/components/branches_dropdown_spec.js b/spec/frontend/projects/commit/components/branches_dropdown_spec.js
index bff40c2bc39..6c595b81455 100644
--- a/spec/frontend/projects/commit/components/branches_dropdown_spec.js
+++ b/spec/frontend/projects/commit/components/branches_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlCollapsibleListbox } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import BranchesDropdown from '~/projects/commit/components/branches_dropdown.vue';
diff --git a/spec/frontend/projects/commit/components/projects_dropdown_spec.js b/spec/frontend/projects/commit/components/projects_dropdown_spec.js
index baf2ea2656f..725840cb60b 100644
--- a/spec/frontend/projects/commit/components/projects_dropdown_spec.js
+++ b/spec/frontend/projects/commit/components/projects_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlCollapsibleListbox } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ProjectsDropdown from '~/projects/commit/components/projects_dropdown.vue';
diff --git a/spec/frontend/projects/commits/components/author_select_spec.js b/spec/frontend/projects/commits/components/author_select_spec.js
index 50e3f2d0f37..d345407c15e 100644
--- a/spec/frontend/projects/commits/components/author_select_spec.js
+++ b/spec/frontend/projects/commits/components/author_select_spec.js
@@ -1,6 +1,7 @@
import { GlCollapsibleListbox, GlListboxItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { resetHTMLFixture, setHTMLFixture } from 'helpers/fixtures';
import setWindowLocation from 'helpers/set_window_location_helper';
diff --git a/spec/frontend/ref/components/ref_selector_spec.js b/spec/frontend/ref/components/ref_selector_spec.js
index 290cde29866..12ca0d053e9 100644
--- a/spec/frontend/ref/components/ref_selector_spec.js
+++ b/spec/frontend/ref/components/ref_selector_spec.js
@@ -3,6 +3,7 @@ import Vue, { nextTick } from 'vue';
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { merge, last } from 'lodash';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import tags from 'test_fixtures/api/tags/tags.json';
import commit from 'test_fixtures/api/commits/commit.json';
diff --git a/spec/frontend/releases/components/app_edit_new_spec.js b/spec/frontend/releases/components/app_edit_new_spec.js
index 69d8969f0ad..15436832be8 100644
--- a/spec/frontend/releases/components/app_edit_new_spec.js
+++ b/spec/frontend/releases/components/app_edit_new_spec.js
@@ -1,6 +1,7 @@
import axios from 'axios';
import MockAdapter from 'axios-mock-adapter';
import { merge } from 'lodash';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { nextTick } from 'vue';
import { GlDatepicker, GlFormCheckbox } from '@gitlab/ui';
diff --git a/spec/frontend/releases/components/asset_links_form_spec.js b/spec/frontend/releases/components/asset_links_form_spec.js
index 8eee9acd808..53e78170f4a 100644
--- a/spec/frontend/releases/components/asset_links_form_spec.js
+++ b/spec/frontend/releases/components/asset_links_form_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import originalRelease from 'test_fixtures/api/releases/release.json';
import * as commonUtils from '~/lib/utils/common_utils';
diff --git a/spec/frontend/releases/components/confirm_delete_modal_spec.js b/spec/frontend/releases/components/confirm_delete_modal_spec.js
index b4699302779..42ddb0dc12c 100644
--- a/spec/frontend/releases/components/confirm_delete_modal_spec.js
+++ b/spec/frontend/releases/components/confirm_delete_modal_spec.js
@@ -1,4 +1,5 @@
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { GlModal } from '@gitlab/ui';
import originalOneReleaseForEditingQueryResponse from 'test_fixtures/graphql/releases/graphql/queries/one_release_for_editing.query.graphql.json';
diff --git a/spec/frontend/releases/components/tag_field_exsting_spec.js b/spec/frontend/releases/components/tag_field_exsting_spec.js
index 0e896eb645c..14b2fe32239 100644
--- a/spec/frontend/releases/components/tag_field_exsting_spec.js
+++ b/spec/frontend/releases/components/tag_field_exsting_spec.js
@@ -1,6 +1,7 @@
import { GlFormInput } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import TagFieldExisting from '~/releases/components/tag_field_existing.vue';
import createStore from '~/releases/stores';
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index a3fab889801..5ac2627dc5d 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -1,5 +1,6 @@
import { GlLoadingIcon } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Vue, { nextTick } from 'vue';
import axios from 'axios';
diff --git a/spec/frontend/search/sidebar/components/app_spec.js b/spec/frontend/search/sidebar/components/app_spec.js
index 83eb4cd3ab7..a4559c2dc34 100644
--- a/spec/frontend/search/sidebar/components/app_spec.js
+++ b/spec/frontend/search/sidebar/components/app_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_QUERY } from 'jest/search/mock_data';
import GlobalSearchSidebar from '~/search/sidebar/components/app.vue';
diff --git a/spec/frontend/search/sidebar/components/archived_filter_spec.js b/spec/frontend/search/sidebar/components/archived_filter_spec.js
index 2838cb60fa1..69bf2ebd72e 100644
--- a/spec/frontend/search/sidebar/components/archived_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/archived_filter_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { GlFormCheckboxGroup } from '@gitlab/ui';
import ArchivedFilter from '~/search/sidebar/components/archived_filter/index.vue';
diff --git a/spec/frontend/search/sidebar/components/checkbox_filter_spec.js b/spec/frontend/search/sidebar/components/checkbox_filter_spec.js
index 54fdf6e869e..b551e8c659c 100644
--- a/spec/frontend/search/sidebar/components/checkbox_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/checkbox_filter_spec.js
@@ -1,5 +1,6 @@
import { GlFormCheckboxGroup, GlFormCheckbox } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/search/sidebar/components/confidentiality_filter_spec.js b/spec/frontend/search/sidebar/components/confidentiality_filter_spec.js
index 68054a341a2..6444ec10466 100644
--- a/spec/frontend/search/sidebar/components/confidentiality_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/confidentiality_filter_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import ConfidentialityFilter from '~/search/sidebar/components/confidentiality_filter/index.vue';
import RadioFilter from '~/search/sidebar/components/radio_filter.vue';
diff --git a/spec/frontend/search/sidebar/components/filters_spec.js b/spec/frontend/search/sidebar/components/filters_spec.js
index 42508d7e216..d3c774929f5 100644
--- a/spec/frontend/search/sidebar/components/filters_spec.js
+++ b/spec/frontend/search/sidebar/components/filters_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_QUERY } from 'jest/search/mock_data';
import IssuesFilters from '~/search/sidebar/components/issues_filters.vue';
diff --git a/spec/frontend/search/sidebar/components/filters_template_spec.js b/spec/frontend/search/sidebar/components/filters_template_spec.js
index 11c7c541b54..f1a807c5ceb 100644
--- a/spec/frontend/search/sidebar/components/filters_template_spec.js
+++ b/spec/frontend/search/sidebar/components/filters_template_spec.js
@@ -1,5 +1,6 @@
import { GlForm, GlButton, GlLink } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
diff --git a/spec/frontend/search/sidebar/components/issues_filters_spec.js b/spec/frontend/search/sidebar/components/issues_filters_spec.js
index cab3a78bd34..84c4258cbdb 100644
--- a/spec/frontend/search/sidebar/components/issues_filters_spec.js
+++ b/spec/frontend/search/sidebar/components/issues_filters_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_QUERY } from 'jest/search/mock_data';
import IssuesFilters from '~/search/sidebar/components/issues_filters.vue';
diff --git a/spec/frontend/search/sidebar/components/label_dropdown_items_spec.js b/spec/frontend/search/sidebar/components/label_dropdown_items_spec.js
index 135b12956b2..9124da5cfe1 100644
--- a/spec/frontend/search/sidebar/components/label_dropdown_items_spec.js
+++ b/spec/frontend/search/sidebar/components/label_dropdown_items_spec.js
@@ -1,5 +1,6 @@
import { GlFormCheckbox } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMount } from '@vue/test-utils';
import { PROCESS_LABELS_DATA } from 'jest/search/mock_data';
diff --git a/spec/frontend/search/sidebar/components/label_filter_spec.js b/spec/frontend/search/sidebar/components/label_filter_spec.js
index 2a5b3a96045..07b2e176610 100644
--- a/spec/frontend/search/sidebar/components/label_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/label_filter_spec.js
@@ -9,6 +9,7 @@ import {
GlDropdownDivider,
} from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { mountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/search/sidebar/components/language_filter_spec.js b/spec/frontend/search/sidebar/components/language_filter_spec.js
index 88be8f908d7..b45f365e1e1 100644
--- a/spec/frontend/search/sidebar/components/language_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/language_filter_spec.js
@@ -1,5 +1,6 @@
import { GlAlert, GlFormCheckbox } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/search/sidebar/components/radio_filter_spec.js b/spec/frontend/search/sidebar/components/radio_filter_spec.js
index b5f2b9bb6dd..b99daf9e2f3 100644
--- a/spec/frontend/search/sidebar/components/radio_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/radio_filter_spec.js
@@ -1,6 +1,7 @@
import { GlFormRadioGroup, GlFormRadio } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_QUERY } from 'jest/search/mock_data';
import RadioFilter from '~/search/sidebar/components/radio_filter.vue';
diff --git a/spec/frontend/search/sidebar/components/scope_legacy_navigation_spec.js b/spec/frontend/search/sidebar/components/scope_legacy_navigation_spec.js
index 786ad806ea6..63d8b34fcf0 100644
--- a/spec/frontend/search/sidebar/components/scope_legacy_navigation_spec.js
+++ b/spec/frontend/search/sidebar/components/scope_legacy_navigation_spec.js
@@ -1,6 +1,7 @@
import { GlNav, GlNavItem, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_QUERY, MOCK_NAVIGATION } from 'jest/search/mock_data';
import ScopeLegacyNavigation from '~/search/sidebar/components/scope_legacy_navigation.vue';
diff --git a/spec/frontend/search/sidebar/components/scope_sidebar_navigation_spec.js b/spec/frontend/search/sidebar/components/scope_sidebar_navigation_spec.js
index 86939bdc5d6..d85942b9634 100644
--- a/spec/frontend/search/sidebar/components/scope_sidebar_navigation_spec.js
+++ b/spec/frontend/search/sidebar/components/scope_sidebar_navigation_spec.js
@@ -1,5 +1,6 @@
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import ScopeSidebarNavigation from '~/search/sidebar/components/scope_sidebar_navigation.vue';
import NavItem from '~/super_sidebar/components/nav_item.vue';
diff --git a/spec/frontend/search/sidebar/components/status_filter_spec.js b/spec/frontend/search/sidebar/components/status_filter_spec.js
index fd705d5976b..c230341c172 100644
--- a/spec/frontend/search/sidebar/components/status_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/status_filter_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import RadioFilter from '~/search/sidebar/components/radio_filter.vue';
import StatusFilter from '~/search/sidebar/components/status_filter/index.vue';
diff --git a/spec/frontend/search/sort/components/app_spec.js b/spec/frontend/search/sort/components/app_spec.js
index 09c295e3ea9..f701952701c 100644
--- a/spec/frontend/search/sort/components/app_spec.js
+++ b/spec/frontend/search/sort/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlButtonGroup, GlButton, GlCollapsibleListbox, GlListboxItem } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_QUERY, MOCK_SORT_OPTIONS } from 'jest/search/mock_data';
import GlobalSearchSort from '~/search/sort/components/app.vue';
diff --git a/spec/frontend/search/topbar/components/app_spec.js b/spec/frontend/search/topbar/components/app_spec.js
index 9dc14b97ce0..62d0e377d74 100644
--- a/spec/frontend/search/topbar/components/app_spec.js
+++ b/spec/frontend/search/topbar/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlSearchBoxByClick, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_QUERY } from 'jest/search/mock_data';
import { stubComponent } from 'helpers/stub_component';
diff --git a/spec/frontend/search/topbar/components/group_filter_spec.js b/spec/frontend/search/topbar/components/group_filter_spec.js
index 94882d181d3..fa8036a7f97 100644
--- a/spec/frontend/search/topbar/components/group_filter_spec.js
+++ b/spec/frontend/search/topbar/components/group_filter_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_GROUP, MOCK_QUERY, CURRENT_SCOPE } from 'jest/search/mock_data';
import { visitUrl, setUrlParams } from '~/lib/utils/url_utility';
diff --git a/spec/frontend/search/topbar/components/project_filter_spec.js b/spec/frontend/search/topbar/components/project_filter_spec.js
index c25d2b94027..e7808370098 100644
--- a/spec/frontend/search/topbar/components/project_filter_spec.js
+++ b/spec/frontend/search/topbar/components/project_filter_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { MOCK_PROJECT, MOCK_QUERY, CURRENT_SCOPE } from 'jest/search/mock_data';
import { visitUrl, setUrlParams } from '~/lib/utils/url_utility';
diff --git a/spec/frontend/search/topbar/components/searchable_dropdown_spec.js b/spec/frontend/search/topbar/components/searchable_dropdown_spec.js
index f7d847674eb..5acaa1c1900 100644
--- a/spec/frontend/search/topbar/components/searchable_dropdown_spec.js
+++ b/spec/frontend/search/topbar/components/searchable_dropdown_spec.js
@@ -1,6 +1,7 @@
import { GlDropdown, GlDropdownItem, GlSearchBoxByType, GlSkeletonLoader } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { MOCK_GROUPS, MOCK_GROUP, MOCK_QUERY } from 'jest/search/mock_data';
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_button_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_button_spec.js
index 084ca5ed3fc..2ca19c0927a 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_button_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_button_spec.js
@@ -1,6 +1,7 @@
import { GlIcon, GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DropdownButton from '~/sidebar/components/labels/labels_select_vue/dropdown_button.vue';
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_create_view_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_create_view_spec.js
index 7e53fcfe850..cd391765dde 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_create_view_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_create_view_spec.js
@@ -1,5 +1,6 @@
import { GlButton, GlFormInput, GlLink, GlLoadingIcon } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DropdownContentsCreateView from '~/sidebar/components/labels/labels_select_vue/dropdown_contents_create_view.vue';
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
index 5c6358a94ab..392171390e1 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
@@ -6,6 +6,7 @@ import {
GlLink,
} from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
import DropdownContentsLabelsView from '~/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view.vue';
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_spec.js
index d74cea2827c..fa04089a681 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DropdownContents from '~/sidebar/components/labels/labels_select_vue/dropdown_contents.vue';
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_title_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_title_spec.js
index 367f6007194..3603ef64a9b 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_title_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_title_spec.js
@@ -1,6 +1,7 @@
import { GlButton, GlLoadingIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DropdownTitle from '~/sidebar/components/labels/labels_select_vue/dropdown_title.vue';
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_value_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_value_spec.js
index 70aafceb00c..656b5ef5cd8 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_value_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_value_spec.js
@@ -1,6 +1,7 @@
import { GlLabel } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import DropdownValue from '~/sidebar/components/labels/labels_select_vue/dropdown_value.vue';
diff --git a/spec/frontend/sidebar/components/labels/labels_select_vue/labels_select_root_spec.js b/spec/frontend/sidebar/components/labels/labels_select_vue/labels_select_root_spec.js
index 3add96f2c03..32ca7c24217 100644
--- a/spec/frontend/sidebar/components/labels/labels_select_vue/labels_select_root_spec.js
+++ b/spec/frontend/sidebar/components/labels/labels_select_vue/labels_select_root_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { isInViewport } from '~/lib/utils/common_utils';
diff --git a/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js b/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
index da79daebb93..e1c41fb8b46 100644
--- a/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
+++ b/spec/frontend/sidebar/components/lock/issuable_lock_form_spec.js
@@ -1,6 +1,7 @@
import { GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, triggerEvent } from 'helpers/tracking_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
diff --git a/spec/frontend/super_sidebar/components/global_search/components/global_search_autocomplete_items_spec.js b/spec/frontend/super_sidebar/components/global_search/components/global_search_autocomplete_items_spec.js
index aac321bd8e0..5af9b0372f7 100644
--- a/spec/frontend/super_sidebar/components/global_search/components/global_search_autocomplete_items_spec.js
+++ b/spec/frontend/super_sidebar/components/global_search/components/global_search_autocomplete_items_spec.js
@@ -7,6 +7,7 @@ import {
} from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import GlobalSearchAutocompleteItems from '~/super_sidebar/components/global_search/components/global_search_autocomplete_items.vue';
diff --git a/spec/frontend/super_sidebar/components/global_search/components/global_search_default_issuables_spec.js b/spec/frontend/super_sidebar/components/global_search/components/global_search_default_issuables_spec.js
index 934cb1678df..8130cceb61d 100644
--- a/spec/frontend/super_sidebar/components/global_search/components/global_search_default_issuables_spec.js
+++ b/spec/frontend/super_sidebar/components/global_search/components/global_search_default_issuables_spec.js
@@ -1,5 +1,6 @@
import { GlDisclosureDropdownGroup, GlDisclosureDropdownItem } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMount } from '@vue/test-utils';
import GlobalSearchDefaultIssuables from '~/super_sidebar/components/global_search/components/global_search_default_issuables.vue';
diff --git a/spec/frontend/super_sidebar/components/global_search/components/global_search_default_items_spec.js b/spec/frontend/super_sidebar/components/global_search/components/global_search_default_items_spec.js
index 18a6e4aa35a..48844c565e3 100644
--- a/spec/frontend/super_sidebar/components/global_search/components/global_search_default_items_spec.js
+++ b/spec/frontend/super_sidebar/components/global_search/components/global_search_default_items_spec.js
@@ -1,4 +1,5 @@
import { shallowMount } from '@vue/test-utils';
+
import GlobalSearchDefaultItems from '~/super_sidebar/components/global_search/components/global_search_default_items.vue';
import GlobalSearchDefaultPlaces from '~/super_sidebar/components/global_search/components/global_search_default_places.vue';
import GlobalSearchDefaultIssuables from '~/super_sidebar/components/global_search/components/global_search_default_issuables.vue';
diff --git a/spec/frontend/super_sidebar/components/global_search/components/global_search_scoped_items_spec.js b/spec/frontend/super_sidebar/components/global_search/components/global_search_scoped_items_spec.js
index 4976f3be4cd..164eea991e5 100644
--- a/spec/frontend/super_sidebar/components/global_search/components/global_search_scoped_items_spec.js
+++ b/spec/frontend/super_sidebar/components/global_search/components/global_search_scoped_items_spec.js
@@ -1,6 +1,7 @@
import { GlDisclosureDropdownGroup, GlDisclosureDropdownItem, GlToken, GlIcon } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { trimText } from 'helpers/text_helper';
import GlobalSearchScopedItems from '~/super_sidebar/components/global_search/components/global_search_scoped_items.vue';
diff --git a/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js b/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js
index 3c44075ab21..f9a6690a391 100644
--- a/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js
+++ b/spec/frontend/super_sidebar/components/global_search/components/global_search_spec.js
@@ -1,5 +1,6 @@
import { GlModal, GlSearchBoxByType, GlToken, GlIcon } from '@gitlab/ui';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { s__, sprintf } from '~/locale';
diff --git a/spec/frontend/super_sidebar/components/user_bar_spec.js b/spec/frontend/super_sidebar/components/user_bar_spec.js
index d90553dfdd3..c6dd8441094 100644
--- a/spec/frontend/super_sidebar/components/user_bar_spec.js
+++ b/spec/frontend/super_sidebar/components/user_bar_spec.js
@@ -1,4 +1,5 @@
import { GlBadge } from '@gitlab/ui';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Vue, { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
diff --git a/spec/frontend/user_lists/components/edit_user_list_spec.js b/spec/frontend/user_lists/components/edit_user_list_spec.js
index 21a883aefe0..5656c5ebf60 100644
--- a/spec/frontend/user_lists/components/edit_user_list_spec.js
+++ b/spec/frontend/user_lists/components/edit_user_list_spec.js
@@ -1,6 +1,7 @@
import { GlAlert, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
diff --git a/spec/frontend/user_lists/components/new_user_list_spec.js b/spec/frontend/user_lists/components/new_user_list_spec.js
index 004cfb6ca07..f2c4d29d05a 100644
--- a/spec/frontend/user_lists/components/new_user_list_spec.js
+++ b/spec/frontend/user_lists/components/new_user_list_spec.js
@@ -1,6 +1,7 @@
import { GlAlert } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
diff --git a/spec/frontend/user_lists/components/user_list_spec.js b/spec/frontend/user_lists/components/user_list_spec.js
index e02862cad2b..286fb9fef5f 100644
--- a/spec/frontend/user_lists/components/user_list_spec.js
+++ b/spec/frontend/user_lists/components/user_list_spec.js
@@ -2,6 +2,7 @@ import { GlAlert, GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { uniq } from 'lodash';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import Api from '~/api';
import UserList from '~/user_lists/components/user_list.vue';
diff --git a/spec/frontend/user_lists/components/user_lists_spec.js b/spec/frontend/user_lists/components/user_lists_spec.js
index 0164e7e49b2..ec892104a1c 100644
--- a/spec/frontend/user_lists/components/user_lists_spec.js
+++ b/spec/frontend/user_lists/components/user_lists_spec.js
@@ -2,6 +2,7 @@ import { GlEmptyState, GlLoadingIcon } from '@gitlab/ui';
import { within } from '@testing-library/dom';
import { mount, createWrapper } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import waitForPromises from 'helpers/wait_for_promises';
import Api from '~/api';
diff --git a/spec/frontend/vue_merge_request_widget/components/artifacts_list_app_spec.js b/spec/frontend/vue_merge_request_widget/components/artifacts_list_app_spec.js
index 9516aacea0a..79cfd2fd1ed 100644
--- a/spec/frontend/vue_merge_request_widget/components/artifacts_list_app_spec.js
+++ b/spec/frontend/vue_merge_request_widget/components/artifacts_list_app_spec.js
@@ -2,6 +2,7 @@ import { GlLoadingIcon } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { TEST_HOST as FAKE_ENDPOINT } from 'helpers/test_constants';
import axios from '~/lib/utils/axios_utils';
diff --git a/spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js b/spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js
index 0d536b23c45..2f165338577 100644
--- a/spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js
+++ b/spec/frontend/vue_shared/components/diff_viewer/viewers/renamed_spec.js
@@ -1,5 +1,6 @@
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { GlAlert, GlLink, GlLoadingIcon } from '@gitlab/ui';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
index 6dc018797a6..271214907fc 100644
--- a/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
+++ b/spec/frontend/vue_shared/components/gl_modal_vuex_spec.js
@@ -1,6 +1,7 @@
import { GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { BV_SHOW_MODAL, BV_HIDE_MODAL } from '~/lib/utils/constants';
import GlModalVuex from '~/vue_shared/components/gl_modal_vuex.vue';
diff --git a/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js b/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
index 4b0b89fe1e7..36f5517decf 100644
--- a/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
+++ b/spec/frontend/vue_shared/components/metric_images/metric_images_tab_spec.js
@@ -2,6 +2,7 @@ import { GlFormInput, GlModal } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import merge from 'lodash/merge';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import MetricImagesTable from '~/vue_shared/components/metric_images/metric_images_table.vue';
import MetricImagesTab from '~/vue_shared/components/metric_images/metric_images_tab.vue';
diff --git a/spec/frontend/vue_shared/components/metric_images/metric_images_table_spec.js b/spec/frontend/vue_shared/components/metric_images/metric_images_table_spec.js
index 12dca95e9ba..ca141f53bf1 100644
--- a/spec/frontend/vue_shared/components/metric_images/metric_images_table_spec.js
+++ b/spec/frontend/vue_shared/components/metric_images/metric_images_table_spec.js
@@ -2,6 +2,7 @@ import { GlLink, GlModal } from '@gitlab/ui';
import { shallowMount, mount } from '@vue/test-utils';
import Vue from 'vue';
import merge from 'lodash/merge';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import createStore from '~/vue_shared/components/metric_images/store';
import MetricsImageTable from '~/vue_shared/components/metric_images/metric_images_table.vue';
diff --git a/spec/frontend/vue_shared/components/metric_images/store/actions_spec.js b/spec/frontend/vue_shared/components/metric_images/store/actions_spec.js
index 626f6fc735e..544466a22ca 100644
--- a/spec/frontend/vue_shared/components/metric_images/store/actions_spec.js
+++ b/spec/frontend/vue_shared/components/metric_images/store/actions_spec.js
@@ -1,4 +1,5 @@
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import actionsFactory from '~/vue_shared/components/metric_images/store/actions';
import * as types from '~/vue_shared/components/metric_images/store/mutation_types';
diff --git a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
index 7e669fb7c71..6d4745e8e3d 100644
--- a/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
+++ b/spec/frontend/vue_shared/components/notes/placeholder_note_spec.js
@@ -1,5 +1,6 @@
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import IssuePlaceholderNote from '~/vue_shared/components/notes/placeholder_note.vue';
import { userDataMock } from 'jest/notes/mock_data';
diff --git a/spec/frontend/whats_new/components/app_spec.js b/spec/frontend/whats_new/components/app_spec.js
index b74473b5494..c0954ac1133 100644
--- a/spec/frontend/whats_new/components/app_spec.js
+++ b/spec/frontend/whats_new/components/app_spec.js
@@ -1,6 +1,7 @@
import { GlDrawer, GlInfiniteScroll } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
+// eslint-disable-next-line no-restricted-imports
import Vuex from 'vuex';
import { mockTracking, unmockTracking, triggerEvent } from 'helpers/tracking_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
diff --git a/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb b/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb
index c651eae6bf2..4f565f5f811 100644
--- a/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb
+++ b/spec/lib/gitlab/ci/config/yaml/interpolator_spec.rb
@@ -9,199 +9,166 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli
subject { described_class.new(result, arguments) }
- # Remove shared examples when ci_interpolation_inputs_refactor is removed.
- shared_examples 'interpolator' do
- context 'when input data is valid' do
- let(:header) do
- { spec: { inputs: { website: nil } } }
- end
-
- let(:content) do
- { test: 'deploy $[[ inputs.website ]]' }
- end
-
- let(:arguments) do
- { website: 'gitlab.com' }
- end
-
- it 'correctly interpolates the config' do
- subject.interpolate!
-
- expect(subject).to be_interpolated
- expect(subject).to be_valid
- expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' })
- end
+ context 'when input data is valid' do
+ let(:header) do
+ { spec: { inputs: { website: nil } } }
end
- context 'when config has a syntax error' do
- let(:result) { ::Gitlab::Ci::Config::Yaml::Result.new(error: 'Invalid configuration format') }
+ let(:content) do
+ { test: 'deploy $[[ inputs.website ]]' }
+ end
- let(:arguments) do
- { website: 'gitlab.com' }
- end
+ let(:arguments) do
+ { website: 'gitlab.com' }
+ end
- it 'surfaces an error about invalid config' do
- subject.interpolate!
+ it 'correctly interpolates the config' do
+ subject.interpolate!
- expect(subject).not_to be_valid
- expect(subject.error_message).to eq subject.errors.first
- expect(subject.errors).to include 'Invalid configuration format'
- end
+ expect(subject).to be_interpolated
+ expect(subject).to be_valid
+ expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' })
end
+ end
- context 'when spec header is missing but inputs are specified' do
- let(:header) { nil }
- let(:content) { { test: 'echo' } }
- let(:arguments) { { foo: 'bar' } }
-
- it 'surfaces an error about invalid inputs' do
- subject.interpolate!
+ context 'when config has a syntax error' do
+ let(:result) { ::Gitlab::Ci::Config::Yaml::Result.new(error: 'Invalid configuration format') }
- expect(subject).not_to be_valid
- expect(subject.error_message).to eq subject.errors.first
- expect(subject.errors).to include('unknown input arguments')
- end
+ let(:arguments) do
+ { website: 'gitlab.com' }
end
- context 'when spec header is invalid' do
- let(:header) do
- { spec: { arguments: { website: nil } } }
- end
+ it 'surfaces an error about invalid config' do
+ subject.interpolate!
- let(:content) do
- { test: 'deploy $[[ inputs.website ]]' }
- end
+ expect(subject).not_to be_valid
+ expect(subject.error_message).to eq subject.errors.first
+ expect(subject.errors).to include 'Invalid configuration format'
+ end
+ end
- let(:arguments) do
- { website: 'gitlab.com' }
- end
+ context 'when spec header is missing but inputs are specified' do
+ let(:header) { nil }
+ let(:content) { { test: 'echo' } }
+ let(:arguments) { { foo: 'bar' } }
- it 'surfaces an error about invalid header' do
- subject.interpolate!
+ it 'surfaces an error about invalid inputs' do
+ subject.interpolate!
- expect(subject).not_to be_valid
- expect(subject.error_message).to eq subject.errors.first
- expect(subject.errors).to include('header:spec config contains unknown keys: arguments')
- end
+ expect(subject).not_to be_valid
+ expect(subject.error_message).to eq subject.errors.first
+ expect(subject.errors).to include('unknown input arguments')
end
+ end
- context 'when interpolation block is invalid' do
- let(:header) do
- { spec: { inputs: { website: nil } } }
- end
+ context 'when spec header is invalid' do
+ let(:header) do
+ { spec: { arguments: { website: nil } } }
+ end
- let(:content) do
- { test: 'deploy $[[ inputs.abc ]]' }
- end
+ let(:content) do
+ { test: 'deploy $[[ inputs.website ]]' }
+ end
- let(:arguments) do
- { website: 'gitlab.com' }
- end
+ let(:arguments) do
+ { website: 'gitlab.com' }
+ end
- it 'correctly interpolates the config' do
- subject.interpolate!
+ it 'surfaces an error about invalid header' do
+ subject.interpolate!
- expect(subject).not_to be_valid
- expect(subject.errors).to include 'unknown interpolation key: `abc`'
- expect(subject.error_message).to eq 'interpolation interrupted by errors, unknown interpolation key: `abc`'
- end
+ expect(subject).not_to be_valid
+ expect(subject.error_message).to eq subject.errors.first
+ expect(subject.errors).to include('header:spec config contains unknown keys: arguments')
end
+ end
- context 'when multiple interpolation blocks are invalid' do
- let(:header) do
- { spec: { inputs: { website: nil } } }
- end
+ context 'when provided interpolation argument is invalid' do
+ let(:header) do
+ { spec: { inputs: { website: nil } } }
+ end
- let(:content) do
- { test: 'deploy $[[ inputs.something.abc ]] $[[ inputs.cde ]] $[[ efg ]]' }
- end
+ let(:content) do
+ { test: 'deploy $[[ inputs.website ]]' }
+ end
- let(:arguments) do
- { website: 'gitlab.com' }
- end
+ let(:arguments) do
+ { website: ['gitlab.com'] }
+ end
- it 'correctly interpolates the config' do
- subject.interpolate!
+ it 'returns an error' do
+ subject.interpolate!
- expect(subject).not_to be_valid
- expect(subject.error_message)
- .to eq 'interpolation interrupted by errors, unknown interpolation key: `something`'
- end
+ expect(subject).not_to be_valid
+ expect(subject.error_message).to eq subject.errors.first
+ expect(subject.errors).to include '`website` input: provided value is not a string'
end
+ end
- describe '#to_hash' do
- context 'when interpolation is not used' do
- let(:result) do
- ::Gitlab::Ci::Config::Yaml::Result.new(config: content)
- end
+ context 'when interpolation block is invalid' do
+ let(:header) do
+ { spec: { inputs: { website: nil } } }
+ end
- let(:content) do
- { test: 'deploy production' }
- end
+ let(:content) do
+ { test: 'deploy $[[ inputs.abc ]]' }
+ end
- let(:arguments) { nil }
+ let(:arguments) do
+ { website: 'gitlab.com' }
+ end
- it 'returns original content' do
- subject.interpolate!
+ it 'returns an error' do
+ subject.interpolate!
- expect(subject.to_hash).to eq(content)
- end
- end
+ expect(subject).not_to be_valid
+ expect(subject.errors).to include 'unknown interpolation key: `abc`'
+ expect(subject.error_message).to eq 'interpolation interrupted by errors, unknown interpolation key: `abc`'
+ end
+ end
- context 'when interpolation is available' do
- let(:header) do
- { spec: { inputs: { website: nil } } }
- end
+ context 'when multiple interpolation blocks are invalid' do
+ let(:header) do
+ { spec: { inputs: { website: nil } } }
+ end
- let(:content) do
- { test: 'deploy $[[ inputs.website ]]' }
- end
+ let(:content) do
+ { test: 'deploy $[[ inputs.something.abc ]] $[[ inputs.cde ]] $[[ efg ]]' }
+ end
- let(:arguments) do
- { website: 'gitlab.com' }
- end
+ let(:arguments) do
+ { website: 'gitlab.com' }
+ end
- it 'correctly interpolates content' do
- subject.interpolate!
+ it 'returns an error' do
+ subject.interpolate!
- expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' })
- end
- end
+ expect(subject).not_to be_valid
+ expect(subject.error_message)
+ .to eq 'interpolation interrupted by errors, unknown interpolation key: `something`'
end
end
- it_behaves_like 'interpolator' do
- context 'when provided interpolation argument is invalid' do
- let(:header) do
- { spec: { inputs: { website: nil } } }
+ describe '#to_hash' do
+ context 'when interpolation is not used' do
+ let(:result) do
+ ::Gitlab::Ci::Config::Yaml::Result.new(config: content)
end
let(:content) do
- { test: 'deploy $[[ inputs.website ]]' }
+ { test: 'deploy production' }
end
- let(:arguments) do
- { website: ['gitlab.com'] }
- end
+ let(:arguments) { nil }
- it 'returns an error' do
+ it 'returns original content' do
subject.interpolate!
- expect(subject).not_to be_valid
- expect(subject.error_message).to eq subject.errors.first
- expect(subject.errors).to include '`website` input: provided value is not a string'
+ expect(subject.to_hash).to eq(content)
end
end
- end
- context 'when feature flag ci_interpolation_inputs_refactor is disabled' do
- before do
- stub_feature_flags(ci_interpolation_inputs_refactor: false)
- end
-
- it_behaves_like 'interpolator'
-
- context 'when provided interpolation argument is invalid' do
+ context 'when interpolation is available' do
let(:header) do
{ spec: { inputs: { website: nil } } }
end
@@ -211,15 +178,13 @@ RSpec.describe Gitlab::Ci::Config::Yaml::Interpolator, feature_category: :pipeli
end
let(:arguments) do
- { website: ['gitlab.com'] }
+ { website: 'gitlab.com' }
end
- it 'returns an error' do
+ it 'correctly interpolates content' do
subject.interpolate!
- expect(subject).not_to be_valid
- expect(subject.error_message).to eq subject.errors.first
- expect(subject.errors).to include 'unsupported value in input argument `website`'
+ expect(subject.to_hash).to eq({ test: 'deploy gitlab.com' })
end
end
end
diff --git a/spec/lib/gitlab/ci/input/arguments/base_spec.rb b/spec/lib/gitlab/ci/input/arguments/base_spec.rb
deleted file mode 100644
index ed8e99b7257..00000000000
--- a/spec/lib/gitlab/ci/input/arguments/base_spec.rb
+++ /dev/null
@@ -1,19 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::Ci::Input::Arguments::Base, feature_category: :pipeline_composition do
- subject do
- Class.new(described_class) do
- def validate!; end
- def to_value; end
- end
- end
-
- it 'fabricates an invalid input argument if unknown value is provided' do
- argument = subject.new(:something, { spec: 123 }, [:a, :b])
-
- expect(argument).not_to be_valid
- expect(argument.errors.first).to eq 'unsupported value in input argument `something`'
- end
-end
diff --git a/spec/lib/gitlab/ci/input/arguments/default_spec.rb b/spec/lib/gitlab/ci/input/arguments/default_spec.rb
deleted file mode 100644
index bc0cee6ac4e..00000000000
--- a/spec/lib/gitlab/ci/input/arguments/default_spec.rb
+++ /dev/null
@@ -1,53 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::Ci::Input::Arguments::Default, feature_category: :pipeline_composition do
- it 'returns a user-provided value if it is present' do
- argument = described_class.new(:website, { default: 'https://gitlab.com' }, 'https://example.gitlab.com')
-
- expect(argument).to be_valid
- expect(argument.to_value).to eq 'https://example.gitlab.com'
- expect(argument.to_hash).to eq({ website: 'https://example.gitlab.com' })
- end
-
- it 'returns an empty value if user-provider input is empty' do
- argument = described_class.new(:website, { default: 'https://gitlab.com' }, '')
-
- expect(argument).to be_valid
- expect(argument.to_value).to eq ''
- expect(argument.to_hash).to eq({ website: '' })
- end
-
- it 'returns a default value if user-provider one is unknown' do
- argument = described_class.new(:website, { default: 'https://gitlab.com' }, nil)
-
- expect(argument).to be_valid
- expect(argument.to_value).to eq 'https://gitlab.com'
- expect(argument.to_hash).to eq({ website: 'https://gitlab.com' })
- end
-
- it 'returns an error if the default argument has not been recognized' do
- argument = described_class.new(:website, { default: ['gitlab.com'] }, 'abc')
-
- expect(argument).not_to be_valid
- end
-
- it 'returns an error if the argument has not been fabricated correctly' do
- argument = described_class.new(:website, { required: 'https://gitlab.com' }, 'https://example.gitlab.com')
-
- expect(argument).not_to be_valid
- end
-
- describe '.matches?' do
- it 'matches specs with default configuration' do
- expect(described_class.matches?({ default: 'abc' })).to be true
- end
-
- it 'does not match specs different configuration keyword' do
- expect(described_class.matches?({ options: %w[a b] })).to be false
- expect(described_class.matches?('a b c')).to be false
- expect(described_class.matches?(%w[default a])).to be false
- end
- end
-end
diff --git a/spec/lib/gitlab/ci/input/arguments/options_spec.rb b/spec/lib/gitlab/ci/input/arguments/options_spec.rb
deleted file mode 100644
index 17e3469b294..00000000000
--- a/spec/lib/gitlab/ci/input/arguments/options_spec.rb
+++ /dev/null
@@ -1,54 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::Ci::Input::Arguments::Options, feature_category: :pipeline_composition do
- it 'returns a user-provided value if it is an allowed one' do
- argument = described_class.new(:run, { options: %w[opt1 opt2] }, 'opt1')
-
- expect(argument).to be_valid
- expect(argument.to_value).to eq 'opt1'
- expect(argument.to_hash).to eq({ run: 'opt1' })
- end
-
- it 'returns an error if user-provided value is not allowlisted' do
- argument = described_class.new(:run, { options: %w[opt1 opt2] }, 'opt3')
-
- expect(argument).not_to be_valid
- expect(argument.errors.first).to eq '`run` input: argument value opt3 not allowlisted'
- end
-
- it 'returns an error if specification is not correct' do
- argument = described_class.new(:website, { options: nil }, 'opt1')
-
- expect(argument).not_to be_valid
- expect(argument.errors.first).to eq '`website` input: argument specification invalid'
- end
-
- it 'returns an error if specification is using a hash' do
- argument = described_class.new(:website, { options: { a: 1 } }, 'opt1')
-
- expect(argument).not_to be_valid
- expect(argument.errors.first).to eq '`website` input: argument specification invalid'
- end
-
- it 'returns an empty value if it is allowlisted' do
- argument = described_class.new(:run, { options: ['opt1', ''] }, '')
-
- expect(argument).to be_valid
- expect(argument.to_value).to be_empty
- expect(argument.to_hash).to eq({ run: '' })
- end
-
- describe '.matches?' do
- it 'matches specs with options configuration' do
- expect(described_class.matches?({ options: %w[a b] })).to be true
- end
-
- it 'does not match specs different configuration keyword' do
- expect(described_class.matches?({ default: 'abc' })).to be false
- expect(described_class.matches?(['options'])).to be false
- expect(described_class.matches?('options')).to be false
- end
- end
-end
diff --git a/spec/lib/gitlab/ci/input/arguments/required_spec.rb b/spec/lib/gitlab/ci/input/arguments/required_spec.rb
deleted file mode 100644
index 847272998c2..00000000000
--- a/spec/lib/gitlab/ci/input/arguments/required_spec.rb
+++ /dev/null
@@ -1,45 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::Ci::Input::Arguments::Required, feature_category: :pipeline_composition do
- it 'returns a user-provided value if it is present' do
- argument = described_class.new(:website, nil, 'https://example.gitlab.com')
-
- expect(argument).to be_valid
- expect(argument.to_value).to eq 'https://example.gitlab.com'
- expect(argument.to_hash).to eq({ website: 'https://example.gitlab.com' })
- end
-
- it 'returns an empty value if user-provider value is empty' do
- argument = described_class.new(:website, nil, '')
-
- expect(argument).to be_valid
- expect(argument.to_hash).to eq(website: '')
- end
-
- it 'returns an error if user-provided value is unspecified' do
- argument = described_class.new(:website, nil, nil)
-
- expect(argument).not_to be_valid
- expect(argument.errors.first).to eq '`website` input: required value has not been provided'
- end
-
- describe '.matches?' do
- it 'matches specs without configuration' do
- expect(described_class.matches?(nil)).to be true
- end
-
- it 'matches specs with empty configuration' do
- expect(described_class.matches?('')).to be true
- end
-
- it 'matches specs with an empty hash configuration' do
- expect(described_class.matches?({})).to be true
- end
-
- it 'does not match specs with configuration' do
- expect(described_class.matches?({ options: %w[a b] })).to be false
- end
- end
-end
diff --git a/spec/lib/gitlab/ci/input/arguments/unknown_spec.rb b/spec/lib/gitlab/ci/input/arguments/unknown_spec.rb
deleted file mode 100644
index 1270423ac72..00000000000
--- a/spec/lib/gitlab/ci/input/arguments/unknown_spec.rb
+++ /dev/null
@@ -1,18 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::Ci::Input::Arguments::Unknown, feature_category: :pipeline_composition do
- it 'raises an error when someone tries to evaluate the value' do
- argument = described_class.new(:website, nil, 'https://example.gitlab.com')
-
- expect(argument).not_to be_valid
- expect { argument.to_value }.to raise_error ArgumentError
- end
-
- describe '.matches?' do
- it 'always matches' do
- expect(described_class.matches?('abc')).to be true
- end
- end
-end
diff --git a/spec/lib/gitlab/ci/input/inputs_spec.rb b/spec/lib/gitlab/ci/input/inputs_spec.rb
deleted file mode 100644
index 5d2d5192299..00000000000
--- a/spec/lib/gitlab/ci/input/inputs_spec.rb
+++ /dev/null
@@ -1,126 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-
-RSpec.describe Gitlab::Ci::Input::Inputs, feature_category: :pipeline_composition do
- describe '#valid?' do
- let(:spec) { { website: nil } }
-
- it 'describes user-provided inputs' do
- inputs = described_class.new(spec, { website: 'http://example.gitlab.com' })
-
- expect(inputs).to be_valid
- end
- end
-
- context 'when proper specification has been provided' do
- let(:spec) do
- {
- website: nil,
- env: { default: 'development' },
- run: { options: %w[tests spec e2e] }
- }
- end
-
- let(:args) { { website: 'https://gitlab.com', run: 'tests' } }
-
- it 'fabricates desired input arguments' do
- inputs = described_class.new(spec, args)
-
- expect(inputs).to be_valid
- expect(inputs.count).to eq 3
- expect(inputs.to_hash).to eq(args.merge(env: 'development'))
- end
- end
-
- context 'when inputs and args are empty' do
- it 'is a valid use-case' do
- inputs = described_class.new({}, {})
-
- expect(inputs).to be_valid
- expect(inputs.to_hash).to be_empty
- end
- end
-
- context 'when there are arguments recoincilation errors present' do
- context 'when required argument is missing' do
- let(:spec) { { website: nil } }
-
- it 'returns an error' do
- inputs = described_class.new(spec, {})
-
- expect(inputs).not_to be_valid
- expect(inputs.errors.first).to eq '`website` input: required value has not been provided'
- end
- end
-
- context 'when argument is not present but configured as allowlist' do
- let(:spec) do
- { run: { options: %w[opt1 opt2] } }
- end
-
- it 'returns an error' do
- inputs = described_class.new(spec, {})
-
- expect(inputs).not_to be_valid
- expect(inputs.errors.first).to eq '`run` input: argument not provided'
- end
- end
- end
-
- context 'when unknown specification argument has been used' do
- let(:spec) do
- {
- website: nil,
- env: { default: 'development' },
- run: { options: %w[tests spec e2e] },
- test: { unknown: 'something' }
- }
- end
-
- let(:args) { { website: 'https://gitlab.com', run: 'tests' } }
-
- it 'fabricates an unknown argument entry and returns an error' do
- inputs = described_class.new(spec, args)
-
- expect(inputs).not_to be_valid
- expect(inputs.count).to eq 4
- expect(inputs.errors.first).to eq '`test` input: unrecognized input argument specification: `unknown`'
- end
- end
-
- context 'when unknown arguments are being passed by a user' do
- let(:spec) do
- { env: { default: 'development' } }
- end
-
- let(:args) { { website: 'https://gitlab.com', run: 'tests' } }
-
- it 'returns an error with a list of unknown arguments' do
- inputs = described_class.new(spec, args)
-
- expect(inputs).not_to be_valid
- expect(inputs.errors.first).to eq 'unknown input arguments: [:website, :run]'
- end
- end
-
- context 'when composite specification is being used' do
- let(:spec) do
- {
- env: {
- default: 'dev',
- options: %w[test dev prod]
- }
- }
- end
-
- let(:args) { { env: 'dev' } }
-
- it 'returns an error describing an unknown specification' do
- inputs = described_class.new(spec, args)
-
- expect(inputs).not_to be_valid
- expect(inputs.errors.first).to eq '`env` input: unrecognized input argument definition'
- end
- end
-end
diff --git a/spec/migrations/20230810123044_swap_snippet_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb b/spec/migrations/20230810123044_swap_snippet_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb
new file mode 100644
index 00000000000..92b73901fec
--- /dev/null
+++ b/spec/migrations/20230810123044_swap_snippet_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb
@@ -0,0 +1,125 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapSnippetUserMentionsNoteIdToBigintForSelfHosts, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:snippet_user_mentions) { table(:snippet_user_mentions) }
+
+ shared_examples 'column `note_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE snippet_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute('ALTER TABLE snippet_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ snippet_user_mentions.reset_column_information
+
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ snippet_user_mentions.reset_column_information
+
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `note_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE snippet_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE snippet_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE snippet_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE snippet_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute(
+ 'ALTER TABLE snippet_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint bigint'
+ )
+ connection.execute('ALTER TABLE snippet_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ connection.execute('DROP INDEX IF EXISTS index_snippet_user_mentions_on_note_id_convert_to_bigint CASCADE')
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_bfc6e47be8cc() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."note_id_convert_to_bigint" := NEW."note_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE snippet_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ snippet_user_mentions.reset_column_information
+
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('integer')
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ snippet_user_mentions.reset_column_information
+
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(snippet_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/migrations/20230811103941_swap_vulnerability_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb b/spec/migrations/20230811103941_swap_vulnerability_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb
new file mode 100644
index 00000000000..c1aa2d4daec
--- /dev/null
+++ b/spec/migrations/20230811103941_swap_vulnerability_user_mentions_note_id_to_bigint_for_self_hosts_spec.rb
@@ -0,0 +1,133 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe SwapVulnerabilityUserMentionsNoteIdToBigintForSelfHosts, feature_category: :database do
+ let(:connection) { described_class.new.connection }
+ let(:vulnerability_user_mentions) { table(:vulnerability_user_mentions) }
+
+ shared_examples 'column `note_id_convert_to_bigint` is already dropped' do
+ before do
+ connection.execute('ALTER TABLE vulnerability_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute('ALTER TABLE vulnerability_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ vulnerability_user_mentions.reset_column_information
+
+ expect(vulnerability_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(vulnerability_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+
+ migration.after -> {
+ vulnerability_user_mentions.reset_column_information
+
+ expect(vulnerability_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(vulnerability_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }).to be_nil
+ }
+ end
+ end
+ end
+ end
+
+ describe '#up' do
+ before do
+ # rubocop:disable RSpec/AnyInstanceOf
+ allow_any_instance_of(described_class).to(
+ receive(:com_or_dev_or_test_but_not_jh?).and_return(com_or_dev_or_test_but_not_jh?)
+ )
+ # rubocop:enable RSpec/AnyInstanceOf
+ end
+
+ context 'when GitLab.com, dev, or test' do
+ let(:com_or_dev_or_test_but_not_jh?) { true }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance with the `note_id_convert_to_bigint` column already dropped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ it_behaves_like 'column `note_id_convert_to_bigint` is already dropped'
+ end
+
+ context 'when self-managed instance columns already swapped' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE vulnerability_user_mentions ALTER COLUMN note_id TYPE bigint')
+ connection.execute(
+ 'ALTER TABLE vulnerability_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint integer'
+ )
+
+ disable_migrations_output { migrate! }
+ end
+
+ after do
+ connection.execute('ALTER TABLE vulnerability_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'does not swaps the columns' do
+ expect(vulnerability_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(vulnerability_user_mentions.columns.find { |c| c.name == 'note_id_convert_to_bigint' }.sql_type).to(
+ eq('integer')
+ )
+ end
+ end
+
+ context 'when self-managed instance' do
+ let(:com_or_dev_or_test_but_not_jh?) { false }
+
+ before do
+ connection.execute('ALTER TABLE vulnerability_user_mentions ALTER COLUMN note_id TYPE integer')
+ connection.execute(
+ 'ALTER TABLE vulnerability_user_mentions ADD COLUMN IF NOT EXISTS note_id_convert_to_bigint bigint'
+ )
+ connection.execute('ALTER TABLE vulnerability_user_mentions ALTER COLUMN note_id_convert_to_bigint TYPE bigint')
+ connection.execute(
+ 'DROP INDEX IF EXISTS index_vulnerability_user_mentions_on_note_id_convert_to_bigint CASCADE'
+ )
+ connection.execute('CREATE OR REPLACE FUNCTION trigger_0e214b8a14f2() RETURNS trigger LANGUAGE plpgsql AS $$
+ BEGIN NEW."note_id_convert_to_bigint" := NEW."note_id"; RETURN NEW; END; $$;')
+ end
+
+ after do
+ connection.execute('ALTER TABLE vulnerability_user_mentions DROP COLUMN IF EXISTS note_id_convert_to_bigint')
+ end
+
+ it 'swaps the columns' do
+ disable_migrations_output do
+ reversible_migration do |migration|
+ migration.before -> {
+ vulnerability_user_mentions.reset_column_information
+
+ expect(vulnerability_user_mentions.columns.find do |c|
+ c.name == 'note_id'
+ end.sql_type).to eq('integer')
+ expect(vulnerability_user_mentions.columns.find do |c|
+ c.name == 'note_id_convert_to_bigint'
+ end.sql_type).to(
+ eq('bigint')
+ )
+ }
+
+ migration.after -> {
+ vulnerability_user_mentions.reset_column_information
+
+ expect(vulnerability_user_mentions.columns.find { |c| c.name == 'note_id' }.sql_type).to eq('bigint')
+ expect(vulnerability_user_mentions.columns.find do |c|
+ c.name == 'note_id_convert_to_bigint'
+ end.sql_type).to(
+ eq('integer')
+ )
+ }
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/models/label_spec.rb b/spec/models/label_spec.rb
index ee63433965e..4862b0b0453 100644
--- a/spec/models/label_spec.rb
+++ b/spec/models/label_spec.rb
@@ -238,6 +238,7 @@ RSpec.describe Label, feature_category: :team_planning do
label = create(:label, lock_on_merge: true)
expect(label.destroy).to be false
+ expect(label.errors.full_messages).to include("#{label.name} is locked and was not removed")
end
end
diff --git a/spec/models/project_authorizations/changes_spec.rb b/spec/models/project_authorizations/changes_spec.rb
index 1c29179b9d2..d0718153d16 100644
--- a/spec/models/project_authorizations/changes_spec.rb
+++ b/spec/models/project_authorizations/changes_spec.rb
@@ -27,11 +27,37 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
end
end
+ shared_examples_for 'publishes AuthorizationsChangedEvent' do
+ it 'publishes a AuthorizationsChangedEvent event with project id' do
+ project_ids.each do |project_id|
+ project_data = { project_id: project_id }
+ project_event = instance_double('::ProjectAuthorizations::AuthorizationsChangedEvent', data: project_data)
+
+ allow(::ProjectAuthorizations::AuthorizationsChangedEvent).to receive(:new)
+ .with(data: project_data)
+ .and_return(project_event)
+
+ expect(::Gitlab::EventStore).to receive(:publish).with(project_event)
+ end
+
+ apply_project_authorization_changes
+ end
+ end
+
+ shared_examples_for 'does not publishes AuthorizationsChangedEvent' do
+ it 'does not publishes a AuthorizationsChangedEvent event' do
+ expect(::Gitlab::EventStore).not_to receive(:publish)
+
+ apply_project_authorization_changes
+ end
+ end
+
context 'when new authorizations should be added' do
let_it_be(:user) { create(:user) }
let_it_be(:project_1) { create(:project) }
let_it_be(:project_2) { create(:project) }
let_it_be(:project_3) { create(:project) }
+ let(:project_ids) { [project_1.id, project_2.id, project_3.id] }
let(:authorizations_to_add) do
[
@@ -79,6 +105,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
end
it_behaves_like 'logs the detail', batch_size: 2
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
context 'when the GitLab installation does not have a replica database configured' do
before do
@@ -88,6 +115,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
it_behaves_like 'inserts the rows in batches, as per the `per_batch` size, without a delay between batches'
it_behaves_like 'does not log any detail'
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
end
end
@@ -98,6 +126,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
it_behaves_like 'inserts the rows in batches, as per the `per_batch` size, without a delay between batches'
it_behaves_like 'does not log any detail'
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
end
end
@@ -109,6 +138,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
let_it_be(:user_4) { create(:user) }
let(:user_ids) { [user_1.id, user_2.id, user_3.id] }
+ let(:project_ids) { [project.id] }
let(:project_authorization_changes) do
ProjectAuthorizations::Changes.new do |changes|
@@ -158,6 +188,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
end
it_behaves_like 'logs the detail', batch_size: 2
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
context 'when the GitLab installation does not have a replica database configured' do
before do
@@ -167,6 +198,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
it_behaves_like 'removes project authorizations of the users in the current project, without a delay'
it_behaves_like 'does not log any detail'
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
end
end
@@ -177,18 +209,21 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
it_behaves_like 'removes project authorizations of the users in the current project, without a delay'
it_behaves_like 'does not log any detail'
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
end
context 'when the user_ids list is empty' do
let(:user_ids) { [] }
it_behaves_like 'does not removes project authorizations of the users in the current project'
+ it_behaves_like 'does not publishes AuthorizationsChangedEvent'
end
context 'when the user_ids list is nil' do
let(:user_ids) { nil }
it_behaves_like 'does not removes project authorizations of the users in the current project'
+ it_behaves_like 'does not publishes AuthorizationsChangedEvent'
end
end
@@ -249,6 +284,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
end
it_behaves_like 'logs the detail', batch_size: 2
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
context 'when the GitLab installation does not have a replica database configured' do
before do
@@ -258,6 +294,7 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
it_behaves_like 'removes project authorizations of projects from the current user, without a delay'
it_behaves_like 'does not log any detail'
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
end
end
@@ -268,18 +305,21 @@ RSpec.describe ProjectAuthorizations::Changes, feature_category: :groups_and_pro
it_behaves_like 'removes project authorizations of projects from the current user, without a delay'
it_behaves_like 'does not log any detail'
+ it_behaves_like 'publishes AuthorizationsChangedEvent'
end
context 'when the project_ids list is empty' do
let(:project_ids) { [] }
it_behaves_like 'does not removes any project authorizations from the current user'
+ it_behaves_like 'does not publishes AuthorizationsChangedEvent'
end
context 'when the user_ids list is nil' do
let(:project_ids) { nil }
it_behaves_like 'does not removes any project authorizations from the current user'
+ it_behaves_like 'does not publishes AuthorizationsChangedEvent'
end
end
end
diff --git a/spec/requests/api/labels_spec.rb b/spec/requests/api/labels_spec.rb
index b5d7d564749..a9bc38ae77c 100644
--- a/spec/requests/api/labels_spec.rb
+++ b/spec/requests/api/labels_spec.rb
@@ -484,6 +484,18 @@ RSpec.describe API::Labels, feature_category: :team_planning do
let(:params) { { name: valid_label_title_1 } }
end
+ context 'when lock_on_merge' do
+ let(:label_locked) { create(:label, title: 'Locked label', project: project, lock_on_merge: true) }
+
+ it 'returns 400 because label could not be deleted' do
+ delete api("/projects/#{project.id}/labels", user), params: { label_id: label_locked.id }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['message']).to eq('Label is locked and was not removed')
+ expect(project.labels).to include(label_locked)
+ end
+ end
+
context 'with group label' do
let_it_be(:group) { create(:group) }
let_it_be(:group_label) { create(:group_label, title: valid_group_label_title_1, group: group) }
diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb
index 6a147782209..660686cf805 100644
--- a/spec/services/issues/import_csv_service_spec.rb
+++ b/spec/services/issues/import_csv_service_spec.rb
@@ -22,6 +22,8 @@ RSpec.describe Issues::ImportCsvService, feature_category: :team_planning do
describe '#execute' do
subject { service.execute }
+ it_behaves_like 'performs a spam check', true
+
it 'sets all issueable attributes and executes quick actions' do
project.add_developer(user)
project.add_developer(assignee)
@@ -38,5 +40,13 @@ RSpec.describe Issues::ImportCsvService, feature_category: :team_planning do
)
)
end
+
+ context 'when user is an admin' do
+ before do
+ allow(user).to receive(:can_admin_all_resources?).and_return(true)
+ end
+
+ it_behaves_like 'performs a spam check', false
+ end
end
end
diff --git a/spec/services/members/create_service_spec.rb b/spec/services/members/create_service_spec.rb
index c9dee0aadda..96fa8ab278d 100644
--- a/spec/services/members/create_service_spec.rb
+++ b/spec/services/members/create_service_spec.rb
@@ -121,7 +121,12 @@ RSpec.describe Members::CreateService, :aggregate_failures, :clean_gitlab_redis_
source.group.add_developer(member)
end
- it 'triggers the members added event' do
+ it 'triggers the members added and authorizations changed events' do
+ expect(Gitlab::EventStore)
+ .to receive(:publish)
+ .with(an_instance_of(ProjectAuthorizations::AuthorizationsChangedEvent))
+ .and_call_original
+
expect(Gitlab::EventStore)
.to receive(:publish)
.with(an_instance_of(Members::MembersAddedEvent))
diff --git a/spec/services/merge_requests/ff_merge_service_spec.rb b/spec/services/merge_requests/ff_merge_service_spec.rb
index f2dbc02f12c..c48ed19e40d 100644
--- a/spec/services/merge_requests/ff_merge_service_spec.rb
+++ b/spec/services/merge_requests/ff_merge_service_spec.rb
@@ -19,6 +19,7 @@ RSpec.describe MergeRequests::FfMergeService, feature_category: :code_review_wor
let(:valid_merge_params) { { sha: merge_request.diff_head_sha } }
before do
+ stub_feature_flags(refactor_merge_service: false)
project.add_maintainer(user)
project.add_developer(user2)
end
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index c32b7b16f63..1faa1fd3644 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -8,67 +8,62 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
let_it_be(:user) { create(:user) }
let_it_be(:user2) { create(:user) }
- let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
- let(:project) { merge_request.project }
+ where(:ff_refactor_merge_service_enabled) { [true, false] }
- before do
- project.add_maintainer(user)
- project.add_developer(user2)
- end
-
- describe '#execute' do
- let(:service) { described_class.new(project: project, current_user: user, params: merge_params) }
- let(:merge_params) do
- { commit_message: 'Awesome message', sha: merge_request.diff_head_sha }
- end
+ with_them do
+ let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
+ let(:project) { merge_request.project }
- let(:lease_key) { "merge_requests_merge_service:#{merge_request.id}" }
- let!(:lease) { stub_exclusive_lease(lease_key) }
+ before do
+ stub_feature_flags(refactor_merge_service: ff_refactor_merge_service_enabled)
- context 'valid params' do
- before do
- allow(service).to receive(:execute_hooks)
- expect(merge_request).to receive(:update_and_mark_in_progress_merge_commit_sha).twice.and_call_original
+ project.add_maintainer(user)
+ project.add_developer(user2)
+ end
- perform_enqueued_jobs do
- service.execute(merge_request)
- end
+ describe '#execute' do
+ let(:service) { described_class.new(project: project, current_user: user, params: merge_params) }
+ let(:merge_params) do
+ { commit_message: 'Awesome message', sha: merge_request.diff_head_sha }
end
- it { expect(merge_request).to be_valid }
- it { expect(merge_request).to be_merged }
+ let(:lease_key) { "merge_requests_merge_service:#{merge_request.id}" }
+ let!(:lease) { stub_exclusive_lease(lease_key) }
- it 'persists merge_commit_sha and nullifies in_progress_merge_commit_sha' do
- expect(merge_request.merge_commit_sha).not_to be_nil
- expect(merge_request.in_progress_merge_commit_sha).to be_nil
- end
+ shared_examples 'with valid params' do
+ before do
+ allow(service).to receive(:execute_hooks)
+ expect(merge_request).to receive(:update_and_mark_in_progress_merge_commit_sha).twice.and_call_original
- it 'does not update squash_commit_sha if it is not a squash' do
- expect(merge_request.squash_commit_sha).to be_nil
- end
+ perform_enqueued_jobs do
+ service.execute(merge_request)
+ end
+ end
- it 'sends email to user2 about merge of new merge_request' do
- email = ActionMailer::Base.deliveries.last
- expect(email.to.first).to eq(user2.email)
- expect(email.subject).to include(merge_request.title)
- end
+ it { expect(merge_request).to be_valid }
+ it { expect(merge_request).to be_merged }
- context 'note creation' do
- it 'creates resource state event about merge_request merge' do
- event = merge_request.resource_state_events.last
- expect(event.state).to eq('merged')
+ it 'does not update squash_commit_sha if it is not a squash' do
+ expect(merge_request.squash_commit_sha).to be_nil
end
- end
- context 'when squashing' do
- let(:merge_params) do
- { commit_message: 'Merge commit message',
- squash_commit_message: 'Squash commit message',
- sha: merge_request.diff_head_sha }
+ it 'sends email to user2 about merge of new merge_request' do
+ email = ActionMailer::Base.deliveries.last
+ expect(email.to.first).to eq(user2.email)
+ expect(email.subject).to include(merge_request.title)
end
+ context 'note creation' do
+ it 'creates resource state event about merge_request merge' do
+ event = merge_request.resource_state_events.last
+ expect(event.state).to eq('merged')
+ end
+ end
+ end
+
+ shared_examples 'squashing' do
+ # A merge request with 5 commits
let(:merge_request) do
- # A merge request with 5 commits
create(
:merge_request,
:simple,
@@ -80,6 +75,21 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
)
end
+ let(:merge_params) do
+ { commit_message: 'Merge commit message',
+ squash_commit_message: 'Squash commit message',
+ sha: merge_request.diff_head_sha }
+ end
+
+ before do
+ allow(service).to receive(:execute_hooks)
+ expect(merge_request).to receive(:update_and_mark_in_progress_merge_commit_sha).twice.and_call_original
+
+ perform_enqueued_jobs do
+ service.execute(merge_request)
+ end
+ end
+
it 'merges the merge request with squashed commits' do
expect(merge_request).to be_merged
@@ -96,357 +106,339 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
expect(merge_request.squash_commit_sha).to eq(squash_commit.id)
end
end
- end
-
- context 'running the service once' do
- let(:ref) { merge_request.to_reference(full: true) }
- let(:jid) { SecureRandom.hex }
-
- let(:messages) do
- [
- /#{ref} - Git merge started on JID #{jid}/,
- /#{ref} - Git merge finished on JID #{jid}/,
- /#{ref} - Post merge started on JID #{jid}/,
- /#{ref} - Post merge finished on JID #{jid}/,
- /#{ref} - Merge process finished on JID #{jid}/
- ]
- end
- before do
- merge_request.update!(merge_jid: jid)
- ::Gitlab::ApplicationContext.push(caller_id: 'MergeWorker')
- end
-
- it 'logs status messages' do
- allow(Gitlab::AppLogger).to receive(:info).and_call_original
+ context 'when merge strategy is merge commit' do
+ it 'persists merge_commit_sha and nullifies in_progress_merge_commit_sha' do
+ service.execute(merge_request)
- messages.each do |message|
- expect(Gitlab::AppLogger).to receive(:info).with(
- hash_including(
- 'meta.caller_id' => 'MergeWorker',
- message: message,
- merge_request_info: ref
- )
- ).and_call_original
+ expect(merge_request.merge_commit_sha).not_to be_nil
+ expect(merge_request.in_progress_merge_commit_sha).to be_nil
end
- service.execute(merge_request)
- end
- end
-
- context 'running the service multiple time' do
- it 'is idempotent' do
- 2.times { service.execute(merge_request) }
-
- expect(merge_request.merge_error).to be_falsey
- expect(merge_request).to be_valid
- expect(merge_request).to be_merged
-
- commit_messages = project.repository.commits('master', limit: 2).map(&:message)
- expect(commit_messages.uniq.size).to eq(2)
- expect(merge_request.in_progress_merge_commit_sha).to be_nil
- end
- end
-
- context 'when an invalid sha is passed' do
- let(:merge_request) do
- create(
- :merge_request,
- :simple,
- author: user2,
- assignees: [user2],
- squash: true,
- source_branch: 'improve/awesome',
- target_branch: 'fix'
- )
- end
+ it_behaves_like 'with valid params'
- let(:merge_params) do
- { sha: merge_request.commits.second.sha }
+ it_behaves_like 'squashing'
end
- it 'does not merge the MR' do
- service.execute(merge_request)
+ context 'when merge strategy is fast forward' do
+ before do
+ project.update!(merge_requests_ff_only_enabled: true)
+ end
- expect(merge_request).not_to be_merged
- expect(merge_request.merge_error).to match(/Branch has been updated/)
- end
- end
+ let(:merge_request) do
+ create(
+ :merge_request,
+ source_branch: 'flatten-dir',
+ target_branch: 'improve/awesome',
+ assignees: [user2],
+ author: create(:user)
+ )
+ end
- context 'when the `sha` param is missing' do
- let(:merge_params) { {} }
+ it 'does not create merge_commit_sha and nullifies in_progress_merge_commit_sha' do
+ service.execute(merge_request)
- it 'returns the error' do
- merge_error = 'Branch has been updated since the merge was requested. '\
- 'Please review the changes.'
+ expect(merge_request.merge_commit_sha).to be_nil
+ expect(merge_request.in_progress_merge_commit_sha).to be_nil
+ end
- expect { service.execute(merge_request) }
- .to change { merge_request.merge_error }
- .from(nil).to(merge_error)
- end
- end
+ it_behaves_like 'with valid params'
- context 'closes related issues' do
- before do
- allow(project).to receive(:default_branch).and_return(merge_request.target_branch)
- end
+ it 'updates squash_commit_sha if it is a squash' do
+ expect(merge_request).to receive(:update_and_mark_in_progress_merge_commit_sha).twice.and_call_original
- it 'closes GitLab issue tracker issues', :sidekiq_inline do
- issue = create :issue, project: project
- commit = double('commit', safe_message: "Fixes #{issue.to_reference}", date: Time.current, authored_date: Time.current)
- allow(merge_request).to receive(:commits).and_return([commit])
- merge_request.cache_merge_request_closes_issues!
+ merge_request.update!(squash: true)
- service.execute(merge_request)
+ expect { service.execute(merge_request) }
+ .to change { merge_request.squash_commit_sha }
+ .from(nil)
- expect(issue.reload.closed?).to be_truthy
+ expect(merge_request.merge_commit_sha).to be_nil
+ expect(merge_request.in_progress_merge_commit_sha).to be_nil
+ end
end
- context 'with Jira integration' do
- include JiraIntegrationHelpers
+ context 'running the service once' do
+ let(:ref) { merge_request.to_reference(full: true) }
+ let(:jid) { SecureRandom.hex }
- let(:jira_tracker) { project.create_jira_integration }
- let(:jira_issue) { ExternalIssue.new('JIRA-123', project) }
- let(:commit) { double('commit', safe_message: "Fixes #{jira_issue.to_reference}") }
+ let(:messages) do
+ [
+ /#{ref} - Git merge started on JID #{jid}/,
+ /#{ref} - Git merge finished on JID #{jid}/,
+ /#{ref} - Post merge started on JID #{jid}/,
+ /#{ref} - Post merge finished on JID #{jid}/,
+ /#{ref} - Merge process finished on JID #{jid}/
+ ]
+ end
before do
- stub_jira_integration_test
- project.update!(has_external_issue_tracker: true)
- jira_integration_settings
- stub_jira_urls(jira_issue.id)
- allow(merge_request).to receive(:commits).and_return([commit])
+ merge_request.update!(merge_jid: jid)
+ ::Gitlab::ApplicationContext.push(caller_id: 'MergeWorker')
end
- it 'closes issues on Jira issue tracker' do
- jira_issue = ExternalIssue.new('JIRA-123', project)
- stub_jira_urls(jira_issue)
- commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
- allow(merge_request).to receive(:commits).and_return([commit])
+ it 'logs status messages' do
+ allow(Gitlab::AppLogger).to receive(:info).and_call_original
- expect_any_instance_of(Integrations::Jira).to receive(:close_issue).with(merge_request, jira_issue, user).once
+ messages.each do |message|
+ expect(Gitlab::AppLogger).to receive(:info).with(
+ hash_including(
+ 'meta.caller_id' => 'MergeWorker',
+ message: message,
+ merge_request_info: ref
+ )
+ ).and_call_original
+ end
service.execute(merge_request)
end
+ end
- context 'wrong issue markdown' do
- it 'does not close issues on Jira issue tracker' do
- jira_issue = ExternalIssue.new('#JIRA-123', project)
- stub_jira_urls(jira_issue)
- commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
- allow(merge_request).to receive(:commits).and_return([commit])
+ context 'running the service multiple time' do
+ it 'is idempotent' do
+ 2.times { service.execute(merge_request) }
- expect_any_instance_of(Integrations::Jira).not_to receive(:close_issue)
+ expect(merge_request.merge_error).to be_falsey
+ expect(merge_request).to be_valid
+ expect(merge_request).to be_merged
- service.execute(merge_request)
- end
+ commit_messages = project.repository.commits('master', limit: 2).map(&:message)
+ expect(commit_messages.uniq.size).to eq(2)
+ expect(merge_request.in_progress_merge_commit_sha).to be_nil
end
end
- end
-
- context 'closes related todos' do
- let(:merge_request) { create(:merge_request, assignees: [user], author: user) }
- let(:project) { merge_request.project }
- let!(:todo) do
- create(:todo, :assigned,
- project: project,
- author: user,
- user: user,
- target: merge_request)
- end
+ context 'when an invalid sha is passed' do
+ let(:merge_request) do
+ create(
+ :merge_request,
+ :simple,
+ author: user2,
+ assignees: [user2],
+ squash: true,
+ source_branch: 'improve/awesome',
+ target_branch: 'fix'
+ )
+ end
- before do
- allow(service).to receive(:execute_hooks)
+ let(:merge_params) do
+ { sha: merge_request.commits.second.sha }
+ end
- perform_enqueued_jobs do
+ it 'does not merge the MR' do
service.execute(merge_request)
- todo.reload
+
+ expect(merge_request).not_to be_merged
+ expect(merge_request.merge_error).to match(/Branch has been updated/)
end
end
- it { expect(todo).to be_done }
- end
+ context 'when the `sha` param is missing' do
+ let(:merge_params) { {} }
- context 'source branch removal' do
- context 'when the source branch is protected' do
- let(:service) do
- described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => true))
+ it 'returns the error' do
+ merge_error = 'Branch has been updated since the merge was requested. '\
+ 'Please review the changes.'
+
+ expect { service.execute(merge_request) }
+ .to change { merge_request.merge_error }
+ .from(nil).to(merge_error)
end
+ end
+ context 'closes related issues' do
before do
- create(:protected_branch, project: project, name: merge_request.source_branch)
+ allow(project).to receive(:default_branch).and_return(merge_request.target_branch)
end
- it 'does not delete the source branch' do
- expect(::Branches::DeleteService).not_to receive(:new)
+ it 'closes GitLab issue tracker issues', :sidekiq_inline do
+ issue = create :issue, project: project
+ commit = double('commit', safe_message: "Fixes #{issue.to_reference}", date: Time.current, authored_date: Time.current)
+ allow(merge_request).to receive(:commits).and_return([commit])
+ merge_request.cache_merge_request_closes_issues!
service.execute(merge_request)
- end
- end
- context 'when the source branch is the default branch' do
- let(:service) do
- described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => true))
+ expect(issue.reload.closed?).to be_truthy
end
- before do
- allow(project).to receive(:root_ref?).with(merge_request.source_branch).and_return(true)
- end
+ context 'with Jira integration' do
+ include JiraIntegrationHelpers
- it 'does not delete the source branch' do
- expect(::Branches::DeleteService).not_to receive(:new)
- service.execute(merge_request)
- end
- end
+ let(:jira_tracker) { project.create_jira_integration }
+ let(:jira_issue) { ExternalIssue.new('JIRA-123', project) }
+ let(:commit) { double('commit', safe_message: "Fixes #{jira_issue.to_reference}") }
- context 'when the source branch can be removed' do
- context 'when MR author set the source branch to be removed' do
before do
- merge_request.update_attribute(:merge_params, { 'force_remove_source_branch' => '1' })
+ stub_jira_integration_test
+ project.update!(has_external_issue_tracker: true)
+ jira_integration_settings
+ stub_jira_urls(jira_issue.id)
+ allow(merge_request).to receive(:commits).and_return([commit])
end
- # Not a real use case. When a merger merges a MR , merge param 'should_remove_source_branch' is defined
- it 'removes the source branch using the author user' do
- expect(::MergeRequests::DeleteSourceBranchWorker).to receive(:perform_async).with(merge_request.id, merge_request.source_branch_sha, merge_request.author.id)
+ it 'closes issues on Jira issue tracker' do
+ jira_issue = ExternalIssue.new('JIRA-123', project)
+ stub_jira_urls(jira_issue)
+ commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
+ allow(merge_request).to receive(:commits).and_return([commit])
- service.execute(merge_request)
+ expect_any_instance_of(Integrations::Jira).to receive(:close_issue).with(merge_request, jira_issue, user).once
- expect(merge_request.reload.should_remove_source_branch?).to be nil
+ service.execute(merge_request)
end
- context 'when the merger set the source branch not to be removed' do
- let(:service) { described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => false)) }
+ context 'wrong issue markdown' do
+ it 'does not close issues on Jira issue tracker' do
+ jira_issue = ExternalIssue.new('#JIRA-123', project)
+ stub_jira_urls(jira_issue)
+ commit = double('commit', safe_message: "Fixes #{jira_issue.to_reference}")
+ allow(merge_request).to receive(:commits).and_return([commit])
- it 'does not delete the source branch' do
- expect(::MergeRequests::DeleteSourceBranchWorker).not_to receive(:perform_async)
+ expect_any_instance_of(Integrations::Jira).not_to receive(:close_issue)
service.execute(merge_request)
-
- expect(merge_request.reload.should_remove_source_branch?).to be false
end
end
end
+ end
- context 'when MR merger set the source branch to be removed' do
- let(:service) do
- described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => true))
- end
+ context 'closes related todos' do
+ let(:merge_request) { create(:merge_request, assignees: [user], author: user) }
+ let(:project) { merge_request.project }
- it 'removes the source branch using the current user' do
- expect(::MergeRequests::DeleteSourceBranchWorker).to receive(:perform_async).with(merge_request.id, merge_request.source_branch_sha, user.id)
+ let!(:todo) do
+ create(:todo, :assigned,
+ project: project,
+ author: user,
+ user: user,
+ target: merge_request)
+ end
- service.execute(merge_request)
+ before do
+ allow(service).to receive(:execute_hooks)
- expect(merge_request.reload.should_remove_source_branch?).to be true
+ perform_enqueued_jobs do
+ service.execute(merge_request)
+ todo.reload
end
end
- end
- end
- context 'error handling' do
- before do
- allow(Gitlab::AppLogger).to receive(:error)
+ it { expect(todo).to be_done }
end
- context 'when source is missing' do
- it 'logs and saves error' do
- allow(merge_request).to receive(:diff_head_sha) { nil }
+ context 'source branch removal' do
+ context 'when the source branch is protected' do
+ let(:service) do
+ described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => true))
+ end
- error_message = 'No source for merge'
+ before do
+ create(:protected_branch, project: project, name: merge_request.source_branch)
+ end
- service.execute(merge_request)
+ it 'does not delete the source branch' do
+ expect(::Branches::DeleteService).not_to receive(:new)
- expect(merge_request.merge_error).to eq(error_message)
- expect(Gitlab::AppLogger).to have_received(:error).with(
- hash_including(
- merge_request_info: merge_request.to_reference(full: true),
- message: a_string_matching(error_message)
- )
- )
+ service.execute(merge_request)
+ end
end
- end
-
- it 'logs and saves error if there is an exception' do
- error_message = 'error message'
- allow(service).to receive(:repository).and_raise(error_message)
- allow(service).to receive(:execute_hooks)
+ context 'when the source branch is the default branch' do
+ let(:service) do
+ described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => true))
+ end
- service.execute(merge_request)
+ before do
+ allow(project).to receive(:root_ref?).with(merge_request.source_branch).and_return(true)
+ end
- expect(merge_request.merge_error).to eq(described_class::GENERIC_ERROR_MESSAGE)
- expect(Gitlab::AppLogger).to have_received(:error).with(
- hash_including(
- merge_request_info: merge_request.to_reference(full: true),
- message: a_string_matching(error_message)
- )
- )
- end
+ it 'does not delete the source branch' do
+ expect(::Branches::DeleteService).not_to receive(:new)
+ service.execute(merge_request)
+ end
+ end
- it 'logs and saves error if user is not authorized' do
- stub_exclusive_lease
+ context 'when the source branch can be removed' do
+ context 'when MR author set the source branch to be removed' do
+ before do
+ merge_request.update_attribute(:merge_params, { 'force_remove_source_branch' => '1' })
+ end
- unauthorized_user = create(:user)
- project.add_reporter(unauthorized_user)
+ # Not a real use case. When a merger merges a MR , merge param 'should_remove_source_branch' is defined
+ it 'removes the source branch using the author user' do
+ expect(::MergeRequests::DeleteSourceBranchWorker).to receive(:perform_async).with(merge_request.id, merge_request.source_branch_sha, merge_request.author.id)
- service = described_class.new(project: project, current_user: unauthorized_user)
+ service.execute(merge_request)
- service.execute(merge_request)
+ expect(merge_request.reload.should_remove_source_branch?).to be nil
+ end
- expect(merge_request.merge_error)
- .to eq('You are not allowed to merge this merge request')
- end
+ context 'when the merger set the source branch not to be removed' do
+ let(:service) { described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => false)) }
- it 'logs and saves error if there is an PreReceiveError exception' do
- error_message = 'error message'
+ it 'does not delete the source branch' do
+ expect(::MergeRequests::DeleteSourceBranchWorker).not_to receive(:perform_async)
- allow(service).to receive(:repository).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{error_message}")
- allow(service).to receive(:execute_hooks)
+ service.execute(merge_request)
- service.execute(merge_request)
+ expect(merge_request.reload.should_remove_source_branch?).to be false
+ end
+ end
+ end
- expect(merge_request.merge_error).to include('Something went wrong during merge pre-receive hook')
- expect(Gitlab::AppLogger).to have_received(:error).with(
- hash_including(
- merge_request_info: merge_request.to_reference(full: true),
- message: a_string_matching(error_message)
- )
- )
- end
+ context 'when MR merger set the source branch to be removed' do
+ let(:service) do
+ described_class.new(project: project, current_user: user, params: merge_params.merge('should_remove_source_branch' => true))
+ end
- it 'logs and saves error if commit is not created' do
- allow_any_instance_of(Repository).to receive(:merge).and_return(false)
- allow(service).to receive(:execute_hooks)
+ it 'removes the source branch using the current user' do
+ expect(::MergeRequests::DeleteSourceBranchWorker).to receive(:perform_async).with(merge_request.id, merge_request.source_branch_sha, user.id)
- service.execute(merge_request)
+ service.execute(merge_request)
- expect(merge_request).to be_open
- expect(merge_request.merge_commit_sha).to be_nil
- expect(merge_request.merge_error).to include(described_class::GENERIC_ERROR_MESSAGE)
- expect(Gitlab::AppLogger).to have_received(:error).with(
- hash_including(
- merge_request_info: merge_request.to_reference(full: true),
- message: a_string_matching(described_class::GENERIC_ERROR_MESSAGE)
- )
- )
+ expect(merge_request.reload.should_remove_source_branch?).to be true
+ end
+ end
+ end
end
- context 'when squashing is required' do
+ context 'error handling' do
before do
- merge_request.update!(source_branch: 'master', target_branch: 'feature')
- merge_request.target_project.project_setting.squash_always!
+ allow(Gitlab::AppLogger).to receive(:error)
end
- it 'raises an error if squashing is not done' do
- error_message = 'requires squashing commits'
+ context 'when source is missing' do
+ it 'logs and saves error' do
+ allow(merge_request).to receive(:diff_head_sha) { nil }
- service.execute(merge_request)
+ error_message = 'No source for merge'
- expect(merge_request).to be_open
+ service.execute(merge_request)
- expect(merge_request.merge_commit_sha).to be_nil
- expect(merge_request.squash_commit_sha).to be_nil
- expect(merge_request.merge_error).to include(error_message)
+ expect(merge_request.merge_error).to eq(error_message)
+ expect(Gitlab::AppLogger).to have_received(:error).with(
+ hash_including(
+ merge_request_info: merge_request.to_reference(full: true),
+ message: a_string_matching(error_message)
+ )
+ )
+ end
+ end
+
+ it 'logs and saves error if there is an exception' do
+ error_message = 'error message'
+
+ allow_next_instance_of(MergeRequests::MergeStrategies::FromSourceBranch) do |strategy|
+ allow(strategy).to receive(:execute_git_merge!).and_raise(error_message)
+ end
+ # we can remove these allows upon refactor_merge_service cleanup
+ allow(service).to receive(:repository).and_raise(error_message)
+ allow(service).to receive(:execute_hooks)
+
+ service.execute(merge_request)
+
+ expect(merge_request.merge_error).to eq(described_class::GENERIC_ERROR_MESSAGE)
expect(Gitlab::AppLogger).to have_received(:error).with(
hash_including(
merge_request_info: merge_request.to_reference(full: true),
@@ -454,25 +446,34 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
)
)
end
- end
- context 'when squashing' do
- before do
- merge_request.update!(source_branch: 'master', target_branch: 'feature')
+ it 'logs and saves error if user is not authorized' do
+ stub_exclusive_lease
+
+ unauthorized_user = create(:user)
+ project.add_reporter(unauthorized_user)
+
+ service = described_class.new(project: project, current_user: unauthorized_user)
+
+ service.execute(merge_request)
+
+ expect(merge_request.merge_error)
+ .to eq('You are not allowed to merge this merge request')
end
- it 'logs and saves error if there is an error when squashing' do
- error_message = 'Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch.'
+ it 'logs and saves error if there is an PreReceiveError exception' do
+ error_message = 'error message'
- allow_any_instance_of(MergeRequests::SquashService).to receive(:squash!).and_return(nil)
- merge_request.update!(squash: true)
+ allow_next_instance_of(MergeRequests::MergeStrategies::FromSourceBranch) do |strategy|
+ allow(strategy).to receive(:execute_git_merge!).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{error_message}")
+ end
+ # we can remove these allows upon refactor_merge_service cleanup
+ allow(service).to receive(:repository).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{error_message}")
+ allow(service).to receive(:execute_hooks)
service.execute(merge_request)
- expect(merge_request).to be_open
- expect(merge_request.merge_commit_sha).to be_nil
- expect(merge_request.squash_commit_sha).to be_nil
- expect(merge_request.merge_error).to include(error_message)
+ expect(merge_request.merge_error).to include('Something went wrong during merge pre-receive hook')
expect(Gitlab::AppLogger).to have_received(:error).with(
hash_including(
merge_request_info: merge_request.to_reference(full: true),
@@ -481,68 +482,65 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
)
end
- it 'logs and saves error if there is an PreReceiveError exception' do
- error_message = 'error message'
-
- allow(service).to receive(:repository).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{error_message}")
+ it 'logs and saves error if commit is not created' do
+ allow_any_instance_of(Repository).to receive(:merge).and_return(false)
allow(service).to receive(:execute_hooks)
- merge_request.update!(squash: true)
service.execute(merge_request)
expect(merge_request).to be_open
expect(merge_request.merge_commit_sha).to be_nil
- expect(merge_request.squash_commit_sha).to be_nil
- expect(merge_request.merge_error).to include('Something went wrong during merge pre-receive hook')
+ expect(merge_request.merge_error).to include(described_class::GENERIC_ERROR_MESSAGE)
expect(Gitlab::AppLogger).to have_received(:error).with(
hash_including(
merge_request_info: merge_request.to_reference(full: true),
- message: a_string_matching(error_message)
+ message: a_string_matching(described_class::GENERIC_ERROR_MESSAGE)
)
)
end
- context 'when fast-forward merge is not allowed' do
+ context 'when squashing is required' do
before do
- allow_any_instance_of(Repository).to receive(:ancestor?).and_return(nil)
+ merge_request.update!(source_branch: 'master', target_branch: 'feature')
+ merge_request.target_project.project_setting.squash_always!
end
- %w(semi-linear ff).each do |merge_method|
- it "logs and saves error if merge is #{merge_method} only" do
- merge_method = 'rebase_merge' if merge_method == 'semi-linear'
- merge_request.project.update!(merge_method: merge_method)
- error_message = 'Only fast-forward merge is allowed for your project. Please update your source branch'
- allow(service).to receive(:execute_hooks)
- expect(lease).to receive(:cancel)
+ it 'raises an error if squashing is not done' do
+ error_message = 'requires squashing commits'
- service.execute(merge_request)
+ service.execute(merge_request)
- expect(merge_request).to be_open
- expect(merge_request.merge_commit_sha).to be_nil
- expect(merge_request.squash_commit_sha).to be_nil
- expect(merge_request.merge_error).to include(error_message)
- expect(Gitlab::AppLogger).to have_received(:error).with(
- hash_including(
- merge_request_info: merge_request.to_reference(full: true),
- message: a_string_matching(error_message)
- )
+ expect(merge_request).to be_open
+
+ expect(merge_request.merge_commit_sha).to be_nil
+ expect(merge_request.squash_commit_sha).to be_nil
+ expect(merge_request.merge_error).to include(error_message)
+ expect(Gitlab::AppLogger).to have_received(:error).with(
+ hash_including(
+ merge_request_info: merge_request.to_reference(full: true),
+ message: a_string_matching(error_message)
)
- end
+ )
end
end
- end
-
- context 'when not mergeable' do
- let!(:error_message) { 'Merge request is not mergeable' }
- context 'with failing CI' do
+ context 'when squashing' do
before do
- allow(merge_request).to receive(:mergeable_ci_state?) { false }
+ merge_request.update!(source_branch: 'master', target_branch: 'feature')
end
- it 'logs and saves error' do
+ it 'logs and saves error if there is an error when squashing' do
+ error_message = 'Squashing failed: Squash the commits locally, resolve any conflicts, then push the branch.'
+
+ allow_any_instance_of(MergeRequests::SquashService).to receive(:squash!).and_return(nil)
+ merge_request.update!(squash: true)
+
service.execute(merge_request)
+ expect(merge_request).to be_open
+ expect(merge_request.merge_commit_sha).to be_nil
+ expect(merge_request.squash_commit_sha).to be_nil
+ expect(merge_request.merge_error).to include(error_message)
expect(Gitlab::AppLogger).to have_received(:error).with(
hash_including(
merge_request_info: merge_request.to_reference(full: true),
@@ -550,16 +548,24 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
)
)
end
- end
- context 'with unresolved discussions' do
- before do
- allow(merge_request).to receive(:mergeable_discussions_state?) { false }
- end
+ it 'logs and saves error if there is an PreReceiveError exception' do
+ error_message = 'error message'
+
+ allow_next_instance_of(MergeRequests::MergeStrategies::FromSourceBranch) do |strategy|
+ allow(strategy).to receive(:execute_git_merge!).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{error_message}")
+ end
+ # we can remove these allows upon refactor_merge_service cleanup
+ allow(service).to receive(:repository).and_raise(Gitlab::Git::PreReceiveError, "GitLab: #{error_message}")
+ allow(service).to receive(:execute_hooks)
+ merge_request.update!(squash: true)
- it 'logs and saves error' do
service.execute(merge_request)
+ expect(merge_request).to be_open
+ expect(merge_request.merge_commit_sha).to be_nil
+ expect(merge_request.squash_commit_sha).to be_nil
+ expect(merge_request.merge_error).to include('Something went wrong during merge pre-receive hook')
expect(Gitlab::AppLogger).to have_received(:error).with(
hash_including(
merge_request_info: merge_request.to_reference(full: true),
@@ -568,12 +574,79 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
)
end
- context 'when passing `skip_discussions_check: true` as `options` parameter' do
- it 'merges the merge request' do
- service.execute(merge_request, skip_discussions_check: true)
+ context 'when fast-forward merge is not allowed' do
+ before do
+ allow_any_instance_of(Repository).to receive(:ancestor?).and_return(nil)
+ end
- expect(merge_request).to be_valid
- expect(merge_request).to be_merged
+ %w(semi-linear ff).each do |merge_method|
+ it "logs and saves error if merge is #{merge_method} only" do
+ merge_method = 'rebase_merge' if merge_method == 'semi-linear'
+ merge_request.project.update!(merge_method: merge_method)
+ error_message = 'Only fast-forward merge is allowed for your project. Please update your source branch'
+ allow(service).to receive(:execute_hooks)
+ expect(lease).to receive(:cancel)
+
+ service.execute(merge_request)
+
+ expect(merge_request).to be_open
+ expect(merge_request.merge_commit_sha).to be_nil
+ expect(merge_request.squash_commit_sha).to be_nil
+ expect(merge_request.merge_error).to include(error_message)
+ expect(Gitlab::AppLogger).to have_received(:error).with(
+ hash_including(
+ merge_request_info: merge_request.to_reference(full: true),
+ message: a_string_matching(error_message)
+ )
+ )
+ end
+ end
+ end
+ end
+
+ context 'when not mergeable' do
+ let!(:error_message) { 'Merge request is not mergeable' }
+
+ context 'with failing CI' do
+ before do
+ allow(merge_request).to receive(:mergeable_ci_state?) { false }
+ end
+
+ it 'logs and saves error' do
+ service.execute(merge_request)
+
+ expect(Gitlab::AppLogger).to have_received(:error).with(
+ hash_including(
+ merge_request_info: merge_request.to_reference(full: true),
+ message: a_string_matching(error_message)
+ )
+ )
+ end
+ end
+
+ context 'with unresolved discussions' do
+ before do
+ allow(merge_request).to receive(:mergeable_discussions_state?) { false }
+ end
+
+ it 'logs and saves error' do
+ service.execute(merge_request)
+
+ expect(Gitlab::AppLogger).to have_received(:error).with(
+ hash_including(
+ merge_request_info: merge_request.to_reference(full: true),
+ message: a_string_matching(error_message)
+ )
+ )
+ end
+
+ context 'when passing `skip_discussions_check: true` as `options` parameter' do
+ it 'merges the merge request' do
+ service.execute(merge_request, skip_discussions_check: true)
+
+ expect(merge_request).to be_valid
+ expect(merge_request).to be_merged
+ end
end
end
end
@@ -586,17 +659,17 @@ RSpec.describe MergeRequests::MergeService, feature_category: :code_review_workf
end
end
end
- end
- context 'when the other sidekiq worker has already been running' do
- before do
- stub_exclusive_lease_taken(lease_key)
- end
+ context 'when the other sidekiq worker has already been running' do
+ before do
+ stub_exclusive_lease_taken(lease_key)
+ end
- it 'does not execute service' do
- expect(service).not_to receive(:commit)
+ it 'does not execute service' do
+ expect(service).not_to receive(:commit)
- service.execute(merge_request)
+ service.execute(merge_request)
+ end
end
end
end
diff --git a/spec/services/merge_requests/merge_strategies/from_source_branch_spec.rb b/spec/services/merge_requests/merge_strategies/from_source_branch_spec.rb
new file mode 100644
index 00000000000..20277fdeec7
--- /dev/null
+++ b/spec/services/merge_requests/merge_strategies/from_source_branch_spec.rb
@@ -0,0 +1,87 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe MergeRequests::MergeStrategies::FromSourceBranch, feature_category: :code_review_workflow do
+ let_it_be(:user) { create(:user) }
+ let_it_be(:user2) { create(:user) }
+
+ let(:merge_request) { create(:merge_request, :simple, author: user2, assignees: [user2]) }
+ let(:project) { merge_request.project }
+
+ subject(:strategy) { described_class.new(merge_request, user) }
+
+ before do
+ project.add_maintainer(user)
+ end
+
+ describe '#validate!' do
+ context 'when source is missing' do
+ before do
+ allow(merge_request).to receive(:diff_head_sha).and_return(nil)
+ end
+
+ it 'raises source error when source is missing' do
+ error_message = 'No source for merge'
+
+ expect { strategy.validate! }
+ .to raise_exception(MergeRequests::MergeStrategies::StrategyError, error_message)
+ end
+ end
+
+ context 'when merge request should be rebased' do
+ before do
+ allow(merge_request).to receive(:should_be_rebased?).and_return(true)
+ end
+
+ it 'raises needs rebase error' do
+ error_message = 'Only fast-forward merge is allowed for your project. Please update your source branch'
+
+ expect { strategy.validate! }
+ .to raise_exception(MergeRequests::MergeStrategies::StrategyError, error_message)
+ end
+ end
+
+ context 'when merge request should be squashed but is not' do
+ before do
+ merge_request.target_project.project_setting.squash_always!
+ merge_request.update!(squash: false)
+ end
+
+ it 'raises squashing error' do
+ error_message = 'This project requires squashing commits when merge requests are accepted.'
+
+ expect { strategy.validate! }
+ .to raise_exception(MergeRequests::MergeStrategies::StrategyError, error_message)
+ end
+ end
+ end
+
+ describe '#execute_git_merge!' do
+ context 'when fast-forward is required' do
+ before do
+ project.merge_method = :ff
+ project.save!
+ end
+
+ it 'performs a fast-forward merge' do
+ expect(merge_request.target_project.repository).to receive(:ff_merge).and_return('1234')
+
+ strategy.execute_git_merge!
+ end
+ end
+
+ context 'when a merge commit is required' do
+ before do
+ project.merge_method = :merge
+ project.save!
+ end
+
+ it 'performs standard merge' do
+ expect(merge_request.target_project.repository).to receive(:merge).and_return('1234')
+
+ strategy.execute_git_merge!
+ end
+ end
+ end
+end
diff --git a/spec/services/spam/spam_action_service_spec.rb b/spec/services/spam/spam_action_service_spec.rb
index 15cb4977b61..fc86ecfe7f2 100644
--- a/spec/services/spam/spam_action_service_spec.rb
+++ b/spec/services/spam/spam_action_service_spec.rb
@@ -42,20 +42,6 @@ RSpec.describe Spam::SpamActionService, feature_category: :instance_resiliency d
described_service.execute
end
- context 'when spam_params is nil' do
- let(:spam_params) { nil }
- let(:expected_service_params_not_present_message) do
- /Skipped spam check because spam_params was not present/
- end
-
- it "returns success with a messaage" do
- response = subject
-
- expect(response.message).to match(expected_service_params_not_present_message)
- expect(issue).not_to be_spam
- end
- end
-
context 'when user is nil' do
let(:spam_params) { true }
let(:user) { nil }
diff --git a/spec/support/shared_examples/services/import_csv_service_shared_examples.rb b/spec/support/shared_examples/services/import_csv_service_shared_examples.rb
index 1555497ae48..b09d087f518 100644
--- a/spec/support/shared_examples/services/import_csv_service_shared_examples.rb
+++ b/spec/support/shared_examples/services/import_csv_service_shared_examples.rb
@@ -36,3 +36,15 @@ RSpec.shared_examples 'correctly handles invalid files' do
it_behaves_like 'invalid file'
end
end
+
+RSpec.shared_examples 'performs a spam check' do |perform_check|
+ it 'initializes issue create service with expected spam check parameter' do
+ expect(Issues::CreateService)
+ .to receive(:new)
+ .at_least(:once)
+ .with(hash_including(perform_spam_check: perform_check))
+ .and_call_original
+
+ subject
+ end
+end