diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-11 15:10:41 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-11-11 15:10:41 +0300 |
commit | 1c7411c597334e20d2e92cc948f0699d339d2710 (patch) | |
tree | e88e76f1f563b71a4b9113373f24849bc5d1d79e /spec | |
parent | 3e9023894d319cf56b7b844910953df19ca010b1 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
49 files changed, 338 insertions, 35 deletions
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb index d92862f0ca3..66af546b113 100644 --- a/spec/controllers/projects/notes_controller_spec.rb +++ b/spec/controllers/projects/notes_controller_spec.rb @@ -1007,6 +1007,35 @@ RSpec.describe Projects::NotesController do end end + describe 'GET outdated_line_change' do + let(:request_params) do + { + namespace_id: project.namespace, + project_id: project, + id: note, + format: 'json' + } + end + + before do + service = double + allow(service).to receive(:execute).and_return([{ line_text: 'Test' }]) + allow(MergeRequests::OutdatedDiscussionDiffLinesService).to receive(:new).once.and_return(service) + + sign_in(user) + project.add_developer(user) + end + + it "successfully renders expected JSON response" do + get :outdated_line_change, params: request_params + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to be_an(Array) + expect(json_response.count).to eq(1) + expect(json_response.first).to include({ "line_text" => "Test" }) + end + end + # Convert a time to an integer number of microseconds def microseconds(time) (time.to_i * 1_000_000) + time.usec diff --git a/spec/features/admin/admin_disables_two_factor_spec.rb b/spec/features/admin/admin_disables_two_factor_spec.rb index 1f34c4ed17c..f65e85b4cb6 100644 --- a/spec/features/admin/admin_disables_two_factor_spec.rb +++ b/spec/features/admin/admin_disables_two_factor_spec.rb @@ -4,6 +4,7 @@ require 'spec_helper' RSpec.describe 'Admin disables 2FA for a user' do it 'successfully', :js do + stub_feature_flags(bootstrap_confirmation_modals: false) admin = create(:admin) sign_in(admin) gitlab_enable_admin_mode_sign_in(admin) diff --git a/spec/features/admin/admin_groups_spec.rb b/spec/features/admin/admin_groups_spec.rb index 8315b8f44b0..8d4e7a7442c 100644 --- a/spec/features/admin/admin_groups_spec.rb +++ b/spec/features/admin/admin_groups_spec.rb @@ -252,6 +252,7 @@ RSpec.describe 'Admin Groups' do describe 'admin remove themself from a group', :js, quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/222342' do it 'removes admin from the group' do + stub_feature_flags(bootstrap_confirmation_modals: false) group.add_user(current_user, Gitlab::Access::DEVELOPER) visit group_group_members_path(group) diff --git a/spec/features/admin/admin_hooks_spec.rb b/spec/features/admin/admin_hooks_spec.rb index a501efd82ed..32e4d18227e 100644 --- a/spec/features/admin/admin_hooks_spec.rb +++ b/spec/features/admin/admin_hooks_spec.rb @@ -79,6 +79,7 @@ RSpec.describe 'Admin::Hooks' do let(:hook_url) { generate(:url) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) create(:system_hook, url: hook_url) end diff --git a/spec/features/admin/admin_labels_spec.rb b/spec/features/admin/admin_labels_spec.rb index 08d81906d9f..65de1160cfd 100644 --- a/spec/features/admin/admin_labels_spec.rb +++ b/spec/features/admin/admin_labels_spec.rb @@ -14,6 +14,7 @@ RSpec.describe 'admin issues labels' do describe 'list' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit admin_labels_path end diff --git a/spec/features/admin/admin_users_impersonation_tokens_spec.rb b/spec/features/admin/admin_users_impersonation_tokens_spec.rb index ed8ea84fbf8..6643ebe82e6 100644 --- a/spec/features/admin/admin_users_impersonation_tokens_spec.rb +++ b/spec/features/admin/admin_users_impersonation_tokens_spec.rb @@ -74,6 +74,7 @@ RSpec.describe 'Admin > Users > Impersonation Tokens', :js do let!(:impersonation_token) { create(:personal_access_token, :impersonation, user: user) } it "allows revocation of an active impersonation token" do + stub_feature_flags(bootstrap_confirmation_modals: false) visit admin_user_impersonation_tokens_path(user_id: user.username) accept_confirm { click_on "Revoke" } diff --git a/spec/features/admin/admin_uses_repository_checks_spec.rb b/spec/features/admin/admin_uses_repository_checks_spec.rb index 0e448446085..c13313609b5 100644 --- a/spec/features/admin/admin_uses_repository_checks_spec.rb +++ b/spec/features/admin/admin_uses_repository_checks_spec.rb @@ -8,6 +8,7 @@ RSpec.describe 'Admin uses repository checks', :request_store do let(:admin) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false') sign_in(admin) end diff --git a/spec/features/admin/users/user_spec.rb b/spec/features/admin/users/user_spec.rb index 624bfde7359..73477fb93dd 100644 --- a/spec/features/admin/users/user_spec.rb +++ b/spec/features/admin/users/user_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'Admin::Users::User' do let_it_be(:current_user) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(current_user) gitlab_enable_admin_mode_sign_in(current_user) end diff --git a/spec/features/admin/users/users_spec.rb b/spec/features/admin/users/users_spec.rb index 119b01ff552..3968b055819 100644 --- a/spec/features/admin/users/users_spec.rb +++ b/spec/features/admin/users/users_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'Admin::Users' do let_it_be(:current_user) { create(:admin) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(current_user) gitlab_enable_admin_mode_sign_in(current_user) end diff --git a/spec/features/boards/boards_spec.rb b/spec/features/boards/boards_spec.rb index 9a5b5bbfc34..2f21961d1fc 100644 --- a/spec/features/boards/boards_spec.rb +++ b/spec/features/boards/boards_spec.rb @@ -536,6 +536,7 @@ RSpec.describe 'Project issue boards', :js do let_it_be(:user_guest) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_guest(user_guest) sign_in(user_guest) visit project_board_path(project, board) diff --git a/spec/features/groups/members/leave_group_spec.rb b/spec/features/groups/members/leave_group_spec.rb index b73313745e9..e6bf1ffc2f7 100644 --- a/spec/features/groups/members/leave_group_spec.rb +++ b/spec/features/groups/members/leave_group_spec.rb @@ -10,6 +10,7 @@ RSpec.describe 'Groups > Members > Leave group' do let(:group) { create(:group) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb index 54c3fe738d2..f9b554c5ed2 100644 --- a/spec/features/merge_request/user_comments_on_diff_spec.rb +++ b/spec/features/merge_request/user_comments_on_diff_spec.rb @@ -14,6 +14,7 @@ RSpec.describe 'User comments on a diff', :js do let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) sign_in(user) diff --git a/spec/features/merge_request/user_posts_diff_notes_spec.rb b/spec/features/merge_request/user_posts_diff_notes_spec.rb index c339a7d9976..dcd289c7627 100644 --- a/spec/features/merge_request/user_posts_diff_notes_spec.rb +++ b/spec/features/merge_request/user_posts_diff_notes_spec.rb @@ -18,6 +18,7 @@ RSpec.describe 'Merge request > User posts diff notes', :js do project.add_developer(user) sign_in(user) + stub_feature_flags(bootstrap_confirmation_modals: false) end context 'when hovering over a parallel view diff file' do diff --git a/spec/features/merge_request/user_posts_notes_spec.rb b/spec/features/merge_request/user_posts_notes_spec.rb index 83d9388914b..0416474218f 100644 --- a/spec/features/merge_request/user_posts_notes_spec.rb +++ b/spec/features/merge_request/user_posts_notes_spec.rb @@ -18,8 +18,10 @@ RSpec.describe 'Merge request > User posts notes', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) sign_in(user) + visit project_merge_request_path(project, merge_request) end diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb index 90cdc28d1bd..64cd5aa2bb1 100644 --- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb +++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb @@ -79,6 +79,7 @@ RSpec.describe 'Merge request > User sees avatars on diff notes', :js do %w(parallel).each do |view| context "#{view} view" do before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit diffs_project_merge_request_path(project, merge_request, view: view) wait_for_requests diff --git a/spec/features/merge_request/user_sees_deployment_widget_spec.rb b/spec/features/merge_request/user_sees_deployment_widget_spec.rb index 873cc0a89c6..345404cc28f 100644 --- a/spec/features/merge_request/user_sees_deployment_widget_spec.rb +++ b/spec/features/merge_request/user_sees_deployment_widget_spec.rb @@ -110,6 +110,7 @@ RSpec.describe 'Merge request > User sees deployment widget', :js do let(:manual) { create(:ci_build, :manual, pipeline: pipeline, name: 'close_app') } before do + stub_feature_flags(bootstrap_confirmation_modals: false) build.success! deployment.update!(on_stop: manual.name) visit project_merge_request_path(project, merge_request) diff --git a/spec/features/profile_spec.rb b/spec/features/profile_spec.rb index 9a261c6d9c8..7d935298f38 100644 --- a/spec/features/profile_spec.rb +++ b/spec/features/profile_spec.rb @@ -6,6 +6,7 @@ RSpec.describe 'Profile account page', :js do let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end @@ -80,6 +81,7 @@ RSpec.describe 'Profile account page', :js do describe 'when I reset incoming email token' do before do allow(Gitlab.config.incoming_email).to receive(:enabled).and_return(true) + stub_feature_flags(bootstrap_confirmation_modals: false) visit profile_personal_access_tokens_path end diff --git a/spec/features/profiles/active_sessions_spec.rb b/spec/features/profiles/active_sessions_spec.rb index fd64704b7c8..a515c7b1c1f 100644 --- a/spec/features/profiles/active_sessions_spec.rb +++ b/spec/features/profiles/active_sessions_spec.rb @@ -11,6 +11,10 @@ RSpec.describe 'Profile > Active Sessions', :clean_gitlab_redis_shared_state do let(:admin) { create(:admin) } + before do + stub_feature_flags(bootstrap_confirmation_modals: false) + end + it 'user sees their active sessions' do travel_to(Time.zone.parse('2018-03-12 09:06')) do Capybara::Session.new(:session1) diff --git a/spec/features/profiles/oauth_applications_spec.rb b/spec/features/profiles/oauth_applications_spec.rb index 2735f601307..6827dff5434 100644 --- a/spec/features/profiles/oauth_applications_spec.rb +++ b/spec/features/profiles/oauth_applications_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'Profile > Applications' do let(:application) { create(:oauth_application, owner: user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/profiles/personal_access_tokens_spec.rb b/spec/features/profiles/personal_access_tokens_spec.rb index 8f44299b18f..74505633cae 100644 --- a/spec/features/profiles/personal_access_tokens_spec.rb +++ b/spec/features/profiles/personal_access_tokens_spec.rb @@ -34,6 +34,7 @@ RSpec.describe 'Profile > Personal Access Tokens', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/projects/branches/user_deletes_branch_spec.rb b/spec/features/projects/branches/user_deletes_branch_spec.rb index 3b8f49accc5..8fc5c3d2e1b 100644 --- a/spec/features/projects/branches/user_deletes_branch_spec.rb +++ b/spec/features/projects/branches/user_deletes_branch_spec.rb @@ -35,6 +35,7 @@ RSpec.describe "User deletes branch", :js do context 'when the feature flag :delete_branch_confirmation_modals is disabled' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) stub_feature_flags(delete_branch_confirmation_modals: false) end diff --git a/spec/features/projects/branches_spec.rb b/spec/features/projects/branches_spec.rb index 0a79719f14a..2725c6a91be 100644 --- a/spec/features/projects/branches_spec.rb +++ b/spec/features/projects/branches_spec.rb @@ -179,6 +179,7 @@ RSpec.describe 'Branches' do context 'when the delete_branch_confirmation_modals feature flag is disabled' do it 'removes branch after confirmation', :js do stub_feature_flags(delete_branch_confirmation_modals: false) + stub_feature_flags(bootstrap_confirmation_modals: false) visit project_branches_filtered_path(project, state: 'all') diff --git a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb index 431cbb4ffbb..67d3276fc14 100644 --- a/spec/features/projects/commit/comments/user_deletes_comments_spec.rb +++ b/spec/features/projects/commit/comments/user_deletes_comments_spec.rb @@ -11,6 +11,7 @@ RSpec.describe "User deletes comments on a commit", :js do let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) project.add_developer(user) diff --git a/spec/features/projects/commit/user_comments_on_commit_spec.rb b/spec/features/projects/commit/user_comments_on_commit_spec.rb index 6997c2d8338..b0be6edb245 100644 --- a/spec/features/projects/commit/user_comments_on_commit_spec.rb +++ b/spec/features/projects/commit/user_comments_on_commit_spec.rb @@ -93,6 +93,8 @@ RSpec.describe "User comments on commit", :js do context "when deleting comment" do before do + stub_feature_flags(bootstrap_confirmation_modals: false) + visit(project_commit_path(project, sample_commit.id)) add_note(comment_text) diff --git a/spec/features/projects/environments/environments_spec.rb b/spec/features/projects/environments/environments_spec.rb index 2404fbf01ca..3b83c25b629 100644 --- a/spec/features/projects/environments/environments_spec.rb +++ b/spec/features/projects/environments/environments_spec.rb @@ -143,6 +143,8 @@ RSpec.describe 'Environments page', :js do create(:environment, project: project, state: :available) end + stub_feature_flags(bootstrap_confirmation_modals: false) + context 'when there are no deployments' do before do visit_environments(project) diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb index 5d7a761cb17..12e88bbf6a5 100644 --- a/spec/features/projects/jobs/user_browses_job_spec.rb +++ b/spec/features/projects/jobs/user_browses_job_spec.rb @@ -12,6 +12,7 @@ RSpec.describe 'User browses a job', :js do before do project.add_maintainer(user) project.enable_ci + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) diff --git a/spec/features/projects/members/member_leaves_project_spec.rb b/spec/features/projects/members/member_leaves_project_spec.rb index c4bd0b81dc0..4881a7bdf1a 100644 --- a/spec/features/projects/members/member_leaves_project_spec.rb +++ b/spec/features/projects/members/member_leaves_project_spec.rb @@ -9,6 +9,7 @@ RSpec.describe 'Projects > Members > Member leaves project' do before do project.add_developer(user) sign_in(user) + stub_feature_flags(bootstrap_confirmation_modals: false) end it 'user leaves project' do diff --git a/spec/features/projects/members/user_requests_access_spec.rb b/spec/features/projects/members/user_requests_access_spec.rb index 113ba692497..dcaef5f4ef0 100644 --- a/spec/features/projects/members/user_requests_access_spec.rb +++ b/spec/features/projects/members/user_requests_access_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'Projects > Members > User requests access', :js do before do sign_in(user) visit project_path(project) + stub_feature_flags(bootstrap_confirmation_modals: false) end it 'request access feature is disabled' do diff --git a/spec/features/projects/pages/user_adds_domain_spec.rb b/spec/features/projects/pages/user_adds_domain_spec.rb index de9effe3dc7..06f130ae69c 100644 --- a/spec/features/projects/pages/user_adds_domain_spec.rb +++ b/spec/features/projects/pages/user_adds_domain_spec.rb @@ -14,6 +14,8 @@ RSpec.describe 'User adds pages domain', :js do project.add_maintainer(user) sign_in(user) + + stub_feature_flags(bootstrap_confirmation_modals: false) end context 'when pages are exposed on external HTTP address', :http_pages_enabled do diff --git a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb index cf8438d5e6f..a3fc5804e13 100644 --- a/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_lets_encrypt_settings_spec.rb @@ -14,6 +14,7 @@ RSpec.describe "Pages with Let's Encrypt", :https_pages_enabled do before do allow(Gitlab.config.pages).to receive(:enabled).and_return(true) stub_lets_encrypt_settings + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_role(user, role) sign_in(user) diff --git a/spec/features/projects/pages/user_edits_settings_spec.rb b/spec/features/projects/pages/user_edits_settings_spec.rb index 71d4cce2784..1226e1dc2ed 100644 --- a/spec/features/projects/pages/user_edits_settings_spec.rb +++ b/spec/features/projects/pages/user_edits_settings_spec.rb @@ -176,6 +176,7 @@ RSpec.describe 'Pages edits pages settings', :js do describe 'Remove page' do context 'when pages are deployed' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.mark_pages_as_deployed end diff --git a/spec/features/projects/pipeline_schedules_spec.rb b/spec/features/projects/pipeline_schedules_spec.rb index 94e3331b173..9df430c0f78 100644 --- a/spec/features/projects/pipeline_schedules_spec.rb +++ b/spec/features/projects/pipeline_schedules_spec.rb @@ -11,6 +11,7 @@ RSpec.describe 'Pipeline Schedules', :js do context 'logged in as maintainer' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) project.add_maintainer(user) gitlab_sign_in(user) end diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb index 3a60087818d..e38c4989f26 100644 --- a/spec/features/projects/pipelines/pipelines_spec.rb +++ b/spec/features/projects/pipelines/pipelines_spec.rb @@ -317,6 +317,7 @@ RSpec.describe 'Pipelines', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) visit_project_pipelines end diff --git a/spec/features/projects/settings/access_tokens_spec.rb b/spec/features/projects/settings/access_tokens_spec.rb index 4941b936c0c..d8de9e0449e 100644 --- a/spec/features/projects/settings/access_tokens_spec.rb +++ b/spec/features/projects/settings/access_tokens_spec.rb @@ -13,6 +13,7 @@ RSpec.describe 'Project > Settings > Access Tokens', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/projects/settings/user_searches_in_settings_spec.rb b/spec/features/projects/settings/user_searches_in_settings_spec.rb index 7ed96d01189..44b5464a1b0 100644 --- a/spec/features/projects/settings/user_searches_in_settings_spec.rb +++ b/spec/features/projects/settings/user_searches_in_settings_spec.rb @@ -7,6 +7,7 @@ RSpec.describe 'User searches project settings', :js do let_it_be(:project) { create(:project, :repository, namespace: user.namespace, pages_https_only: false) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) end diff --git a/spec/features/snippets/notes_on_personal_snippets_spec.rb b/spec/features/snippets/notes_on_personal_snippets_spec.rb index fc88cd9205c..6bd31d7314c 100644 --- a/spec/features/snippets/notes_on_personal_snippets_spec.rb +++ b/spec/features/snippets/notes_on_personal_snippets_spec.rb @@ -18,6 +18,7 @@ RSpec.describe 'Comments on personal snippets', :js do end before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in user visit snippet_path(snippet) diff --git a/spec/features/snippets/user_creates_snippet_spec.rb b/spec/features/snippets/user_creates_snippet_spec.rb index ca050daa62a..82fe895d397 100644 --- a/spec/features/snippets/user_creates_snippet_spec.rb +++ b/spec/features/snippets/user_creates_snippet_spec.rb @@ -16,6 +16,7 @@ RSpec.describe 'User creates snippet', :js do let(:snippet_title_field) { 'snippet-title' } before do + stub_feature_flags(bootstrap_confirmation_modals: false) sign_in(user) visit new_snippet_path diff --git a/spec/features/triggers_spec.rb b/spec/features/triggers_spec.rb index 6fa805d8c74..2ddd86dd807 100644 --- a/spec/features/triggers_spec.rb +++ b/spec/features/triggers_spec.rb @@ -72,6 +72,7 @@ RSpec.describe 'Triggers', :js do describe 'trigger "Revoke" workflow' do before do + stub_feature_flags(bootstrap_confirmation_modals: false) create(:ci_trigger, owner: user2, project: @project, description: trigger_title) visit project_settings_ci_cd_path(@project) end diff --git a/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js new file mode 100644 index 00000000000..d19f9352bbc --- /dev/null +++ b/spec/frontend/lib/utils/confirm_via_gl_modal/confirm_modal_spec.js @@ -0,0 +1,59 @@ +import { GlModal } from '@gitlab/ui'; +import { mount } from '@vue/test-utils'; +import ConfirmModal from '~/lib/utils/confirm_via_gl_modal/confirm_modal.vue'; + +describe('Confirm Modal', () => { + let wrapper; + let modal; + + const createComponent = ({ primaryText, primaryVariant } = {}) => { + wrapper = mount(ConfirmModal, { + propsData: { + primaryText, + primaryVariant, + }, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + const findGlModal = () => wrapper.findComponent(GlModal); + + describe('Modal events', () => { + beforeEach(() => { + createComponent(); + modal = findGlModal(); + }); + + it('should emit `confirmed` event on `primary` modal event', () => { + findGlModal().vm.$emit('primary'); + expect(wrapper.emitted('confirmed')).toBeTruthy(); + }); + + it('should emit closed` event on `hidden` modal event', () => { + modal.vm.$emit('hidden'); + expect(wrapper.emitted('closed')).toBeTruthy(); + }); + }); + + describe('Custom properties', () => { + it('should pass correct custom primary text & button variant to the modal when provided', () => { + const primaryText = "Let's do it!"; + const primaryVariant = 'danger'; + + createComponent({ primaryText, primaryVariant }); + const customProps = findGlModal().props('actionPrimary'); + expect(customProps.text).toBe(primaryText); + expect(customProps.attributes.variant).toBe(primaryVariant); + }); + + it('should pass default primary text & button variant to the modal if no custom values provided', () => { + createComponent(); + const customProps = findGlModal().props('actionPrimary'); + expect(customProps.text).toBe('OK'); + expect(customProps.attributes.variant).toBe('confirm'); + }); + }); +}); diff --git a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js index 082a8977710..9d510b3d231 100644 --- a/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js +++ b/spec/frontend/pages/shared/wikis/components/wiki_form_spec.js @@ -8,9 +8,11 @@ import waitForPromises from 'helpers/wait_for_promises'; import ContentEditor from '~/content_editor/components/content_editor.vue'; import WikiForm from '~/pages/shared/wikis/components/wiki_form.vue'; import { - WIKI_CONTENT_EDITOR_TRACKING_LABEL, CONTENT_EDITOR_LOADED_ACTION, SAVED_USING_CONTENT_EDITOR_ACTION, + WIKI_CONTENT_EDITOR_TRACKING_LABEL, + WIKI_FORMAT_LABEL, + WIKI_FORMAT_UPDATED_ACTION, } from '~/pages/shared/wikis/constants'; import MarkdownField from '~/vue_shared/components/markdown/field.vue'; @@ -65,7 +67,6 @@ describe('WikiForm', () => { const pageInfoPersisted = { ...pageInfoNew, persisted: true, - title: 'My page', content: ' My page content ', format: 'markdown', @@ -177,7 +178,7 @@ describe('WikiForm', () => { await wrapper.vm.$nextTick(); expect(wrapper.text()).toContain(titleHelpText); - expect(findTitleHelpLink().attributes().href).toEqual(titleHelpLink); + expect(findTitleHelpLink().attributes().href).toBe(titleHelpLink); }, ); @@ -186,7 +187,7 @@ describe('WikiForm', () => { await wrapper.vm.$nextTick(); - expect(findMarkdownHelpLink().attributes().href).toEqual( + expect(findMarkdownHelpLink().attributes().href).toBe( '/help/user/markdown#wiki-specific-markdown', ); }); @@ -220,8 +221,8 @@ describe('WikiForm', () => { expect(e.preventDefault).not.toHaveBeenCalled(); }); - it('does not trigger tracking event', async () => { - expect(trackingSpy).not.toHaveBeenCalled(); + it('triggers wiki format tracking event', async () => { + expect(trackingSpy).toHaveBeenCalledTimes(1); }); it('does not trim page content', () => { @@ -273,7 +274,7 @@ describe('WikiForm', () => { ({ persisted, redirectLink }) => { createWrapper(persisted); - expect(findCancelButton().attributes().href).toEqual(redirectLink); + expect(findCancelButton().attributes().href).toBe(redirectLink); }, ); }); @@ -438,7 +439,7 @@ describe('WikiForm', () => { }); }); - it('triggers tracking event on form submit', async () => { + it('triggers tracking events on form submit', async () => { triggerFormSubmit(); await wrapper.vm.$nextTick(); @@ -446,6 +447,15 @@ describe('WikiForm', () => { expect(trackingSpy).toHaveBeenCalledWith(undefined, SAVED_USING_CONTENT_EDITOR_ACTION, { label: WIKI_CONTENT_EDITOR_TRACKING_LABEL, }); + + expect(trackingSpy).toHaveBeenCalledWith(undefined, WIKI_FORMAT_UPDATED_ACTION, { + label: WIKI_FORMAT_LABEL, + value: findFormat().element.value, + extra: { + old_format: pageInfoPersisted.format, + project_path: pageInfoPersisted.path, + }, + }); }); it('updates content from content editor on form submit', async () => { diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js index a5807ac588c..0fd3e7446da 100644 --- a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js +++ b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js @@ -1,5 +1,5 @@ import { GlButton, GlDropdown, GlLoadingIcon, GlToggle } from '@gitlab/ui'; -import { shallowMount } from '@vue/test-utils'; +import { shallowMount, mount } from '@vue/test-utils'; import { nextTick } from 'vue'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import ServiceDeskSetting from '~/projects/settings_service_desk/components/service_desk_setting.vue'; @@ -16,9 +16,9 @@ describe('ServiceDeskSetting', () => { const findTemplateDropdown = () => wrapper.find(GlDropdown); const findToggle = () => wrapper.find(GlToggle); - const createComponent = ({ props = {} } = {}) => + const createComponent = ({ props = {}, mountFunction = shallowMount } = {}) => extendedWrapper( - shallowMount(ServiceDeskSetting, { + mountFunction(ServiceDeskSetting, { propsData: { isEnabled: true, ...props, @@ -128,6 +128,23 @@ describe('ServiceDeskSetting', () => { expect(input.exists()).toBe(true); expect(input.attributes('disabled')).toBeUndefined(); }); + + it('shows error when value contains uppercase or special chars', async () => { + wrapper = createComponent({ + props: { customEmailEnabled: true }, + mountFunction: mount, + }); + + const input = wrapper.findByTestId('project-suffix'); + + input.setValue('abc_A.'); + input.trigger('blur'); + + await wrapper.vm.$nextTick(); + + const errorText = wrapper.find('.text-danger'); + expect(errorText.exists()).toBe(true); + }); }); describe('customEmail is the same as incomingEmail', () => { diff --git a/spec/frontend/runner/components/runner_tag_spec.js b/spec/frontend/runner/components/runner_tag_spec.js index dda318f8153..bd05d4b2cfe 100644 --- a/spec/frontend/runner/components/runner_tag_spec.js +++ b/spec/frontend/runner/components/runner_tag_spec.js @@ -1,18 +1,35 @@ import { GlBadge } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; +import { nextTick } from 'vue'; import RunnerTag from '~/runner/components/runner_tag.vue'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; + +const mockTag = 'tag1'; describe('RunnerTag', () => { let wrapper; const findBadge = () => wrapper.findComponent(GlBadge); + const getTooltipValue = () => getBinding(findBadge().element, 'gl-tooltip').value; + + const setDimensions = ({ scrollWidth, offsetWidth }) => { + jest.spyOn(findBadge().element, 'scrollWidth', 'get').mockReturnValue(scrollWidth); + jest.spyOn(findBadge().element, 'offsetWidth', 'get').mockReturnValue(offsetWidth); + + // Mock trigger resize + getBinding(findBadge().element, 'gl-resize-observer').value(); + }; const createComponent = ({ props = {} } = {}) => { wrapper = shallowMount(RunnerTag, { propsData: { - tag: 'tag1', + tag: mockTag, ...props, }, + directives: { + GlTooltip: createMockDirective(), + GlResizeObserver: createMockDirective(), + }, }); }; @@ -25,21 +42,36 @@ describe('RunnerTag', () => { }); it('Displays tag text', () => { - expect(wrapper.text()).toBe('tag1'); + expect(wrapper.text()).toBe(mockTag); }); it('Displays tags with correct style', () => { expect(findBadge().props()).toMatchObject({ - size: 'md', - variant: 'info', + size: 'sm', + variant: 'neutral', }); }); - it('Displays tags with small size', () => { + it('Displays tags with md size', () => { createComponent({ - props: { size: 'sm' }, + props: { size: 'md' }, }); - expect(findBadge().props('size')).toBe('sm'); + expect(findBadge().props('size')).toBe('md'); }); + + it.each` + case | scrollWidth | offsetWidth | expectedTooltip + ${'overflowing'} | ${110} | ${100} | ${mockTag} + ${'not overflowing'} | ${90} | ${100} | ${''} + ${'almost overflowing'} | ${100} | ${100} | ${''} + `( + 'Sets "$expectedTooltip" as tooltip when $case', + async ({ scrollWidth, offsetWidth, expectedTooltip }) => { + setDimensions({ scrollWidth, offsetWidth }); + await nextTick(); + + expect(getTooltipValue()).toBe(expectedTooltip); + }, + ); }); diff --git a/spec/frontend/runner/components/runner_tags_spec.js b/spec/frontend/runner/components/runner_tags_spec.js index b6487ade0d6..da89a659432 100644 --- a/spec/frontend/runner/components/runner_tags_spec.js +++ b/spec/frontend/runner/components/runner_tags_spec.js @@ -33,16 +33,16 @@ describe('RunnerTags', () => { }); it('Displays tags with correct style', () => { - expect(findBadge().props('size')).toBe('md'); - expect(findBadge().props('variant')).toBe('info'); + expect(findBadge().props('size')).toBe('sm'); + expect(findBadge().props('variant')).toBe('neutral'); }); - it('Displays tags with small size', () => { + it('Displays tags with md size', () => { createComponent({ - props: { size: 'sm' }, + props: { size: 'md' }, }); - expect(findBadge().props('size')).toBe('sm'); + expect(findBadge().props('size')).toBe('md'); }); it('Is empty when there are no tags', () => { diff --git a/spec/frontend/vue_shared/components/notes/system_note_spec.js b/spec/frontend/vue_shared/components/notes/system_note_spec.js index 48dacc50923..65f79bab005 100644 --- a/spec/frontend/vue_shared/components/notes/system_note_spec.js +++ b/spec/frontend/vue_shared/components/notes/system_note_spec.js @@ -1,13 +1,27 @@ +import MockAdapter from 'axios-mock-adapter'; import { mount } from '@vue/test-utils'; +import waitForPromises from 'helpers/wait_for_promises'; import initMRPopovers from '~/mr_popover/index'; import createStore from '~/notes/stores'; import IssueSystemNote from '~/vue_shared/components/notes/system_note.vue'; +import axios from '~/lib/utils/axios_utils'; jest.mock('~/mr_popover/index', () => jest.fn()); describe('system note component', () => { let vm; let props; + let mock; + + function createComponent(propsData = {}) { + const store = createStore(); + store.dispatch('setTargetNoteHash', `note_${props.note.id}`); + + vm = mount(IssueSystemNote, { + store, + propsData, + }); + } beforeEach(() => { props = { @@ -27,28 +41,29 @@ describe('system note component', () => { }, }; - const store = createStore(); - store.dispatch('setTargetNoteHash', `note_${props.note.id}`); - - vm = mount(IssueSystemNote, { - store, - propsData: props, - }); + mock = new MockAdapter(axios); }); afterEach(() => { vm.destroy(); + mock.restore(); }); it('should render a list item with correct id', () => { + createComponent(props); + expect(vm.attributes('id')).toEqual(`note_${props.note.id}`); }); it('should render target class is note is target note', () => { + createComponent(props); + expect(vm.classes()).toContain('target'); }); it('should render svg icon', () => { + createComponent(props); + expect(vm.find('.timeline-icon svg').exists()).toBe(true); }); @@ -56,10 +71,31 @@ describe('system note component', () => { // we need to strip them because they break layout of commit lists in system notes: // https://gitlab.com/gitlab-org/gitlab-foss/uploads/b07a10670919254f0220d3ff5c1aa110/jqzI.png it('removes wrapping paragraph from note HTML', () => { + createComponent(props); + expect(vm.find('.system-note-message').html()).toContain('<span>closed</span>'); }); it('should initMRPopovers onMount', () => { + createComponent(props); + expect(initMRPopovers).toHaveBeenCalled(); }); + + it('renders outdated code lines', async () => { + mock + .onGet('/outdated_line_change_path') + .reply(200, [ + { rich_text: 'console.log', type: 'new', line_code: '123', old_line: null, new_line: 1 }, + ]); + + createComponent({ + note: { ...props.note, outdated_line_change_path: '/outdated_line_change_path' }, + }); + + await vm.find("[data-testid='outdated-lines-change-btn']").trigger('click'); + await waitForPromises(); + + expect(vm.find("[data-testid='outdated-lines']").exists()).toBe(true); + }); }); diff --git a/spec/graphql/resolvers/concerns/resolves_groups_spec.rb b/spec/graphql/resolvers/concerns/resolves_groups_spec.rb new file mode 100644 index 00000000000..bfbbae29e92 --- /dev/null +++ b/spec/graphql/resolvers/concerns/resolves_groups_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe ResolvesGroups do + include GraphqlHelpers + include AfterNextHelpers + + let_it_be(:user) { create(:user) } + let_it_be(:groups) { create_pair(:group) } + + let_it_be(:resolver) do + Class.new(Resolvers::BaseResolver) do + include ResolvesGroups + type Types::GroupType, null: true + end + end + + let_it_be(:query_type) do + query_factory do |query| + query.field :groups, + Types::GroupType.connection_type, + null: true, + resolver: resolver + end + end + + let_it_be(:lookahead_fields) do + <<~FIELDS + contacts { nodes { id } } + containerRepositoriesCount + customEmoji { nodes { id } } + fullPath + organizations { nodes { id } } + path + dependencyProxyBlobCount + dependencyProxyBlobs { nodes { fileName } } + dependencyProxyImageCount + dependencyProxyImageTtlPolicy { enabled } + dependencyProxySetting { enabled } + FIELDS + end + + it 'avoids N+1 queries on the fields marked with lookahead' do + group_ids = groups.map(&:id) + + allow_next(resolver).to receive(:resolve_groups).and_return(Group.id_in(group_ids)) + # Prevent authorization queries from affecting the test. + allow(Ability).to receive(:allowed?).and_return(true) + + single_group_query = ActiveRecord::QueryRecorder.new do + data = query_groups(limit: 1) + expect(data.size).to eq(1) + end + + multi_group_query = -> { + data = query_groups(limit: 2) + expect(data.size).to eq(2) + } + + expect { multi_group_query.call }.not_to exceed_query_limit(single_group_query) + end + + def query_groups(limit:) + query_string = "{ groups(first: #{limit}) { nodes { id #{lookahead_fields} } } }" + + data = execute_query(query_type, graphql: query_string) + + graphql_dig_at(data, :data, :groups, :nodes) + end +end diff --git a/spec/lib/gitlab/ci/variables/collection_spec.rb b/spec/lib/gitlab/ci/variables/collection_spec.rb index 6e3ed27bb44..26c560565e0 100644 --- a/spec/lib/gitlab/ci/variables/collection_spec.rb +++ b/spec/lib/gitlab/ci/variables/collection_spec.rb @@ -358,8 +358,6 @@ RSpec.describe Gitlab::Ci::Variables::Collection do end describe '#sort_and_expand_all' do - let_it_be(:project) { create(:project) } - context 'table tests' do using RSpec::Parameterized::TableSyntax @@ -550,7 +548,7 @@ RSpec.describe Gitlab::Ci::Variables::Collection do with_them do let(:collection) { Gitlab::Ci::Variables::Collection.new(variables) } - subject { collection.sort_and_expand_all(project, keep_undefined: keep_undefined) } + subject { collection.sort_and_expand_all(keep_undefined: keep_undefined) } it 'returns Collection' do is_expected.to be_an_instance_of(Gitlab::Ci::Variables::Collection) diff --git a/spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb b/spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb index bdeaabec1f1..b646cf38178 100644 --- a/spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb +++ b/spec/lib/gitlab/diff/position_tracer/line_strategy_spec.rb @@ -581,13 +581,16 @@ RSpec.describe Gitlab::Diff::PositionTracer::LineStrategy, :clean_gitlab_redis_c ) end - it "returns the new position but drops line_range information" do + it "returns the new position" do expect_change_position( old_path: file_name, new_path: file_name, old_line: nil, new_line: 2, - line_range: nil + line_range: { + "start_line_code" => 1, + "end_line_code" => 2 + } ) end end diff --git a/spec/models/group_spec.rb b/spec/models/group_spec.rb index 2467ef541b2..ae6513a3bc1 100644 --- a/spec/models/group_spec.rb +++ b/spec/models/group_spec.rb @@ -37,6 +37,8 @@ RSpec.describe Group do it { is_expected.to have_many(:daily_build_group_report_results).class_name('Ci::DailyBuildGroupReportResult') } it { is_expected.to have_many(:group_callouts).class_name('Users::GroupCallout').with_foreign_key(:group_id) } it { is_expected.to have_many(:bulk_import_exports).class_name('BulkImports::Export') } + it { is_expected.to have_many(:contacts).class_name('CustomerRelations::Contact') } + it { is_expected.to have_many(:organizations).class_name('CustomerRelations::Organization') } describe '#members & #requesters' do let(:requester) { create(:user) } diff --git a/spec/support/shared_examples/features/2fa_shared_examples.rb b/spec/support/shared_examples/features/2fa_shared_examples.rb index ddc03e178ba..94c91556ea7 100644 --- a/spec/support/shared_examples/features/2fa_shared_examples.rb +++ b/spec/support/shared_examples/features/2fa_shared_examples.rb @@ -18,6 +18,7 @@ RSpec.shared_examples 'hardware device for 2fa' do |device_type| let(:user) { create(:user) } before do + stub_feature_flags(bootstrap_confirmation_modals: false) gitlab_sign_in(user) user.update_attribute(:otp_required_for_login, true) end |