diff options
Diffstat (limited to 'spec/services/issues')
-rw-r--r-- | spec/services/issues/close_service_spec.rb | 21 | ||||
-rw-r--r-- | spec/services/issues/create_service_spec.rb | 61 | ||||
-rw-r--r-- | spec/services/issues/export_csv_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/issues/move_service_spec.rb | 48 | ||||
-rw-r--r-- | spec/services/issues/relative_position_rebalancing_service_spec.rb | 12 | ||||
-rw-r--r-- | spec/services/issues/reopen_service_spec.rb | 20 | ||||
-rw-r--r-- | spec/services/issues/update_service_spec.rb | 33 |
7 files changed, 161 insertions, 36 deletions
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb index e88fe1b42f0..ef92b6984d5 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -397,9 +397,26 @@ RSpec.describe Issues::CloseService do end context 'when issue is not confidential' do + let(:expected_payload) do + include( + event_type: 'issue', + object_kind: 'issue', + changes: { + closed_at: { current: kind_of(Time), previous: nil }, + state_id: { current: 2, previous: 1 }, + updated_at: { current: kind_of(Time), previous: kind_of(Time) } + }, + object_attributes: include( + closed_at: kind_of(Time), + state: 'closed', + action: 'close' + ) + ) + end + it 'executes issue hooks' do - expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks) - expect(project).to receive(:execute_integrations).with(an_instance_of(Hash), :issue_hooks) + expect(project).to receive(:execute_hooks).with(expected_payload, :issue_hooks) + expect(project).to receive(:execute_integrations).with(expected_payload, :issue_hooks) described_class.new(project: project, current_user: user).close_issue(issue) end diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb index 5fe4c693451..5ddf91e167e 100644 --- a/spec/services/issues/create_service_spec.rb +++ b/spec/services/issues/create_service_spec.rb @@ -391,22 +391,61 @@ RSpec.describe Issues::CreateService do end end - it 'executes issue hooks when issue is not confidential' do - opts = { title: 'Title', description: 'Description', confidential: false } + describe 'executing hooks' do + let(:opts) { { title: 'Title', description: 'Description' } } + let(:expected_payload) do + include( + event_type: 'issue', + object_kind: 'issue', + changes: { + author_id: { current: user.id, previous: nil }, + created_at: { current: kind_of(Time), previous: nil }, + description: { current: opts[:description], previous: nil }, + id: { current: kind_of(Integer), previous: nil }, + iid: { current: kind_of(Integer), previous: nil }, + project_id: { current: project.id, previous: nil }, + title: { current: opts[:title], previous: nil }, + updated_at: { current: kind_of(Time), previous: nil } + }, + object_attributes: include( + opts.merge( + author_id: user.id, + project_id: project.id + ) + ) + ) + end + + it 'executes issue hooks' do + expect(project).to receive(:execute_hooks).with(expected_payload, :issue_hooks) + expect(project).to receive(:execute_integrations).with(expected_payload, :issue_hooks) - expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks) - expect(project).to receive(:execute_integrations).with(an_instance_of(Hash), :issue_hooks) + described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + end - described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute - end + context 'when issue is confidential' do + let(:expected_payload) do + include( + event_type: 'confidential_issue', + object_kind: 'issue', + changes: include( + confidential: { current: true, previous: false } + ), + object_attributes: include(confidential: true) + ) + end - it 'executes confidential issue hooks when issue is confidential' do - opts = { title: 'Title', description: 'Description', confidential: true } + before do + opts[:confidential] = true + end - expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :confidential_issue_hooks) - expect(project).to receive(:execute_integrations).with(an_instance_of(Hash), :confidential_issue_hooks) + it 'executes confidential issue hooks' do + expect(project).to receive(:execute_hooks).with(expected_payload, :confidential_issue_hooks) + expect(project).to receive(:execute_integrations).with(expected_payload, :confidential_issue_hooks) - described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + end + end end context 'after_save callback to store_mentions' do diff --git a/spec/services/issues/export_csv_service_spec.rb b/spec/services/issues/export_csv_service_spec.rb index d04480bec18..66d017464bf 100644 --- a/spec/services/issues/export_csv_service_spec.rb +++ b/spec/services/issues/export_csv_service_spec.rb @@ -185,7 +185,7 @@ RSpec.describe Issues::ExportCsvService do labeled_rows = csv.select { |entry| labeled_issues.map(&:iid).include?(entry['Issue ID'].to_i) } expect(labeled_rows.count).to eq(2) - expect(labeled_rows.map { |entry| entry['Labels'] }).to all( eq("Feature,Idea") ) + expect(labeled_rows.map { |entry| entry['Labels'] }).to all(eq("Feature,Idea")) end end end diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb index 23180f75eb3..655c5085fdc 100644 --- a/spec/services/issues/move_service_spec.rb +++ b/spec/services/issues/move_service_spec.rb @@ -228,18 +228,48 @@ RSpec.describe Issues::MoveService do end context 'project issue hooks' do - let!(:hook) { create(:project_hook, project: old_project, issues_events: true) } + let_it_be(:old_project_hook) { create(:project_hook, project: old_project, issues_events: true) } + let_it_be(:new_project_hook) { create(:project_hook, project: new_project, issues_events: true) } + + let(:expected_new_project_hook_payload) do + hash_including( + event_type: 'issue', + object_kind: 'issue', + object_attributes: include( + project_id: new_project.id, + state: 'opened', + action: 'open' + ) + ) + end + + let(:expected_old_project_hook_payload) do + hash_including( + event_type: 'issue', + object_kind: 'issue', + changes: { + state_id: { current: 2, previous: 1 }, + closed_at: { current: kind_of(Time), previous: nil }, + updated_at: { current: kind_of(Time), previous: kind_of(Time) } + }, + object_attributes: include( + id: old_issue.id, + closed_at: kind_of(Time), + state: 'closed', + action: 'close' + ) + ) + end - it 'executes project issue hooks' do - allow_next_instance_of(WebHookService) do |instance| - allow(instance).to receive(:execute) + it 'executes project issue hooks for both projects' do + expect_next_instance_of(WebHookService, new_project_hook, expected_new_project_hook_payload, 'issue_hooks') do |service| + expect(service).to receive(:async_execute).once + end + expect_next_instance_of(WebHookService, old_project_hook, expected_old_project_hook_payload, 'issue_hooks') do |service| + expect(service).to receive(:async_execute).once end - # Ideally, we'd test that `WebHookWorker.jobs.size` increased by 1, - # but since the entire spec run takes place in a transaction, we never - # actually get to the `after_commit` hook that queues these jobs. - expect { move_service.execute(old_issue, new_project) } - .not_to raise_error # Sidekiq::Worker::EnqueueFromTransactionError + move_service.execute(old_issue, new_project) end end diff --git a/spec/services/issues/relative_position_rebalancing_service_spec.rb b/spec/services/issues/relative_position_rebalancing_service_spec.rb index 37a94e1d6a2..27c0394ac8b 100644 --- a/spec/services/issues/relative_position_rebalancing_service_spec.rb +++ b/spec/services/issues/relative_position_rebalancing_service_spec.rb @@ -34,10 +34,6 @@ RSpec.describe Issues::RelativePositionRebalancingService, :clean_gitlab_redis_s end end - before do - stub_feature_flags(issue_rebalancing_with_retry: false) - end - def issues_in_position_order project.reload.issues.order_by_relative_position.to_a end @@ -97,8 +93,12 @@ RSpec.describe Issues::RelativePositionRebalancingService, :clean_gitlab_redis_s it 'resumes a started rebalance even if there are already too many rebalances running' do Gitlab::Redis::SharedState.with do |redis| - redis.sadd("gitlab:issues-position-rebalances:running_rebalances", "#{::Gitlab::Issues::Rebalancing::State::PROJECT}/#{project.id}") - redis.sadd("gitlab:issues-position-rebalances:running_rebalances", "1/100") + redis.sadd("gitlab:issues-position-rebalances:running_rebalances", + [ + "#{::Gitlab::Issues::Rebalancing::State::PROJECT}/#{project.id}", + "1/100" + ] + ) end caching = service.send(:caching) diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb index 477b44f4c2c..6013826f9b1 100644 --- a/spec/services/issues/reopen_service_spec.rb +++ b/spec/services/issues/reopen_service_spec.rb @@ -85,9 +85,25 @@ RSpec.describe Issues::ReopenService do end context 'when issue is not confidential' do + let(:expected_payload) do + include( + event_type: 'issue', + object_kind: 'issue', + changes: { + closed_at: { current: nil, previous: kind_of(Time) }, + state_id: { current: 1, previous: 2 }, + updated_at: { current: kind_of(Time), previous: kind_of(Time) } + }, + object_attributes: include( + state: 'opened', + action: 'reopen' + ) + ) + end + it 'executes issue hooks' do - expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks) - expect(project).to receive(:execute_integrations).with(an_instance_of(Hash), :issue_hooks) + expect(project).to receive(:execute_hooks).with(expected_payload, :issue_hooks) + expect(project).to receive(:execute_integrations).with(expected_payload, :issue_hooks) execute end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 20b1a1f58bb..f1ee62fd589 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -104,10 +104,33 @@ RSpec.describe Issues::UpdateService, :mailer do expect(issue.issue_customer_relations_contacts.last.contact).to eq contact end - it 'updates issue milestone when passing `milestone` param' do - update_issue(milestone: milestone) + context 'when updating milestone' do + before do + update_issue({ milestone: nil }) + end - expect(issue.milestone).to eq milestone + it 'updates issue milestone when passing `milestone` param' do + expect { update_issue({ milestone: milestone }) } + .to change(issue, :milestone).to(milestone).from(nil) + end + + it "triggers 'issuableMilestoneUpdated'" do + expect(GraphqlTriggers).to receive(:issuable_milestone_updated).with(issue).and_call_original + + update_issue({ milestone: milestone }) + end + + context 'when milestone remains unchanged' do + before do + update_issue({ title: 'abc', milestone: milestone }) + end + + it "does not trigger 'issuableMilestoneUpdated'" do + expect(GraphqlTriggers).not_to receive(:issuable_milestone_updated) + + update_issue({ milestone: milestone }) + end + end end context 'when sentry identifier is given' do @@ -520,7 +543,7 @@ RSpec.describe Issues::UpdateService, :mailer do end end - context 'when decription is not changed' do + context 'when description is not changed' do it 'does not trigger GraphQL description updated subscription' do expect(GraphqlTriggers).not_to receive(:issuable_description_updated) @@ -1379,7 +1402,7 @@ RSpec.describe Issues::UpdateService, :mailer do end end - include_examples 'issuable update service' do + it_behaves_like 'issuable update service' do let(:open_issuable) { issue } let(:closed_issuable) { create(:closed_issue, project: project) } end |