diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-16 00:10:20 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-06-16 00:10:20 +0300 |
commit | be522a9abd386ad605786eeb805e12025af0c742 (patch) | |
tree | 3f1057f84c7594b42a889281f96fd51fb778e894 /spec | |
parent | 0e5ce539275e32cfd7592362e03673807fca9cc7 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
7 files changed, 216 insertions, 100 deletions
diff --git a/spec/fixtures/api/schemas/public_api/v4/integration.json b/spec/fixtures/api/schemas/public_api/v4/integration.json index 18e61636fa2..8902196a2c4 100644 --- a/spec/fixtures/api/schemas/public_api/v4/integration.json +++ b/spec/fixtures/api/schemas/public_api/v4/integration.json @@ -33,6 +33,9 @@ "incident_events": { "type": "boolean" }, + "alert_events": { + "type": "boolean" + }, "confidential_issues_events": { "type": "boolean" }, @@ -42,6 +45,9 @@ "tag_push_events": { "type": "boolean" }, + "deployment_events": { + "type": "boolean" + }, "note_events": { "type": "boolean" }, @@ -62,4 +68,4 @@ } }, "additionalProperties": false -}
\ No newline at end of file +} diff --git a/spec/frontend/invite_members/components/import_project_members_modal_spec.js b/spec/frontend/invite_members/components/import_project_members_modal_spec.js index 73634855850..224ebe18e2a 100644 --- a/spec/frontend/invite_members/components/import_project_members_modal_spec.js +++ b/spec/frontend/invite_members/components/import_project_members_modal_spec.js @@ -6,19 +6,28 @@ import { BV_HIDE_MODAL } from '~/lib/utils/constants'; import { stubComponent } from 'helpers/stub_component'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import waitForPromises from 'helpers/wait_for_promises'; +import { mockTracking, unmockTracking } from 'helpers/tracking_helper'; import * as ProjectsApi from '~/api/projects_api'; +import eventHub from '~/invite_members/event_hub'; import ImportProjectMembersModal from '~/invite_members/components/import_project_members_modal.vue'; import ProjectSelect from '~/invite_members/components/project_select.vue'; import axios from '~/lib/utils/axios_utils'; + import { displaySuccessfulInvitationAlert, reloadOnInvitationSuccess, } from '~/invite_members/utils/trigger_successful_invite_alert'; +import { + IMPORT_PROJECT_MEMBERS_MODAL_TRACKING_CATEGORY, + IMPORT_PROJECT_MEMBERS_MODAL_TRACKING_LABEL, +} from '~/invite_members/constants'; + jest.mock('~/invite_members/utils/trigger_successful_invite_alert'); let wrapper; let mock; +let trackingSpy; const projectId = '1'; const projectName = 'test name'; @@ -27,6 +36,18 @@ const $toast = { show: jest.fn(), }; +const expectTracking = (action) => + expect(trackingSpy).toHaveBeenCalledWith(IMPORT_PROJECT_MEMBERS_MODAL_TRACKING_CATEGORY, action, { + label: IMPORT_PROJECT_MEMBERS_MODAL_TRACKING_LABEL, + category: IMPORT_PROJECT_MEMBERS_MODAL_TRACKING_CATEGORY, + property: undefined, + }); + +const triggerOpenModal = async () => { + eventHub.$emit('openProjectMembersModal'); + await nextTick(); +}; + const createComponent = ({ props = {} } = {}) => { wrapper = shallowMountExtended(ImportProjectMembersModal, { propsData: { @@ -48,6 +69,8 @@ const createComponent = ({ props = {} } = {}) => { $toast, }, }); + + trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); }; beforeEach(() => { @@ -57,6 +80,7 @@ beforeEach(() => { afterEach(() => { mock.restore(); + unmockTracking(); }); describe('ImportProjectMembersModal', () => { @@ -106,6 +130,24 @@ describe('ImportProjectMembersModal', () => { expect(findGlModal().props('actionPrimary').attributes.loading).toBe(true); }); + + it('tracks render', async () => { + await triggerOpenModal(); + + expectTracking('render'); + }); + + it('tracks cancel', () => { + findGlModal().vm.$emit('cancel'); + + expectTracking('click_cancel'); + }); + + it('tracks close', () => { + findGlModal().vm.$emit('close'); + + expectTracking('click_x'); + }); }); describe('submitting the import', () => { @@ -145,6 +187,10 @@ describe('ImportProjectMembersModal', () => { wrapper.vm.$options.toastOptions, ); }); + + it('tracks successful import', () => { + expectTracking('invite_successful'); + }); }); describe('when the import is successful', () => { @@ -189,6 +235,10 @@ describe('ImportProjectMembersModal', () => { it('sets isLoading to false after success', () => { expect(findGlModal().props('actionPrimary').attributes.loading).toBe(false); }); + + it('tracks successful import', () => { + expectTracking('invite_successful'); + }); }); describe('when the import fails', () => { diff --git a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb index 0bdb9f7938d..ddec335a54a 100644 --- a/spec/lib/gitlab/gitaly_client/commit_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/commit_service_spec.rb @@ -287,6 +287,129 @@ RSpec.describe Gitlab::GitalyClient::CommitService, feature_category: :gitaly do is_expected.to eq([[], pagination_cursor]) end end + + context 'with structured errors' do + context 'with ResolveTree error' do + before do + expect_any_instance_of(Gitaly::CommitService::Stub) + .to receive(:get_tree_entries) + .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) + .and_raise(raised_error) + end + + let(:raised_error) do + new_detailed_error( + GRPC::Core::StatusCodes::INVALID_ARGUMENT, + "invalid revision or path", + Gitaly::GetTreeEntriesError.new( + resolve_tree: Gitaly::ResolveRevisionError.new( + revision: "incorrect revision" + ))) + end + + it 'raises an IndexError' do + expect { subject }.to raise_error do |error| + expect(error).to be_a(Gitlab::Git::Index::IndexError) + expect(error.message).to eq("invalid revision or path") + end + end + end + + context 'with Path error' do + let(:status_code) { nil } + let(:expected_error) { nil } + + let(:structured_error) do + new_detailed_error( + status_code, + "invalid revision or path", + expected_error) + end + + shared_examples '#get_tree_entries path failure' do + it 'raises an IndexError' do + expect_any_instance_of(Gitaly::CommitService::Stub) + .to receive(:get_tree_entries).with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) + .and_raise(structured_error) + + expect { subject }.to raise_error do |error| + expect(error).to be_a(Gitlab::Git::Index::IndexError) + expect(error.message).to eq(expected_message) + end + end + end + + context 'with missing file' do + let(:status_code) { GRPC::Core::StatusCodes::INVALID_ARGUMENT } + let(:expected_message) { "You must provide a file path" } + let(:expected_error) do + Gitaly::GetTreeEntriesError.new( + path: Gitaly::PathError.new( + path: "random path", + error_type: :ERROR_TYPE_EMPTY_PATH + )) + end + + it_behaves_like '#get_tree_entries path failure' + end + + context 'with path including traversal' do + let(:status_code) { GRPC::Core::StatusCodes::INVALID_ARGUMENT } + let(:expected_message) { "Path cannot include traversal syntax" } + let(:expected_error) do + Gitaly::GetTreeEntriesError.new( + path: Gitaly::PathError.new( + path: "foo/../bar", + error_type: :ERROR_TYPE_RELATIVE_PATH_ESCAPES_REPOSITORY + )) + end + + it_behaves_like '#get_tree_entries path failure' + end + + context 'with absolute path' do + let(:status_code) { GRPC::Core::StatusCodes::INVALID_ARGUMENT } + let(:expected_message) { "Only relative path is accepted" } + let(:expected_error) do + Gitaly::GetTreeEntriesError.new( + path: Gitaly::PathError.new( + path: "/bar/foo", + error_type: :ERROR_TYPE_ABSOLUTE_PATH + )) + end + + it_behaves_like '#get_tree_entries path failure' + end + + context 'with long path' do + let(:status_code) { GRPC::Core::StatusCodes::INVALID_ARGUMENT } + let(:expected_message) { "Path is too long" } + let(:expected_error) do + Gitaly::GetTreeEntriesError.new( + path: Gitaly::PathError.new( + path: "long/path/", + error_type: :ERROR_TYPE_LONG_PATH + )) + end + + it_behaves_like '#get_tree_entries path failure' + end + + context 'with unkown path error' do + let(:status_code) { GRPC::Core::StatusCodes::INVALID_ARGUMENT } + let(:expected_message) { "Unknown path error" } + let(:expected_error) do + Gitaly::GetTreeEntriesError.new( + path: Gitaly::PathError.new( + path: "unkown error", + error_type: :ERROR_TYPE_UNSPECIFIED + )) + end + + it_behaves_like '#get_tree_entries path failure' + end + end + end end describe '#commit_count' do diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb index 7bdfa8922d3..89ac0c119bf 100644 --- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb +++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb @@ -147,92 +147,53 @@ RSpec.describe Gitlab::GitalyClient::RefService, feature_category: :gitaly do describe '#local_branches' do let(:remote_name) { 'my_remote' } - shared_examples 'common examples' do - it 'sends a find_local_branches message' do - target_commits = create_list(:gitaly_commit, 4) - branches = target_commits.each_with_index.map do |gitaly_commit, i| - Gitaly::FindLocalBranchResponse.new( - name: "#{remote_name}/#{i}", - commit: gitaly_commit, - commit_author: Gitaly::FindLocalBranchCommitAuthor.new( - name: gitaly_commit.author.name, - email: gitaly_commit.author.email, - date: gitaly_commit.author.date, - timezone: gitaly_commit.author.timezone - ), - commit_committer: Gitaly::FindLocalBranchCommitAuthor.new( - name: gitaly_commit.committer.name, - email: gitaly_commit.committer.email, - date: gitaly_commit.committer.date, - timezone: gitaly_commit.committer.timezone - ) - ) - end - - local_branches = target_commits.each_with_index.map do |gitaly_commit, i| - Gitaly::Branch.new(name: "#{remote_name}/#{i}", target_commit: gitaly_commit) - end - - response = if set_local_branches - [ - Gitaly::FindLocalBranchesResponse.new(local_branches: local_branches[0, 2]), - Gitaly::FindLocalBranchesResponse.new(local_branches: local_branches[2, 2]) - ] - else - [ - Gitaly::FindLocalBranchesResponse.new(branches: branches[0, 2]), - Gitaly::FindLocalBranchesResponse.new(branches: branches[2, 2]) - ] - end - - expect_any_instance_of(Gitaly::RefService::Stub) - .to receive(:find_local_branches) - .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) - .and_return(response) - - subject = client.local_branches + it 'sends a find_local_branches message' do + target_commits = create_list(:gitaly_commit, 4) - expect(subject.length).to be(target_commits.length) + local_branches = target_commits.each_with_index.map do |gitaly_commit, i| + Gitaly::Branch.new(name: "#{remote_name}/#{i}", target_commit: gitaly_commit) end - it 'parses and sends the sort parameter' do - expect_any_instance_of(Gitaly::RefService::Stub) - .to receive(:find_local_branches) - .with(gitaly_request_with_params(sort_by: :UPDATED_DESC), kind_of(Hash)) - .and_return([]) + response = [ + Gitaly::FindLocalBranchesResponse.new(local_branches: local_branches[0, 2]), + Gitaly::FindLocalBranchesResponse.new(local_branches: local_branches[2, 2]) + ] - client.local_branches(sort_by: 'updated_desc') - end + expect_any_instance_of(Gitaly::RefService::Stub) + .to receive(:find_local_branches) + .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash)) + .and_return(response) - it 'translates known mismatches on sort param values' do - expect_any_instance_of(Gitaly::RefService::Stub) - .to receive(:find_local_branches) - .with(gitaly_request_with_params(sort_by: :NAME), kind_of(Hash)) - .and_return([]) + subject = client.local_branches - client.local_branches(sort_by: 'name_asc') - end + expect(subject.length).to be(target_commits.length) + end - it 'uses default sort by name' do - expect_any_instance_of(Gitaly::RefService::Stub) - .to receive(:find_local_branches) - .with(gitaly_request_with_params(sort_by: :NAME), kind_of(Hash)) - .and_return([]) + it 'parses and sends the sort parameter' do + expect_any_instance_of(Gitaly::RefService::Stub) + .to receive(:find_local_branches) + .with(gitaly_request_with_params(sort_by: :UPDATED_DESC), kind_of(Hash)) + .and_return([]) - client.local_branches(sort_by: 'invalid') - end + client.local_branches(sort_by: 'updated_desc') end - context 'when local_branches variable is not set' do - let(:set_local_branches) { false } + it 'translates known mismatches on sort param values' do + expect_any_instance_of(Gitaly::RefService::Stub) + .to receive(:find_local_branches) + .with(gitaly_request_with_params(sort_by: :NAME), kind_of(Hash)) + .and_return([]) - it_behaves_like 'common examples' + client.local_branches(sort_by: 'name_asc') end - context 'when local_branches variable is set' do - let(:set_local_branches) { true } + it 'uses default sort by name' do + expect_any_instance_of(Gitaly::RefService::Stub) + .to receive(:find_local_branches) + .with(gitaly_request_with_params(sort_by: :NAME), kind_of(Hash)) + .and_return([]) - it_behaves_like 'common examples' + client.local_branches(sort_by: 'invalid') end end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 61fa1eb00d2..12ab061fa03 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -206,7 +206,7 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do it { is_expected.not_to allow_value('default' => 100, shouldntexist: 50).for(:repository_storages_weighted).with_message("can't include: shouldntexist") } %i[notes_create_limit search_rate_limit search_rate_limit_unauthenticated users_get_by_id_limit - projects_api_rate_limit_unauthenticated].each do |setting| + projects_api_rate_limit_unauthenticated gitlab_shell_operation_limit].each do |setting| it { is_expected.to allow_value(400).for(setting) } it { is_expected.not_to allow_value('two').for(setting) } it { is_expected.not_to allow_value(nil).for(setting) } diff --git a/spec/requests/api/integrations_spec.rb b/spec/requests/api/integrations_spec.rb index 6fd2aafd546..4922a07cd6c 100644 --- a/spec/requests/api/integrations_spec.rb +++ b/spec/requests/api/integrations_spec.rb @@ -70,11 +70,11 @@ RSpec.describe API::Integrations, feature_category: :integrations do datadog: %i[archive_trace_events], hangouts_chat: %i[notify_only_broken_pipelines], jira: %i[issues_enabled project_key jira_issue_regex jira_issue_prefix vulnerabilities_enabled vulnerabilities_issuetype], - mattermost: %i[deployment_channel labels_to_be_notified], + mattermost: %i[labels_to_be_notified], mock_ci: %i[enable_ssl_verification], prometheus: %i[manual_configuration], pumble: %i[branches_to_be_notified notify_only_broken_pipelines], - slack: %i[alert_events alert_channel deployment_channel labels_to_be_notified], + slack: %i[labels_to_be_notified], unify_circuit: %i[branches_to_be_notified notify_only_broken_pipelines], webex_teams: %i[branches_to_be_notified notify_only_broken_pipelines] } diff --git a/spec/workers/ci/update_locked_unknown_artifacts_worker_spec.rb b/spec/workers/ci/update_locked_unknown_artifacts_worker_spec.rb index 4bb1d3561f9..3233b8a74c5 100644 --- a/spec/workers/ci/update_locked_unknown_artifacts_worker_spec.rb +++ b/spec/workers/ci/update_locked_unknown_artifacts_worker_spec.rb @@ -16,29 +16,5 @@ RSpec.describe Ci::UpdateLockedUnknownArtifactsWorker, feature_category: :build_ worker.perform end - - context 'with the ci_job_artifacts_backlog_work flag shut off' do - before do - stub_feature_flags(ci_job_artifacts_backlog_work: false) - end - - it 'does not instantiate a new Ci::JobArtifacts::UpdateUnknownLockedStatusService' do - expect(Ci::JobArtifacts::UpdateUnknownLockedStatusService).not_to receive(:new) - - worker.perform - end - - it 'does not log any artifact counts' do - expect(worker).not_to receive(:log_extra_metadata_on_done) - - worker.perform - end - - it 'does not query the database' do - query_count = ActiveRecord::QueryRecorder.new { worker.perform }.count - - expect(query_count).to eq(0) - end - end end end |