diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 09:55:51 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-07-20 09:55:51 +0000 |
commit | e8d2c2579383897a1dd7f9debd359abe8ae8373d (patch) | |
tree | c42be41678c2586d49a75cabce89322082698334 /spec/workers/jira_connect | |
parent | fc845b37ec3a90aaa719975f607740c22ba6a113 (diff) | |
download | gitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz |
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/workers/jira_connect')
7 files changed, 162 insertions, 95 deletions
diff --git a/spec/workers/jira_connect/forward_event_worker_spec.rb b/spec/workers/jira_connect/forward_event_worker_spec.rb new file mode 100644 index 00000000000..adfc071779a --- /dev/null +++ b/spec/workers/jira_connect/forward_event_worker_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe JiraConnect::ForwardEventWorker do + describe '#perform' do + let!(:jira_connect_installation) { create(:jira_connect_installation, instance_url: self_managed_url, client_key: client_key, shared_secret: shared_secret) } + let(:base_path) { '/-/jira_connect' } + let(:event_path) { '/-/jira_connect/events/uninstalled' } + + let(:self_managed_url) { 'http://example.com' } + let(:base_url) { self_managed_url + base_path } + let(:event_url) { self_managed_url + event_path } + + let(:client_key) { '123' } + let(:shared_secret) { '123' } + + subject { described_class.new.perform(jira_connect_installation.id, base_path, event_path) } + + it 'forwards the event including the auth header and deletes the installation' do + stub_request(:post, event_url) + + expect(Atlassian::Jwt).to receive(:create_query_string_hash).with(event_url, 'POST', base_url).and_return('some_qsh') + expect(Atlassian::Jwt).to receive(:encode).with({ iss: client_key, qsh: 'some_qsh' }, shared_secret).and_return('auth_token') + expect { subject }.to change(JiraConnectInstallation, :count).by(-1) + + expect(WebMock).to have_requested(:post, event_url).with(headers: { 'Authorization' => 'JWT auth_token' }) + end + + context 'when installation does not exist' do + let(:jira_connect_installation) { instance_double(JiraConnectInstallation, id: -1) } + + it 'does nothing' do + expect { subject }.not_to change(JiraConnectInstallation, :count) + end + end + + context 'when installation does not have an instance_url' do + let!(:jira_connect_installation) { create(:jira_connect_installation) } + + it 'forwards the event including the auth header' do + expect { subject }.to change(JiraConnectInstallation, :count).by(-1) + + expect(WebMock).not_to have_requested(:post, '*') + end + end + + context 'when it fails to forward the event' do + it 'still deletes the installation' do + allow(Gitlab::HTTP).to receive(:post).and_raise(StandardError) + + expect { subject }.to raise_error(StandardError).and change(JiraConnectInstallation, :count).by(-1) + end + end + end +end diff --git a/spec/workers/jira_connect/sync_branch_worker_spec.rb b/spec/workers/jira_connect/sync_branch_worker_spec.rb index 7c715f36fb4..349ccd10694 100644 --- a/spec/workers/jira_connect/sync_branch_worker_spec.rb +++ b/spec/workers/jira_connect/sync_branch_worker_spec.rb @@ -5,6 +5,10 @@ require 'spec_helper' RSpec.describe JiraConnect::SyncBranchWorker do include AfterNextHelpers + it_behaves_like 'worker with data consistency', + described_class, + data_consistency: :delayed + describe '#perform' do let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, :repository, group: group) } @@ -15,65 +19,59 @@ RSpec.describe JiraConnect::SyncBranchWorker do let(:commit_shas) { %w(b83d6e3 5a62481) } let(:update_sequence_id) { 1 } + def perform + described_class.new.perform(project_id, branch_name, commit_shas, update_sequence_id) + end + def expect_jira_sync_service_execute(args) - expect_next_instances_of(JiraConnect::SyncService, IdempotentWorkerHelper::WORKER_EXEC_TIMES) do |instance| - expect(instance).to receive(:execute).with(args) - end + expect_next(JiraConnect::SyncService).to receive(:execute).with(args) end - it_behaves_like 'an idempotent worker' do - let(:job_args) { [project_id, branch_name, commit_shas, update_sequence_id] } + it 'calls JiraConnect::SyncService#execute' do + expect_jira_sync_service_execute( + branches: [instance_of(Gitlab::Git::Branch)], + commits: project.commits_by(oids: commit_shas), + update_sequence_id: update_sequence_id + ) - before do - stub_request(:post, 'https://sample.atlassian.net/rest/devinfo/0.10/bulk').to_return(status: 200, body: '', headers: {}) - end + perform + end + + context 'without branch name' do + let(:branch_name) { nil } it 'calls JiraConnect::SyncService#execute' do expect_jira_sync_service_execute( - branches: [instance_of(Gitlab::Git::Branch)], + branches: nil, commits: project.commits_by(oids: commit_shas), update_sequence_id: update_sequence_id ) - subject - end - - context 'without branch name' do - let(:branch_name) { nil } - - it 'calls JiraConnect::SyncService#execute' do - expect_jira_sync_service_execute( - branches: nil, - commits: project.commits_by(oids: commit_shas), - update_sequence_id: update_sequence_id - ) - - subject - end + perform end + end - context 'without commits' do - let(:commit_shas) { nil } + context 'without commits' do + let(:commit_shas) { nil } - it 'calls JiraConnect::SyncService#execute' do - expect_jira_sync_service_execute( - branches: [instance_of(Gitlab::Git::Branch)], - commits: nil, - update_sequence_id: update_sequence_id - ) + it 'calls JiraConnect::SyncService#execute' do + expect_jira_sync_service_execute( + branches: [instance_of(Gitlab::Git::Branch)], + commits: nil, + update_sequence_id: update_sequence_id + ) - subject - end + perform end + end - context 'when project no longer exists' do - let(:project_id) { non_existing_record_id } + context 'when project no longer exists' do + let(:project_id) { non_existing_record_id } - it 'does not call JiraConnect::SyncService' do - expect(JiraConnect::SyncService).not_to receive(:new) + it 'does not call JiraConnect::SyncService' do + expect(JiraConnect::SyncService).not_to receive(:new) - subject - end + perform end end end diff --git a/spec/workers/jira_connect/sync_builds_worker_spec.rb b/spec/workers/jira_connect/sync_builds_worker_spec.rb index 8fb8692fdf7..9be0cccae2b 100644 --- a/spec/workers/jira_connect/sync_builds_worker_spec.rb +++ b/spec/workers/jira_connect/sync_builds_worker_spec.rb @@ -4,7 +4,10 @@ require 'spec_helper' RSpec.describe ::JiraConnect::SyncBuildsWorker do include AfterNextHelpers - include ServicesHelper + + it_behaves_like 'worker with data consistency', + described_class, + data_consistency: :delayed describe '#perform' do let_it_be(:pipeline) { create(:ci_pipeline) } diff --git a/spec/workers/jira_connect/sync_deployments_worker_spec.rb b/spec/workers/jira_connect/sync_deployments_worker_spec.rb index 16fa2643d04..86ba11ebe9c 100644 --- a/spec/workers/jira_connect/sync_deployments_worker_spec.rb +++ b/spec/workers/jira_connect/sync_deployments_worker_spec.rb @@ -4,7 +4,10 @@ require 'spec_helper' RSpec.describe ::JiraConnect::SyncDeploymentsWorker do include AfterNextHelpers - include ServicesHelper + + it_behaves_like 'worker with data consistency', + described_class, + data_consistency: :delayed describe '#perform' do let_it_be(:deployment) { create(:deployment) } diff --git a/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb b/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb index 038eed7b9f1..6763aefcbec 100644 --- a/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb +++ b/spec/workers/jira_connect/sync_feature_flags_worker_spec.rb @@ -4,7 +4,10 @@ require 'spec_helper' RSpec.describe ::JiraConnect::SyncFeatureFlagsWorker do include AfterNextHelpers - include ServicesHelper + + it_behaves_like 'worker with data consistency', + described_class, + data_consistency: :delayed describe '#perform' do let_it_be(:feature_flag) { create(:operations_feature_flag) } diff --git a/spec/workers/jira_connect/sync_merge_request_worker_spec.rb b/spec/workers/jira_connect/sync_merge_request_worker_spec.rb index 6a0a0744f6f..65976566b22 100644 --- a/spec/workers/jira_connect/sync_merge_request_worker_spec.rb +++ b/spec/workers/jira_connect/sync_merge_request_worker_spec.rb @@ -5,6 +5,10 @@ require 'spec_helper' RSpec.describe JiraConnect::SyncMergeRequestWorker do include AfterNextHelpers + it_behaves_like 'worker with data consistency', + described_class, + data_consistency: :delayed + describe '#perform' do let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, :repository, group: group) } @@ -14,29 +18,24 @@ RSpec.describe JiraConnect::SyncMergeRequestWorker do let(:merge_request_id) { merge_request.id } let(:update_sequence_id) { 1 } - it_behaves_like 'an idempotent worker' do - let(:job_args) { [merge_request_id, update_sequence_id] } - - before do - stub_request(:post, 'https://sample.atlassian.net/rest/devinfo/0.10/bulk').to_return(status: 200, body: '', headers: {}) - end + def perform + described_class.new.perform(merge_request_id, update_sequence_id) + end - it 'calls JiraConnect::SyncService#execute' do - expect_next_instances_of(JiraConnect::SyncService, IdempotentWorkerHelper::WORKER_EXEC_TIMES) do |service| - expect(service).to receive(:execute).with(merge_requests: [merge_request], update_sequence_id: update_sequence_id) - end + it 'calls JiraConnect::SyncService#execute' do + expect_next(JiraConnect::SyncService).to receive(:execute) + .with(merge_requests: [merge_request], update_sequence_id: update_sequence_id) - subject - end + perform + end - context 'when MR no longer exists' do - let(:merge_request_id) { non_existing_record_id } + context 'when MR no longer exists' do + let(:merge_request_id) { non_existing_record_id } - it 'does not call JiraConnect::SyncService' do - expect(JiraConnect::SyncService).not_to receive(:new) + it 'does not call JiraConnect::SyncService' do + expect(JiraConnect::SyncService).not_to receive(:new) - subject - end + perform end end end diff --git a/spec/workers/jira_connect/sync_project_worker_spec.rb b/spec/workers/jira_connect/sync_project_worker_spec.rb index 5c0e7e7609c..d172bde2400 100644 --- a/spec/workers/jira_connect/sync_project_worker_spec.rb +++ b/spec/workers/jira_connect/sync_project_worker_spec.rb @@ -3,6 +3,12 @@ require 'spec_helper' RSpec.describe JiraConnect::SyncProjectWorker, factory_default: :keep do + include AfterNextHelpers + + it_behaves_like 'worker with data consistency', + described_class, + data_consistency: :delayed + describe '#perform' do let_it_be(:project) { create_default(:project).freeze } @@ -14,6 +20,22 @@ RSpec.describe JiraConnect::SyncProjectWorker, factory_default: :keep do let(:jira_connect_sync_service) { JiraConnect::SyncService.new(project) } let(:job_args) { [project.id, update_sequence_id] } let(:update_sequence_id) { 1 } + let(:request_path) { '/rest/devinfo/0.10/bulk' } + let(:request_body) do + { + repositories: [ + Atlassian::JiraConnect::Serializers::RepositoryEntity.represent( + project, + merge_requests: [mr_with_jira_description, mr_with_jira_title], + update_sequence_id: update_sequence_id + ) + ] + } + end + + def perform(project_id, update_sequence_id) + described_class.new.perform(project_id, update_sequence_id) + end before do stub_request(:post, 'https://sample.atlassian.net/rest/devinfo/0.10/bulk').to_return(status: 200, body: '', headers: {}) @@ -24,54 +46,37 @@ RSpec.describe JiraConnect::SyncProjectWorker, factory_default: :keep do context 'when the project is not found' do it 'does not raise an error' do - expect { described_class.new.perform('non_existing_record_id', update_sequence_id) }.not_to raise_error + expect { perform('non_existing_record_id', update_sequence_id) }.not_to raise_error end end it 'avoids N+1 database queries' do - control_count = ActiveRecord::QueryRecorder.new { described_class.new.perform(project.id, update_sequence_id) }.count + control_count = ActiveRecord::QueryRecorder.new { perform(project.id, update_sequence_id) }.count create(:merge_request, :unique_branches, title: 'TEST-123') - expect { described_class.new.perform(project.id, update_sequence_id) }.not_to exceed_query_limit(control_count) + expect { perform(project.id, update_sequence_id) }.not_to exceed_query_limit(control_count) end - it_behaves_like 'an idempotent worker' do - let(:request_path) { '/rest/devinfo/0.10/bulk' } - let(:request_body) do - { - repositories: [ - Atlassian::JiraConnect::Serializers::RepositoryEntity.represent( - project, - merge_requests: [mr_with_jira_description, mr_with_jira_title], - update_sequence_id: update_sequence_id - ) - ] - } - end - - it 'sends the request with custom update_sequence_id' do - allow_next_instances_of(Atlassian::JiraConnect::Client, IdempotentWorkerHelper::WORKER_EXEC_TIMES) do |client| - expect(client).to receive(:post).with(request_path, request_body) - end + it 'sends the request with custom update_sequence_id' do + allow_next(Atlassian::JiraConnect::Client).to receive(:post) + .with(request_path, request_body) - subject - end + perform(project.id, update_sequence_id) + end - context 'when the number of merge requests to sync is higher than the limit' do - let!(:most_recent_merge_request) { create(:merge_request, :unique_branches, description: 'TEST-323', title: 'TEST-123') } + context 'when the number of merge requests to sync is higher than the limit' do + let!(:most_recent_merge_request) { create(:merge_request, :unique_branches, description: 'TEST-323', title: 'TEST-123') } - before do - stub_const("#{described_class}::MERGE_REQUEST_LIMIT", 1) - end + before do + stub_const("#{described_class}::MERGE_REQUEST_LIMIT", 1) + end - it 'syncs only the most recent merge requests within the limit' do - expect(jira_connect_sync_service).to receive(:execute) - .exactly(IdempotentWorkerHelper::WORKER_EXEC_TIMES).times - .with(merge_requests: [most_recent_merge_request], update_sequence_id: update_sequence_id) + it 'syncs only the most recent merge requests within the limit' do + expect(jira_connect_sync_service).to receive(:execute) + .with(merge_requests: [most_recent_merge_request], update_sequence_id: update_sequence_id) - subject - end + perform(project.id, update_sequence_id) end end end |