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
diff options
context:
space:
mode:
Diffstat (limited to 'spec/services/issues')
-rw-r--r--spec/services/issues/after_create_service_spec.rb2
-rw-r--r--spec/services/issues/build_service_spec.rb14
-rw-r--r--spec/services/issues/clone_service_spec.rb2
-rw-r--r--spec/services/issues/close_service_spec.rb117
-rw-r--r--spec/services/issues/create_service_spec.rb60
-rw-r--r--spec/services/issues/duplicate_service_spec.rb2
-rw-r--r--spec/services/issues/move_service_spec.rb2
-rw-r--r--spec/services/issues/referenced_merge_requests_service_spec.rb4
-rw-r--r--spec/services/issues/related_branches_service_spec.rb4
-rw-r--r--spec/services/issues/reopen_service_spec.rb14
-rw-r--r--spec/services/issues/reorder_service_spec.rb4
-rw-r--r--spec/services/issues/resolve_discussions_spec.rb38
-rw-r--r--spec/services/issues/update_service_spec.rb70
-rw-r--r--spec/services/issues/zoom_link_service_spec.rb2
14 files changed, 216 insertions, 119 deletions
diff --git a/spec/services/issues/after_create_service_spec.rb b/spec/services/issues/after_create_service_spec.rb
index bc9be3211d3..6b720d6e687 100644
--- a/spec/services/issues/after_create_service_spec.rb
+++ b/spec/services/issues/after_create_service_spec.rb
@@ -11,7 +11,7 @@ RSpec.describe Issues::AfterCreateService do
let_it_be(:milestone) { create(:milestone, project: project) }
let_it_be(:issue) { create(:issue, project: project, author: current_user, milestone: milestone, assignee_ids: [assignee.id]) }
- subject(:after_create_service) { described_class.new(project, current_user) }
+ subject(:after_create_service) { described_class.new(project: project, current_user: current_user) }
describe '#execute' do
it 'creates a pending todo for new assignee' do
diff --git a/spec/services/issues/build_service_spec.rb b/spec/services/issues/build_service_spec.rb
index 80fe2474ecd..3f506ec58b0 100644
--- a/spec/services/issues/build_service_spec.rb
+++ b/spec/services/issues/build_service_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper.rb'
+require 'spec_helper'
RSpec.describe Issues::BuildService do
let_it_be(:project) { create(:project, :repository) }
@@ -15,7 +15,7 @@ RSpec.describe Issues::BuildService do
end
def build_issue(issue_params = {})
- described_class.new(project, user, issue_params).execute
+ described_class.new(project: project, current_user: user, params: issue_params).execute
end
context 'for a single discussion' do
@@ -41,7 +41,7 @@ RSpec.describe Issues::BuildService do
describe '#items_for_discussions' do
it 'has an item for each discussion' do
create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.source_project, line_number: 13)
- service = described_class.new(project, user, merge_request_to_resolve_discussions_of: merge_request.iid)
+ service = described_class.new(project: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid })
service.execute
@@ -50,7 +50,7 @@ RSpec.describe Issues::BuildService do
end
describe '#item_for_discussion' do
- let(:service) { described_class.new(project, user, merge_request_to_resolve_discussions_of: merge_request.iid) }
+ let(:service) { described_class.new(project: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid }) }
it 'mentions the author of the note' do
discussion = create(:diff_note_on_merge_request, author: create(:user, username: 'author')).to_discussion
@@ -184,9 +184,9 @@ RSpec.describe Issues::BuildService do
end
it 'cannot set invalid type' do
- expect do
- build_issue(issue_type: 'invalid type')
- end.to raise_error(ArgumentError, "'invalid type' is not a valid issue_type")
+ issue = build_issue(issue_type: 'invalid type')
+
+ expect(issue).to be_issue
end
end
end
diff --git a/spec/services/issues/clone_service_spec.rb b/spec/services/issues/clone_service_spec.rb
index 44180a322ca..abbcb1c1d48 100644
--- a/spec/services/issues/clone_service_spec.rb
+++ b/spec/services/issues/clone_service_spec.rb
@@ -22,7 +22,7 @@ RSpec.describe Issues::CloneService do
let(:with_notes) { false }
subject(:clone_service) do
- described_class.new(old_project, user)
+ described_class.new(project: old_project, current_user: user)
end
shared_context 'user can clone issue' do
diff --git a/spec/services/issues/close_service_spec.rb b/spec/services/issues/close_service_spec.rb
index 3cf45143594..8950bdd465f 100644
--- a/spec/services/issues/close_service_spec.rb
+++ b/spec/services/issues/close_service_spec.rb
@@ -3,24 +3,52 @@
require 'spec_helper'
RSpec.describe Issues::CloseService do
- let(:project) { create(:project, :repository) }
- let(:user) { create(:user, email: "user@example.com") }
- let(:user2) { create(:user, email: "user2@example.com") }
- let(:guest) { create(:user) }
- let(:issue) { create(:issue, title: "My issue", project: project, assignees: [user2], author: create(:user)) }
+ subject(:close_issue) { described_class.new(project: project, current_user: user).close_issue(issue) }
+
+ let_it_be(:project, refind: true) { create(:project, :repository) }
+ let_it_be(:label1) { create(:label, project: project) }
+ let_it_be(:label2) { create(:label, project: project, remove_on_close: true) }
+ let_it_be(:author) { create(:user) }
+ let_it_be(:user) { create(:user, email: "user@example.com") }
+ let_it_be(:user2) { create(:user, email: "user2@example.com") }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:closing_merge_request) { create(:merge_request, source_project: project) }
+
let(:external_issue) { ExternalIssue.new('JIRA-123', project) }
- let(:closing_merge_request) { create(:merge_request, source_project: project) }
- let(:closing_commit) { create(:commit, project: project) }
- let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
+ let!(:issue) { create(:issue, title: "My issue", project: project, assignees: [user2], author: author) }
- before do
+ before_all do
project.add_maintainer(user)
project.add_developer(user2)
project.add_guest(guest)
end
+ shared_examples 'removes labels marked for removal from issue when closed' do
+ before do
+ issue.update!(label_ids: [label1.id, label2.id])
+ end
+
+ it 'removes labels marked for removal' do
+ expect do
+ close_issue
+ end.to change { issue.reload.label_ids }.from(containing_exactly(label1.id, label2.id)).to(containing_exactly(label1.id))
+ end
+
+ it 'creates system notes for the removed labels' do
+ expect do
+ close_issue
+ end.to change(ResourceLabelEvent, :count).by(1)
+
+ expect(ResourceLabelEvent.last.slice(:action, :issue_id, :label_id)).to eq(
+ 'action' => 'remove',
+ 'issue_id' => issue.id,
+ 'label_id' => label2.id
+ )
+ end
+ end
+
describe '#execute' do
- let(:service) { described_class.new(project, user) }
+ let(:service) { described_class.new(project: project, current_user: user) }
it 'checks if the user is authorized to update the issue' do
expect(service).to receive(:can?).with(user, :update_issue, issue)
@@ -87,18 +115,18 @@ RSpec.describe Issues::CloseService do
project.reload
expect(project.external_issue_tracker).to receive(:close_issue)
- described_class.new(project, user).close_issue(external_issue)
+ described_class.new(project: project, current_user: user).close_issue(external_issue)
end
end
- context 'with innactive external issue tracker supporting close_issue' do
+ context 'with inactive external issue tracker supporting close_issue' do
let!(:external_issue_tracker) { create(:jira_service, project: project, active: false) }
it 'does not close the issue on the external issue tracker' do
project.reload
expect(project.external_issue_tracker).not_to receive(:close_issue)
- described_class.new(project, user).close_issue(external_issue)
+ described_class.new(project: project, current_user: user).close_issue(external_issue)
end
end
@@ -109,7 +137,7 @@ RSpec.describe Issues::CloseService do
project.reload
expect(project.external_issue_tracker).not_to receive(:close_issue)
- described_class.new(project, user).close_issue(external_issue)
+ described_class.new(project: project, current_user: user).close_issue(external_issue)
end
end
end
@@ -117,10 +145,12 @@ RSpec.describe Issues::CloseService do
context "closed by a merge request", :sidekiq_might_not_need_inline do
subject(:close_issue) do
perform_enqueued_jobs do
- described_class.new(project, user).close_issue(issue, closed_via: closing_merge_request)
+ described_class.new(project: project, current_user: user).close_issue(issue, closed_via: closing_merge_request)
end
end
+ it_behaves_like 'removes labels marked for removal from issue when closed'
+
it 'mentions closure via a merge request' do
close_issue
@@ -184,10 +214,18 @@ RSpec.describe Issues::CloseService do
end
context "closed by a commit", :sidekiq_might_not_need_inline do
- it 'mentions closure via a commit' do
+ subject(:close_issue) do
perform_enqueued_jobs do
- described_class.new(project, user).close_issue(issue, closed_via: closing_commit)
+ described_class.new(project: project, current_user: user).close_issue(issue, closed_via: closing_commit)
end
+ end
+
+ let(:closing_commit) { create(:commit, project: project) }
+
+ it_behaves_like 'removes labels marked for removal from issue when closed'
+
+ it 'mentions closure via a commit' do
+ close_issue
email = ActionMailer::Base.deliveries.last
@@ -199,9 +237,8 @@ RSpec.describe Issues::CloseService do
context 'when user cannot read the commit' do
it 'does not mention the commit id' do
project.project_feature.update_attribute(:repository_access_level, ProjectFeature::DISABLED)
- perform_enqueued_jobs do
- described_class.new(project, user).close_issue(issue, closed_via: closing_commit)
- end
+
+ close_issue
email = ActionMailer::Base.deliveries.last
body_text = email.body.parts.map(&:body).join(" ")
@@ -216,10 +253,20 @@ RSpec.describe Issues::CloseService do
context "valid params" do
subject(:close_issue) do
perform_enqueued_jobs do
- described_class.new(project, user).close_issue(issue)
+ described_class.new(project: project, current_user: user).close_issue(issue)
end
end
+ it 'verifies the number of queries' do
+ recorded = ActiveRecord::QueryRecorder.new { close_issue }
+ expected_queries = 32
+
+ expect(recorded.count).to be <= expected_queries
+ expect(recorded.cached_count).to eq(0)
+ end
+
+ it_behaves_like 'removes labels marked for removal from issue when closed'
+
it 'closes the issue' do
close_issue
@@ -230,7 +277,7 @@ RSpec.describe Issues::CloseService do
it 'records closed user' do
close_issue
- expect(issue.closed_by_id).to be(user.id)
+ expect(issue.reload.closed_by_id).to be(user.id)
end
it 'sends email to user2 about assign of new issue', :sidekiq_might_not_need_inline do
@@ -249,11 +296,23 @@ RSpec.describe Issues::CloseService do
end
it 'marks todos as done' do
+ todo = create(:todo, :assigned, user: user, project: project, target: issue, author: user2)
+
close_issue
expect(todo.reload).to be_done
end
+ context 'when closing the issue fails' do
+ it 'does not assign a closed_by value for the issue' do
+ allow(issue).to receive(:close).and_return(false)
+
+ close_issue
+
+ expect(issue.closed_by_id).to be_nil
+ end
+ end
+
context 'when there is an associated Alert Management Alert' do
context 'when alert can be resolved' do
let!(:alert) { create(:alert_management_alert, issue: issue, project: project) }
@@ -303,26 +362,32 @@ RSpec.describe Issues::CloseService do
end
context 'when issue is not confidential' do
+ it_behaves_like 'removes labels marked for removal from issue when closed'
+
it 'executes issue hooks' do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :issue_hooks)
- described_class.new(project, user).close_issue(issue)
+ close_issue
end
end
context 'when issue is confidential' do
- it 'executes confidential issue hooks' do
- issue = create(:issue, :confidential, project: project)
+ let(:issue) { create(:issue, :confidential, project: project) }
+
+ it_behaves_like 'removes labels marked for removal from issue when closed'
+ it 'executes confidential issue hooks' do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :confidential_issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :confidential_issue_hooks)
- described_class.new(project, user).close_issue(issue)
+ close_issue
end
end
context 'internal issues disabled' do
+ let!(:todo) { create(:todo, :assigned, user: user, project: project, target: issue, author: user2) }
+
before do
project.issues_enabled = false
project.save!
diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb
index 83c6373c335..9c84242d8ae 100644
--- a/spec/services/issues/create_service_spec.rb
+++ b/spec/services/issues/create_service_spec.rb
@@ -12,7 +12,7 @@ RSpec.describe Issues::CreateService do
let_it_be(:assignee) { create(:user) }
let_it_be(:milestone) { create(:milestone, project: project) }
- let(:issue) { described_class.new(project, user, opts).execute }
+ let(:issue) { described_class.new(project: project, current_user: user, params: opts).execute }
context 'when params are valid' do
let_it_be(:labels) { create_pair(:label, project: project) }
@@ -44,7 +44,7 @@ RSpec.describe Issues::CreateService do
end
context 'when skip_system_notes is true' do
- let(:issue) { described_class.new(project, user, opts).execute(skip_system_notes: true) }
+ let(:issue) { described_class.new(project: project, current_user: user, params: opts).execute(skip_system_notes: true) }
it 'does not call Issuable::CommonSystemNotesService' do
expect(Issuable::CommonSystemNotesService).not_to receive(:new)
@@ -96,7 +96,7 @@ RSpec.describe Issues::CreateService do
end
it 'filters out params that cannot be set without the :admin_issue permission' do
- issue = described_class.new(project, guest, opts).execute
+ issue = described_class.new(project: project, current_user: guest, params: opts).execute
expect(issue).to be_persisted
expect(issue.title).to eq('Awesome issue')
@@ -108,7 +108,7 @@ RSpec.describe Issues::CreateService do
end
it 'creates confidential issues' do
- issue = described_class.new(project, guest, confidential: true).execute
+ issue = described_class.new(project: project, current_user: guest, params: { confidential: true }).execute
expect(issue.confidential).to be_truthy
end
@@ -117,7 +117,7 @@ RSpec.describe Issues::CreateService do
it 'moves the issue to the end, in an asynchronous worker' do
expect(IssuePlacementWorker).to receive(:perform_async).with(be_nil, Integer)
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
end
context 'when label belongs to project group' do
@@ -204,7 +204,7 @@ RSpec.describe Issues::CreateService do
it 'invalidates open issues counter for assignees when issue is assigned' do
project.add_maintainer(assignee)
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
expect(assignee.assigned_open_issues_count).to eq 1
end
@@ -230,7 +230,7 @@ RSpec.describe Issues::CreateService do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :issue_hooks)
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
end
it 'executes confidential issue hooks when issue is confidential' do
@@ -239,7 +239,7 @@ RSpec.describe Issues::CreateService do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :confidential_issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :confidential_issue_hooks)
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
end
context 'after_save callback to store_mentions' do
@@ -283,7 +283,7 @@ RSpec.describe Issues::CreateService do
it 'removes assignee when user id is invalid' do
opts = { title: 'Title', description: 'Description', assignee_ids: [-1] }
- issue = described_class.new(project, user, opts).execute
+ issue = described_class.new(project: project, current_user: user, params: opts).execute
expect(issue.assignees).to be_empty
end
@@ -291,7 +291,7 @@ RSpec.describe Issues::CreateService do
it 'removes assignee when user id is 0' do
opts = { title: 'Title', description: 'Description', assignee_ids: [0] }
- issue = described_class.new(project, user, opts).execute
+ issue = described_class.new(project: project, current_user: user, params: opts).execute
expect(issue.assignees).to be_empty
end
@@ -300,7 +300,7 @@ RSpec.describe Issues::CreateService do
project.add_maintainer(assignee)
opts = { title: 'Title', description: 'Description', assignee_ids: [assignee.id] }
- issue = described_class.new(project, user, opts).execute
+ issue = described_class.new(project: project, current_user: user, params: opts).execute
expect(issue.assignees).to eq([assignee])
end
@@ -318,7 +318,7 @@ RSpec.describe Issues::CreateService do
project.update!(visibility_level: level)
opts = { title: 'Title', description: 'Description', assignee_ids: [assignee.id] }
- issue = described_class.new(project, user, opts).execute
+ issue = described_class.new(project: project, current_user: user, params: opts).execute
expect(issue.assignees).to be_empty
end
@@ -328,7 +328,7 @@ RSpec.describe Issues::CreateService do
end
it_behaves_like 'issuable record that supports quick actions' do
- let(:issuable) { described_class.new(project, user, params).execute }
+ let(:issuable) { described_class.new(project: project, current_user: user, params: params).execute }
end
context 'Quick actions' do
@@ -368,14 +368,14 @@ RSpec.describe Issues::CreateService do
let(:opts) { { discussion_to_resolve: discussion.id, merge_request_to_resolve_discussions_of: merge_request.iid } }
it 'resolves the discussion' do
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
discussion.first_note.reload
expect(discussion.resolved?).to be(true)
end
it 'added a system note to the discussion' do
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
reloaded_discussion = MergeRequest.find(merge_request.id).discussions.first
@@ -383,17 +383,19 @@ RSpec.describe Issues::CreateService do
end
it 'assigns the title and description for the issue' do
- issue = described_class.new(project, user, opts).execute
+ issue = described_class.new(project: project, current_user: user, params: opts).execute
expect(issue.title).not_to be_nil
expect(issue.description).not_to be_nil
end
it 'can set nil explicitly to the title and description' do
- issue = described_class.new(project, user,
- merge_request_to_resolve_discussions_of: merge_request,
- description: nil,
- title: nil).execute
+ issue = described_class.new(project: project, current_user: user,
+ params: {
+ merge_request_to_resolve_discussions_of: merge_request,
+ description: nil,
+ title: nil
+ }).execute
expect(issue.description).to be_nil
expect(issue.title).to be_nil
@@ -404,14 +406,14 @@ RSpec.describe Issues::CreateService do
let(:opts) { { merge_request_to_resolve_discussions_of: merge_request.iid } }
it 'resolves the discussion' do
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
discussion.first_note.reload
expect(discussion.resolved?).to be(true)
end
it 'added a system note to the discussion' do
- described_class.new(project, user, opts).execute
+ described_class.new(project: project, current_user: user, params: opts).execute
reloaded_discussion = MergeRequest.find(merge_request.id).discussions.first
@@ -419,17 +421,19 @@ RSpec.describe Issues::CreateService do
end
it 'assigns the title and description for the issue' do
- issue = described_class.new(project, user, opts).execute
+ issue = described_class.new(project: project, current_user: user, params: opts).execute
expect(issue.title).not_to be_nil
expect(issue.description).not_to be_nil
end
it 'can set nil explicitly to the title and description' do
- issue = described_class.new(project, user,
- merge_request_to_resolve_discussions_of: merge_request,
- description: nil,
- title: nil).execute
+ issue = described_class.new(project: project, current_user: user,
+ params: {
+ merge_request_to_resolve_discussions_of: merge_request,
+ description: nil,
+ title: nil
+ }).execute
expect(issue.description).to be_nil
expect(issue.title).to be_nil
@@ -454,7 +458,7 @@ RSpec.describe Issues::CreateService do
end
subject do
- described_class.new(project, user, params)
+ described_class.new(project: project, current_user: user, params: params)
end
before do
diff --git a/spec/services/issues/duplicate_service_spec.rb b/spec/services/issues/duplicate_service_spec.rb
index 0b5bc3f32ef..0eb0bbb1480 100644
--- a/spec/services/issues/duplicate_service_spec.rb
+++ b/spec/services/issues/duplicate_service_spec.rb
@@ -10,7 +10,7 @@ RSpec.describe Issues::DuplicateService do
let(:canonical_issue) { create(:issue, project: canonical_project) }
let(:duplicate_issue) { create(:issue, project: duplicate_project) }
- subject { described_class.new(duplicate_project, user, {}) }
+ subject { described_class.new(project: duplicate_project, current_user: user) }
describe '#execute' do
context 'when the issues passed are the same' do
diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb
index 2f29a2e2022..76588860957 100644
--- a/spec/services/issues/move_service_spec.rb
+++ b/spec/services/issues/move_service_spec.rb
@@ -20,7 +20,7 @@ RSpec.describe Issues::MoveService do
end
subject(:move_service) do
- described_class.new(old_project, user)
+ described_class.new(project: old_project, current_user: user)
end
shared_context 'user can move issue' do
diff --git a/spec/services/issues/referenced_merge_requests_service_spec.rb b/spec/services/issues/referenced_merge_requests_service_spec.rb
index bf7a4c97e48..dc55ba8ebea 100644
--- a/spec/services/issues/referenced_merge_requests_service_spec.rb
+++ b/spec/services/issues/referenced_merge_requests_service_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper.rb'
+require 'spec_helper'
RSpec.describe Issues::ReferencedMergeRequestsService do
def create_referencing_mr(attributes = {})
@@ -26,7 +26,7 @@ RSpec.describe Issues::ReferencedMergeRequestsService do
let_it_be(:referencing_mr) { create_referencing_mr(source_project: project, source_branch: 'csv') }
let_it_be(:referencing_mr_other_project) { create_referencing_mr(source_project: other_project, source_branch: 'csv') }
- let(:service) { described_class.new(project, user) }
+ let(:service) { described_class.new(project: project, current_user: user) }
describe '#execute' do
it 'returns a list of sorted merge requests' do
diff --git a/spec/services/issues/related_branches_service_spec.rb b/spec/services/issues/related_branches_service_spec.rb
index c9c029bca4f..7a4bae7f852 100644
--- a/spec/services/issues/related_branches_service_spec.rb
+++ b/spec/services/issues/related_branches_service_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Issues::RelatedBranchesService do
let(:user) { developer }
- subject { described_class.new(issue.project, user) }
+ subject { described_class.new(project: issue.project, current_user: user) }
before do
issue.project.add_developer(developer)
@@ -95,7 +95,7 @@ RSpec.describe Issues::RelatedBranchesService do
merge_request.create_cross_references!(user)
referenced_merge_requests = Issues::ReferencedMergeRequestsService
- .new(issue.project, user)
+ .new(project: issue.project, current_user: user)
.referenced_merge_requests(issue)
expect(referenced_merge_requests).not_to be_empty
diff --git a/spec/services/issues/reopen_service_spec.rb b/spec/services/issues/reopen_service_spec.rb
index ffe74cca9cf..746a9105531 100644
--- a/spec/services/issues/reopen_service_spec.rb
+++ b/spec/services/issues/reopen_service_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Issues::ReopenService do
project.add_guest(guest)
perform_enqueued_jobs do
- described_class.new(project, guest).execute(issue)
+ described_class.new(project: project, current_user: guest).execute(issue)
end
end
@@ -33,11 +33,11 @@ RSpec.describe Issues::ReopenService do
issue.assignees << user
expect_any_instance_of(User).to receive(:invalidate_issue_cache_counts)
- described_class.new(project, user).execute(issue)
+ described_class.new(project: project, current_user: user).execute(issue)
end
it 'refreshes the number of opened issues' do
- service = described_class.new(project, user)
+ service = described_class.new(project: project, current_user: user)
expect { service.execute(issue) }
.to change { project.open_issues_count }.from(0).to(1)
@@ -50,14 +50,14 @@ RSpec.describe Issues::ReopenService do
expect(service).to receive(:delete_cache).and_call_original
end
- described_class.new(project, user).execute(issue)
+ described_class.new(project: project, current_user: user).execute(issue)
end
context 'issue is incident type' do
let(:issue) { create(:incident, :closed, project: project) }
let(:current_user) { user }
- subject { described_class.new(project, user).execute(issue) }
+ subject { described_class.new(project: project, current_user: user).execute(issue) }
it_behaves_like 'an incident management tracked event', :incident_management_incident_reopened
end
@@ -67,7 +67,7 @@ RSpec.describe Issues::ReopenService do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :issue_hooks)
- described_class.new(project, user).execute(issue)
+ described_class.new(project: project, current_user: user).execute(issue)
end
end
@@ -78,7 +78,7 @@ RSpec.describe Issues::ReopenService do
expect(project).to receive(:execute_hooks).with(an_instance_of(Hash), :confidential_issue_hooks)
expect(project).to receive(:execute_services).with(an_instance_of(Hash), :confidential_issue_hooks)
- described_class.new(project, user).execute(issue)
+ described_class.new(project: project, current_user: user).execute(issue)
end
end
end
diff --git a/spec/services/issues/reorder_service_spec.rb b/spec/services/issues/reorder_service_spec.rb
index 78b937a1caf..15668a3aa23 100644
--- a/spec/services/issues/reorder_service_spec.rb
+++ b/spec/services/issues/reorder_service_spec.rb
@@ -75,7 +75,7 @@ RSpec.describe Issues::ReorderService do
match_params = { move_between_ids: [issue2.id, issue3.id], board_group_id: group.id }
expect(Issues::UpdateService)
- .to receive(:new).with(project, user, match_params)
+ .to receive(:new).with(project: project, current_user: user, params: match_params)
.and_return(double(execute: build(:issue)))
subject.execute(issue1)
@@ -95,6 +95,6 @@ RSpec.describe Issues::ReorderService do
end
def service(params)
- described_class.new(project, user, params)
+ described_class.new(project: project, current_user: user, params: params)
end
end
diff --git a/spec/services/issues/resolve_discussions_spec.rb b/spec/services/issues/resolve_discussions_spec.rb
index 9fbc9cbcca6..1ac71b966bc 100644
--- a/spec/services/issues/resolve_discussions_spec.rb
+++ b/spec/services/issues/resolve_discussions_spec.rb
@@ -1,6 +1,6 @@
# frozen_string_literal: true
-require 'spec_helper.rb'
+require 'spec_helper'
RSpec.describe Issues::ResolveDiscussions do
let(:project) { create(:project, :repository) }
@@ -11,7 +11,7 @@ RSpec.describe Issues::ResolveDiscussions do
DummyService.class_eval do
include ::Issues::ResolveDiscussions
- def initialize(*args)
+ def initialize(project:, current_user: nil, params: {})
super
filter_resolve_discussion_params
end
@@ -26,7 +26,7 @@ RSpec.describe Issues::ResolveDiscussions do
let(:other_merge_request) { create(:merge_request, source_project: project, source_branch: "fix") }
describe "#merge_request_for_resolving_discussion" do
- let(:service) { DummyService.new(project, user, merge_request_to_resolve_discussions_of: merge_request.iid) }
+ let(:service) { DummyService.new(project: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid }) }
it "finds the merge request" do
expect(service.merge_request_to_resolve_discussions_of).to eq(merge_request)
@@ -45,10 +45,12 @@ RSpec.describe Issues::ResolveDiscussions do
describe "#discussions_to_resolve" do
it "contains a single discussion when matching merge request and discussion are passed" do
service = DummyService.new(
- project,
- user,
- discussion_to_resolve: discussion.id,
- merge_request_to_resolve_discussions_of: merge_request.iid
+ project: project,
+ current_user: user,
+ params: {
+ discussion_to_resolve: discussion.id,
+ merge_request_to_resolve_discussions_of: merge_request.iid
+ }
)
# We need to compare discussion id's because the Discussion-objects are rebuilt
# which causes the object-id's not to be different.
@@ -63,9 +65,9 @@ RSpec.describe Issues::ResolveDiscussions do
project: merge_request.target_project,
line_number: 15)])
service = DummyService.new(
- project,
- user,
- merge_request_to_resolve_discussions_of: merge_request.iid
+ project: project,
+ current_user: user,
+ params: { merge_request_to_resolve_discussions_of: merge_request.iid }
)
# We need to compare discussion id's because the Discussion-objects are rebuilt
# which causes the object-id's not to be different.
@@ -81,9 +83,9 @@ RSpec.describe Issues::ResolveDiscussions do
line_number: 15
)])
service = DummyService.new(
- project,
- user,
- merge_request_to_resolve_discussions_of: merge_request.iid
+ project: project,
+ current_user: user,
+ params: { merge_request_to_resolve_discussions_of: merge_request.iid }
)
# We need to compare discussion id's because the Discussion-objects are rebuilt
# which causes the object-id's not to be different.
@@ -94,10 +96,12 @@ RSpec.describe Issues::ResolveDiscussions do
it "is empty when a discussion and another merge request are passed" do
service = DummyService.new(
- project,
- user,
- discussion_to_resolve: discussion.id,
- merge_request_to_resolve_discussions_of: other_merge_request.iid
+ project: project,
+ current_user: user,
+ params: {
+ discussion_to_resolve: discussion.id,
+ merge_request_to_resolve_discussions_of: other_merge_request.iid
+ }
)
expect(service.discussions_to_resolve).to be_empty
diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb
index fd42a84e405..8c97dd95ced 100644
--- a/spec/services/issues/update_service_spec.rb
+++ b/spec/services/issues/update_service_spec.rb
@@ -41,7 +41,7 @@ RSpec.describe Issues::UpdateService, :mailer do
end
def update_issue(opts)
- described_class.new(project, user, opts).execute(issue)
+ described_class.new(project: project, current_user: user, params: opts).execute(issue)
end
context 'valid params' do
@@ -165,20 +165,38 @@ RSpec.describe Issues::UpdateService, :mailer do
expect(user2.assigned_open_issues_count).to eq 1
end
- it 'sorts issues as specified by parameters' do
- issue1 = create(:issue, project: project, assignees: [user3])
- issue2 = create(:issue, project: project, assignees: [user3])
+ context 'when changing relative position' do
+ let(:issue1) { create(:issue, project: project, assignees: [user3]) }
+ let(:issue2) { create(:issue, project: project, assignees: [user3]) }
- [issue, issue1, issue2].each do |issue|
- issue.move_to_end
- issue.save!
+ before do
+ [issue, issue1, issue2].each do |issue|
+ issue.move_to_end
+ issue.save!
+ end
end
- opts[:move_between_ids] = [issue1.id, issue2.id]
+ it 'sorts issues as specified by parameters' do
+ opts[:move_between_ids] = [issue1.id, issue2.id]
- update_issue(opts)
+ update_issue(opts)
- expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
+ expect(issue.relative_position).to be_between(issue1.relative_position, issue2.relative_position)
+ end
+
+ context 'when block_issue_positioning flag is enabled' do
+ before do
+ stub_feature_flags(block_issue_repositioning: true)
+ end
+
+ it 'raises error' do
+ old_position = issue.relative_position
+ opts[:move_between_ids] = [issue1.id, issue2.id]
+
+ expect { update_issue(opts) }.to raise_error(::Gitlab::RelativePositioning::IssuePositioningDisabled)
+ expect(issue.reload.relative_position).to eq(old_position)
+ end
+ end
end
it 'does not rebalance even if needed if the flag is disabled' do
@@ -269,7 +287,7 @@ RSpec.describe Issues::UpdateService, :mailer do
opts[:move_between_ids] = [issue_1.id, issue_2.id]
opts[:board_group_id] = group.id
- described_class.new(issue_3.project, user, opts).execute(issue_3)
+ described_class.new(project: issue_3.project, current_user: user, params: opts).execute(issue_3)
expect(issue_2.relative_position).to be_between(issue_1.relative_position, issue_2.relative_position)
end
end
@@ -282,7 +300,12 @@ RSpec.describe Issues::UpdateService, :mailer do
end
it 'filters out params that cannot be set without the :admin_issue permission' do
- described_class.new(project, guest, opts.merge(confidential: true)).execute(issue)
+ described_class.new(
+ project: project, current_user: guest, params: opts.merge(
+ confidential: true,
+ issue_type: 'test_case'
+ )
+ ).execute(issue)
expect(issue).to be_valid
expect(issue.title).to eq 'New title'
@@ -293,6 +316,7 @@ RSpec.describe Issues::UpdateService, :mailer do
expect(issue.due_date).to be_nil
expect(issue.discussion_locked).to be_falsey
expect(issue.confidential).to be_falsey
+ expect(issue.issue_type).to eql('issue')
end
end
@@ -650,7 +674,7 @@ RSpec.describe Issues::UpdateService, :mailer do
opts = { label_ids: [label.id] }
perform_enqueued_jobs do
- @issue = described_class.new(project, user, opts).execute(issue)
+ @issue = described_class.new(project: project, current_user: user, params: opts).execute(issue)
end
should_email(subscriber)
@@ -666,7 +690,7 @@ RSpec.describe Issues::UpdateService, :mailer do
opts = { label_ids: [label.id, label2.id] }
perform_enqueued_jobs do
- @issue = described_class.new(project, user, opts).execute(issue)
+ @issue = described_class.new(project: project, current_user: user, params: opts).execute(issue)
end
should_not_email(subscriber)
@@ -677,7 +701,7 @@ RSpec.describe Issues::UpdateService, :mailer do
opts = { label_ids: [label2.id] }
perform_enqueued_jobs do
- @issue = described_class.new(project, user, opts).execute(issue)
+ @issue = described_class.new(project: project, current_user: user, params: opts).execute(issue)
end
should_not_email(subscriber)
@@ -709,7 +733,7 @@ RSpec.describe Issues::UpdateService, :mailer do
line_number: 1
}
}
- service = described_class.new(project, user, params)
+ service = described_class.new(project: project, current_user: user, params: params)
expect(Spam::SpamActionService).not_to receive(:new)
@@ -785,7 +809,7 @@ RSpec.describe Issues::UpdateService, :mailer do
context 'updating labels' do
let(:label3) { create(:label, project: project) }
- let(:result) { described_class.new(project, user, params).execute(issue).reload }
+ let(:result) { described_class.new(project: project, current_user: user, params: params).execute(issue).reload }
context 'when add_label_ids and label_ids are passed' do
let(:params) { { label_ids: [label.id], add_label_ids: [label3.id] } }
@@ -983,14 +1007,14 @@ RSpec.describe Issues::UpdateService, :mailer do
it 'raises an error for invalid move ids within a project' do
opts = { move_between_ids: [9000, non_existing_record_id] }
- expect { described_class.new(issue.project, user, opts).execute(issue) }
+ expect { described_class.new(project: issue.project, current_user: user, params: opts).execute(issue) }
.to raise_error(ActiveRecord::RecordNotFound)
end
it 'raises an error for invalid move ids within a group' do
opts = { move_between_ids: [9000, non_existing_record_id], board_group_id: create(:group).id }
- expect { described_class.new(issue.project, user, opts).execute(issue) }
+ expect { described_class.new(project: issue.project, current_user: user, params: opts).execute(issue) }
.to raise_error(ActiveRecord::RecordNotFound)
end
end
@@ -1014,13 +1038,13 @@ RSpec.describe Issues::UpdateService, :mailer do
with_them do
it 'broadcasts to the issues channel based on ActionCable and feature flag values' do
- expect(Gitlab::ActionCable::Config).to receive(:in_app?).and_return(action_cable_in_app_enabled)
+ allow(Gitlab::ActionCable::Config).to receive(:in_app?).and_return(action_cable_in_app_enabled)
stub_feature_flags(broadcast_issue_updates: feature_flag_enabled)
if should_broadcast
- expect(IssuesChannel).to receive(:broadcast_to).with(issue, event: 'updated')
+ expect(GraphqlTriggers).to receive(:issuable_assignees_updated).with(issue)
else
- expect(IssuesChannel).not_to receive(:broadcast_to)
+ expect(GraphqlTriggers).not_to receive(:issuable_assignees_updated).with(issue)
end
update_issue(update_params)
@@ -1030,7 +1054,7 @@ RSpec.describe Issues::UpdateService, :mailer do
it_behaves_like 'issuable record that supports quick actions' do
let(:existing_issue) { create(:issue, project: project) }
- let(:issuable) { described_class.new(project, user, params).execute(existing_issue) }
+ let(:issuable) { described_class.new(project: project, current_user: user, params: params).execute(existing_issue) }
end
end
end
diff --git a/spec/services/issues/zoom_link_service_spec.rb b/spec/services/issues/zoom_link_service_spec.rb
index 8e8adc516cf..19db892fcae 100644
--- a/spec/services/issues/zoom_link_service_spec.rb
+++ b/spec/services/issues/zoom_link_service_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe Issues::ZoomLinkService do
let_it_be(:issue) { create(:issue) }
let(:project) { issue.project }
- let(:service) { described_class.new(issue, user) }
+ let(:service) { described_class.new(project: project, current_user: user, params: { issue: issue }) }
let(:zoom_link) { 'https://zoom.us/j/123456789' }
before do