diff options
Diffstat (limited to 'spec/services/issues')
-rw-r--r-- | spec/services/issues/after_create_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/issues/build_service_spec.rb | 6 | ||||
-rw-r--r-- | spec/services/issues/clone_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/issues/close_service_spec.rb | 22 | ||||
-rw-r--r-- | spec/services/issues/create_service_spec.rb | 76 | ||||
-rw-r--r-- | spec/services/issues/duplicate_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/issues/export_csv_service_spec.rb | 214 | ||||
-rw-r--r-- | spec/services/issues/import_csv_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/issues/move_service_spec.rb | 4 | ||||
-rw-r--r-- | spec/services/issues/referenced_merge_requests_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/issues/related_branches_service_spec.rb | 4 | ||||
-rw-r--r-- | spec/services/issues/reopen_service_spec.rb | 6 | ||||
-rw-r--r-- | spec/services/issues/reorder_service_spec.rb | 2 | ||||
-rw-r--r-- | spec/services/issues/update_service_spec.rb | 68 | ||||
-rw-r--r-- | spec/services/issues/zoom_link_service_spec.rb | 2 |
15 files changed, 242 insertions, 172 deletions
diff --git a/spec/services/issues/after_create_service_spec.rb b/spec/services/issues/after_create_service_spec.rb index 6b720d6e687..39a6799dbad 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: project, current_user: current_user) } + subject(:after_create_service) { described_class.new(container: 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 838e0675372..2160c45d079 100644 --- a/spec/services/issues/build_service_spec.rb +++ b/spec/services/issues/build_service_spec.rb @@ -19,7 +19,7 @@ RSpec.describe Issues::BuildService do end def build_issue(issue_params = {}) - described_class.new(project: project, current_user: user, params: issue_params).execute + described_class.new(container: project, current_user: user, params: issue_params).execute end context 'for a single discussion' do @@ -45,7 +45,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: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid }) + service = described_class.new(container: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid }) service.execute @@ -54,7 +54,7 @@ RSpec.describe Issues::BuildService do end describe '#item_for_discussion' do - let(:service) { described_class.new(project: project, current_user: user, params: { merge_request_to_resolve_discussions_of: merge_request.iid }) } + let(:service) { described_class.new(container: 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 diff --git a/spec/services/issues/clone_service_spec.rb b/spec/services/issues/clone_service_spec.rb index 67f32b85350..eafaea93015 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(project: old_project, current_user: user) + described_class.new(container: 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 ef24d1e940e..803808e667c 100644 --- a/spec/services/issues/close_service_spec.rb +++ b/spec/services/issues/close_service_spec.rb @@ -20,13 +20,13 @@ RSpec.describe Issues::CloseService do end describe '#execute' do - let(:service) { described_class.new(project: project, current_user: user) } + let(:service) { described_class.new(container: project, current_user: user) } context 'when skip_authorization is true' do it 'does close the issue even if user is not authorized' do non_authorized_user = create(:user) - service = described_class.new(project: project, current_user: non_authorized_user) + service = described_class.new(container: project, current_user: non_authorized_user) expect do service.execute(issue, skip_authorization: true) @@ -167,7 +167,7 @@ RSpec.describe Issues::CloseService do project.reload expect(project.external_issue_tracker).to receive(:close_issue) - described_class.new(project: project, current_user: user).close_issue(external_issue) + described_class.new(container: project, current_user: user).close_issue(external_issue) end end @@ -178,7 +178,7 @@ RSpec.describe Issues::CloseService do project.reload expect(project.external_issue_tracker).not_to receive(:close_issue) - described_class.new(project: project, current_user: user).close_issue(external_issue) + described_class.new(container: project, current_user: user).close_issue(external_issue) end end @@ -189,7 +189,7 @@ RSpec.describe Issues::CloseService do project.reload expect(project.external_issue_tracker).not_to receive(:close_issue) - described_class.new(project: project, current_user: user).close_issue(external_issue) + described_class.new(container: project, current_user: user).close_issue(external_issue) end end end @@ -197,7 +197,7 @@ 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: project, current_user: user).close_issue(issue, closed_via: closing_merge_request) + described_class.new(container: project, current_user: user).close_issue(issue, closed_via: closing_merge_request) end end @@ -266,7 +266,7 @@ RSpec.describe Issues::CloseService do context "closed by a commit", :sidekiq_might_not_need_inline do it 'mentions closure via a commit' do perform_enqueued_jobs do - described_class.new(project: project, current_user: user).close_issue(issue, closed_via: closing_commit) + described_class.new(container: project, current_user: user).close_issue(issue, closed_via: closing_commit) end email = ActionMailer::Base.deliveries.last @@ -280,7 +280,7 @@ RSpec.describe Issues::CloseService 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: project, current_user: user).close_issue(issue, closed_via: closing_commit) + described_class.new(container: project, current_user: user).close_issue(issue, closed_via: closing_commit) end email = ActionMailer::Base.deliveries.last @@ -296,7 +296,7 @@ RSpec.describe Issues::CloseService do context "valid params" do subject(:close_issue) do perform_enqueued_jobs do - described_class.new(project: project, current_user: user).close_issue(issue) + described_class.new(container: project, current_user: user).close_issue(issue) end end @@ -438,7 +438,7 @@ RSpec.describe Issues::CloseService do 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) + described_class.new(container: project, current_user: user).close_issue(issue) end end @@ -449,7 +449,7 @@ RSpec.describe Issues::CloseService do 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) - described_class.new(project: project, current_user: user).close_issue(issue) + described_class.new(container: project, current_user: user).close_issue(issue) end end diff --git a/spec/services/issues/create_service_spec.rb b/spec/services/issues/create_service_spec.rb index 7ab2046b6be..ada5b300d7a 100644 --- a/spec/services/issues/create_service_spec.rb +++ b/spec/services/issues/create_service_spec.rb @@ -11,7 +11,7 @@ RSpec.describe Issues::CreateService do let(:opts) { { title: 'title' } } let(:spam_params) { double } - let(:service) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params) } + let(:service) { described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params) } it_behaves_like 'rate limited service' do let(:key) { :issues_create } @@ -147,7 +147,7 @@ RSpec.describe Issues::CreateService do end context 'when a build_service is provided' do - let(:result) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params, build_service: build_service).execute } + let(:result) { described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params, build_service: build_service).execute } let(:issue_from_builder) { WorkItem.new(project: project, title: 'Issue from builder') } let(:build_service) { double(:build_service, execute: issue_from_builder) } @@ -160,7 +160,7 @@ RSpec.describe Issues::CreateService do end context 'when skip_system_notes is true' do - let(:issue) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute(skip_system_notes: true) } + let(:issue) { described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute(skip_system_notes: true) } it 'does not call Issuable::CommonSystemNotesService' do expect(Issuable::CommonSystemNotesService).not_to receive(:new) @@ -256,7 +256,7 @@ RSpec.describe Issues::CreateService do let_it_be(:non_member) { create(:user) } it 'filters out params that cannot be set without the :set_issue_metadata permission' do - result = described_class.new(project: project, current_user: non_member, params: opts, spam_params: spam_params).execute + result = described_class.new(container: project, current_user: non_member, params: opts, spam_params: spam_params).execute issue = result[:issue] expect(result).to be_success @@ -270,7 +270,7 @@ RSpec.describe Issues::CreateService do end it 'can create confidential issues' do - result = described_class.new(project: project, current_user: non_member, params: opts.merge(confidential: true), spam_params: spam_params).execute + result = described_class.new(container: project, current_user: non_member, params: opts.merge(confidential: true), spam_params: spam_params).execute issue = result[:issue] expect(result).to be_success @@ -281,7 +281,7 @@ RSpec.describe Issues::CreateService do it 'moves the issue to the end, in an asynchronous worker' do expect(Issues::PlacementWorker).to receive(:perform_async).with(be_nil, Integer) - described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute end context 'when label belongs to project group' do @@ -368,7 +368,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: project, current_user: user, params: opts, spam_params: spam_params).execute + described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute expect(assignee.assigned_open_issues_count).to eq 1 end @@ -439,7 +439,7 @@ RSpec.describe Issues::CreateService do 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, params: opts, spam_params: spam_params).execute + described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute end context 'when issue is confidential' do @@ -462,7 +462,7 @@ RSpec.describe Issues::CreateService 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(container: project, current_user: user, params: opts, spam_params: spam_params).execute end end end @@ -508,7 +508,7 @@ RSpec.describe Issues::CreateService do it 'removes assignee when user id is invalid' do opts = { title: 'Title', description: 'Description', assignee_ids: [-1] } - result = described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + result = described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute issue = result[:issue] expect(result).to be_success @@ -518,7 +518,7 @@ RSpec.describe Issues::CreateService do it 'removes assignee when user id is 0' do opts = { title: 'Title', description: 'Description', assignee_ids: [0] } - result = described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + result = described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute issue = result[:issue] expect(result).to be_success @@ -529,7 +529,7 @@ RSpec.describe Issues::CreateService do project.add_maintainer(assignee) opts = { title: 'Title', description: 'Description', assignee_ids: [assignee.id] } - result = described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + result = described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute issue = result[:issue] expect(result).to be_success @@ -549,7 +549,7 @@ RSpec.describe Issues::CreateService do project.update!(visibility_level: level) opts = { title: 'Title', description: 'Description', assignee_ids: [assignee.id] } - result = described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute + result = described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute issue = result[:issue] expect(result).to be_success @@ -561,10 +561,40 @@ RSpec.describe Issues::CreateService do end it_behaves_like 'issuable record that supports quick actions' do - let(:issuable) { described_class.new(project: project, current_user: user, params: params, spam_params: spam_params).execute[:issue] } + let(:issuable) { described_class.new(container: project, current_user: user, params: params, spam_params: spam_params).execute[:issue] } end context 'Quick actions' do + context 'as work item' do + let(:opts) do + { + title: "My work item", + work_item_type: work_item_type, + description: "/shrug" + } + end + + context 'when work item type is not the default Issue' do + let(:work_item_type) { create(:work_item_type, namespace: project.namespace) } + + it 'saves the work item without applying the quick action' do + expect(result).to be_success + expect(issue).to be_persisted + expect(issue.description).to eq("/shrug") + end + end + + context 'when work item type is the default Issue' do + let(:work_item_type) { WorkItems::Type.default_by_type(:issue) } + + it 'saves the work item and applies the quick action' do + expect(result).to be_success + expect(issue).to be_persisted + expect(issue.description).to eq(" ¯\\_(ツ)_/¯") + end + end + end + context 'with assignee, milestone, and contact in params and command' do let_it_be(:contact) { create(:contact, group: group) } @@ -672,14 +702,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: project, current_user: user, params: opts, spam_params: spam_params).execute + described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).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: project, current_user: user, params: opts, spam_params: spam_params).execute + described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute reloaded_discussion = MergeRequest.find(merge_request.id).discussions.first @@ -688,7 +718,7 @@ RSpec.describe Issues::CreateService do it 'sets default title and description values if not provided' do result = described_class.new( - project: project, current_user: user, + container: project, current_user: user, params: opts, spam_params: spam_params ).execute @@ -702,7 +732,7 @@ RSpec.describe Issues::CreateService do it 'takes params from the request over the default values' do result = described_class.new( - project: project, + container: project, current_user: user, params: opts.merge( description: 'Custom issue description', @@ -723,14 +753,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: project, current_user: user, params: opts, spam_params: spam_params).execute + described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).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: project, current_user: user, params: opts, spam_params: spam_params).execute + described_class.new(container: project, current_user: user, params: opts, spam_params: spam_params).execute reloaded_discussion = MergeRequest.find(merge_request.id).discussions.first @@ -739,7 +769,7 @@ RSpec.describe Issues::CreateService do it 'sets default title and description values if not provided' do result = described_class.new( - project: project, current_user: user, + container: project, current_user: user, params: opts, spam_params: spam_params ).execute @@ -753,7 +783,7 @@ RSpec.describe Issues::CreateService do it 'takes params from the request over the default values' do result = described_class.new( - project: project, + container: project, current_user: user, params: opts.merge( description: 'Custom issue description', @@ -806,7 +836,7 @@ RSpec.describe Issues::CreateService do end subject do - described_class.new(project: project, current_user: user, params: params, spam_params: spam_params) + described_class.new(container: project, current_user: user, params: params, spam_params: spam_params) end it 'executes SpamActionService' do diff --git a/spec/services/issues/duplicate_service_spec.rb b/spec/services/issues/duplicate_service_spec.rb index 0eb0bbb1480..f49bce70cd0 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(project: duplicate_project, current_user: user) } + subject { described_class.new(container: duplicate_project, current_user: user) } describe '#execute' do context 'when the issues passed are the same' do diff --git a/spec/services/issues/export_csv_service_spec.rb b/spec/services/issues/export_csv_service_spec.rb index d3359447fd8..1ac64c0301d 100644 --- a/spec/services/issues/export_csv_service_spec.rb +++ b/spec/services/issues/export_csv_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Issues::ExportCsvService, :with_license do +RSpec.describe Issues::ExportCsvService, :with_license, feature_category: :team_planning do let_it_be(:user) { create(:user) } let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, :public, group: group) } @@ -57,137 +57,151 @@ RSpec.describe Issues::ExportCsvService, :with_license do time_estimate: 72000) end - it 'includes the columns required for import' do - expect(csv.headers).to include('Title', 'Description') - end - - it 'returns two issues' do - expect(csv.count).to eq(2) - end + shared_examples 'exports CSVs for issues' do + it 'includes the columns required for import' do + expect(csv.headers).to include('Title', 'Description') + end - specify 'iid' do - expect(csv[0]['Issue ID']).to eq issue.iid.to_s - end + it 'returns two issues' do + expect(csv.count).to eq(2) + end - specify 'url' do - expect(csv[0]['URL']).to match(/http.*#{project.full_path}.*#{issue.iid}/) - end + specify 'iid' do + expect(csv[0]['Issue ID']).to eq issue.iid.to_s + end - specify 'title' do - expect(csv[0]['Title']).to eq issue.title - end + specify 'url' do + expect(csv[0]['URL']).to match(/http.*#{project.full_path}.*#{issue.iid}/) + end - specify 'state' do - expect(csv[0]['State']).to eq 'Open' - end + specify 'title' do + expect(csv[0]['Title']).to eq issue.title + end - specify 'description' do - expect(csv[0]['Description']).to eq issue.description - expect(csv[1]['Description']).to eq nil - end + specify 'state' do + expect(csv[0]['State']).to eq 'Open' + end - specify 'author name' do - expect(csv[0]['Author']).to eq issue.author_name - end + specify 'description' do + expect(csv[0]['Description']).to eq issue.description + expect(csv[1]['Description']).to eq nil + end - specify 'author username' do - expect(csv[0]['Author Username']).to eq issue.author.username - end + specify 'author name' do + expect(csv[0]['Author']).to eq issue.author_name + end - specify 'assignee name' do - expect(csv[0]['Assignee']).to eq user.name - expect(csv[1]['Assignee']).to eq '' - end + specify 'author username' do + expect(csv[0]['Author Username']).to eq issue.author.username + end - specify 'assignee username' do - expect(csv[0]['Assignee Username']).to eq user.username - expect(csv[1]['Assignee Username']).to eq '' - end + specify 'assignee name' do + expect(csv[0]['Assignee']).to eq user.name + expect(csv[1]['Assignee']).to eq '' + end - specify 'confidential' do - expect(csv[0]['Confidential']).to eq 'No' - end + specify 'assignee username' do + expect(csv[0]['Assignee Username']).to eq user.username + expect(csv[1]['Assignee Username']).to eq '' + end - specify 'milestone' do - expect(csv[0]['Milestone']).to eq issue.milestone.title - expect(csv[1]['Milestone']).to eq nil - end + specify 'confidential' do + expect(csv[0]['Confidential']).to eq 'No' + end - specify 'labels' do - expect(csv[0]['Labels']).to eq 'Feature,Idea' - expect(csv[1]['Labels']).to eq nil - end + specify 'milestone' do + expect(csv[0]['Milestone']).to eq issue.milestone.title + expect(csv[1]['Milestone']).to eq nil + end - specify 'due_date' do - expect(csv[0]['Due Date']).to eq '2014-03-02' - expect(csv[1]['Due Date']).to eq nil - end + specify 'labels' do + expect(csv[0]['Labels']).to eq 'Feature,Idea' + expect(csv[1]['Labels']).to eq nil + end - specify 'created_at' do - expect(csv[0]['Created At (UTC)']).to eq '2015-04-03 02:01:00' - end + specify 'due_date' do + expect(csv[0]['Due Date']).to eq '2014-03-02' + expect(csv[1]['Due Date']).to eq nil + end - specify 'updated_at' do - expect(csv[0]['Updated At (UTC)']).to eq '2016-05-04 03:02:01' - end + specify 'created_at' do + expect(csv[0]['Created At (UTC)']).to eq '2015-04-03 02:01:00' + end - specify 'closed_at' do - expect(csv[0]['Closed At (UTC)']).to eq '2017-06-05 04:03:02' - expect(csv[1]['Closed At (UTC)']).to eq nil - end + specify 'updated_at' do + expect(csv[0]['Updated At (UTC)']).to eq '2016-05-04 03:02:01' + end - specify 'discussion_locked' do - expect(csv[0]['Locked']).to eq 'Yes' - end + specify 'closed_at' do + expect(csv[0]['Closed At (UTC)']).to eq '2017-06-05 04:03:02' + expect(csv[1]['Closed At (UTC)']).to eq nil + end - specify 'weight' do - expect(csv[0]['Weight']).to eq '4' - end + specify 'discussion_locked' do + expect(csv[0]['Locked']).to eq 'Yes' + end - specify 'time estimate' do - expect(csv[0]['Time Estimate']).to eq '72000' - expect(csv[1]['Time Estimate']).to eq '0' - end + specify 'weight' do + expect(csv[0]['Weight']).to eq '4' + end - specify 'time spent' do - expect(csv[0]['Time Spent']).to eq '560' - expect(csv[1]['Time Spent']).to eq '0' - end + specify 'time estimate' do + expect(csv[0]['Time Estimate']).to eq '72000' + expect(csv[1]['Time Estimate']).to eq '0' + end - context 'with issues filtered by labels and project' do - subject do - described_class.new( - IssuesFinder.new(user, - project_id: project.id, - label_name: %w(Idea Feature)).execute, project) + specify 'time spent' do + expect(csv[0]['Time Spent']).to eq '560' + expect(csv[1]['Time Spent']).to eq '0' end - it 'returns only filtered objects' do - expect(csv.count).to eq(1) - expect(csv[0]['Issue ID']).to eq issue.iid.to_s + context 'with issues filtered by labels and project' do + subject do + described_class.new( + IssuesFinder.new(user, + project_id: project.id, + label_name: %w(Idea Feature)).execute, project) + end + + it 'returns only filtered objects' do + expect(csv.count).to eq(1) + expect(csv[0]['Issue ID']).to eq issue.iid.to_s + end end - end - context 'with label links' do - let(:labeled_issues) { create_list(:labeled_issue, 2, project: project, author: user, labels: [feature_label, idea_label]) } + context 'with label links' do + let(:labeled_issues) { create_list(:labeled_issue, 2, project: project, author: user, labels: [feature_label, idea_label]) } - it 'does not run a query for each label link' do - control_count = ActiveRecord::QueryRecorder.new { csv }.count + it 'does not run a query for each label link' do + control_count = ActiveRecord::QueryRecorder.new { csv }.count - labeled_issues + labeled_issues - expect { csv }.not_to exceed_query_limit(control_count) - expect(csv.count).to eq(4) - end + expect { csv }.not_to exceed_query_limit(control_count) + expect(csv.count).to eq(4) + end - it 'returns the labels in sorted order' do - labeled_issues + it 'returns the labels in sorted order' do + labeled_issues - 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")) + 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")) + end end end + + context 'with export_csv_preload_in_batches feature flag disabled' do + before do + stub_feature_flags(export_csv_preload_in_batches: false) + end + + it_behaves_like 'exports CSVs for issues' + end + + context 'with export_csv_preload_in_batches feature flag enabled' do + it_behaves_like 'exports CSVs for issues' + end end context 'with minimal details' do diff --git a/spec/services/issues/import_csv_service_spec.rb b/spec/services/issues/import_csv_service_spec.rb index 9ad1d7dba9f..90e360f9cf1 100644 --- a/spec/services/issues/import_csv_service_spec.rb +++ b/spec/services/issues/import_csv_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Issues::ImportCsvService do +RSpec.describe Issues::ImportCsvService, feature_category: :team_planning do let(:project) { create(:project) } let(:user) { create(:user) } let(:assignee) { create(:user, username: 'csv_assignee') } diff --git a/spec/services/issues/move_service_spec.rb b/spec/services/issues/move_service_spec.rb index 324b2aa9fe2..12924df3200 100644 --- a/spec/services/issues/move_service_spec.rb +++ b/spec/services/issues/move_service_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Issues::MoveService do +RSpec.describe Issues::MoveService, feature_category: :team_planning do include DesignManagementTestHelpers let_it_be(:user) { create(:user) } @@ -20,7 +20,7 @@ RSpec.describe Issues::MoveService do end subject(:move_service) do - described_class.new(project: old_project, current_user: user) + described_class.new(container: 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 16166c1fa33..aee3583b834 100644 --- a/spec/services/issues/referenced_merge_requests_service_spec.rb +++ b/spec/services/issues/referenced_merge_requests_service_spec.rb @@ -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: project, current_user: user) } + let(:service) { described_class.new(container: 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 95d456c1b05..05c61d0abfc 100644 --- a/spec/services/issues/related_branches_service_spec.rb +++ b/spec/services/issues/related_branches_service_spec.rb @@ -9,7 +9,7 @@ RSpec.describe Issues::RelatedBranchesService do let(:user) { developer } - subject { described_class.new(project: project, current_user: user) } + subject { described_class.new(container: project, current_user: user) } before_all do project.add_developer(developer) @@ -54,7 +54,7 @@ RSpec.describe Issues::RelatedBranchesService do merge_request.create_cross_references!(user) referenced_merge_requests = Issues::ReferencedMergeRequestsService - .new(project: issue.project, current_user: user) + .new(container: 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 529b3ff266b..68015a2327e 100644 --- a/spec/services/issues/reopen_service_spec.rb +++ b/spec/services/issues/reopen_service_spec.rb @@ -12,7 +12,7 @@ RSpec.describe Issues::ReopenService do guest = create(:user) project.add_guest(guest) - described_class.new(project: project, current_user: guest).execute(issue) + described_class.new(container: project, current_user: guest).execute(issue) expect(issue).to be_closed end @@ -21,7 +21,7 @@ RSpec.describe Issues::ReopenService do it 'does close the issue even if user is not authorized' do non_authorized_user = create(:user) - service = described_class.new(project: project, current_user: non_authorized_user) + service = described_class.new(container: project, current_user: non_authorized_user) expect do service.execute(issue, skip_authorization: true) @@ -33,7 +33,7 @@ RSpec.describe Issues::ReopenService do context 'when user is authorized to reopen issue' do let(:user) { create(:user) } - subject(:execute) { described_class.new(project: project, current_user: user).execute(issue) } + subject(:execute) { described_class.new(container: project, current_user: user).execute(issue) } before do project.add_maintainer(user) diff --git a/spec/services/issues/reorder_service_spec.rb b/spec/services/issues/reorder_service_spec.rb index 392930c1b9f..430a9e9f526 100644 --- a/spec/services/issues/reorder_service_spec.rb +++ b/spec/services/issues/reorder_service_spec.rb @@ -85,6 +85,6 @@ RSpec.describe Issues::ReorderService do end def service(params) - described_class.new(project: project, current_user: user, params: params) + described_class.new(container: project, current_user: user, params: params) end end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index 930766c520b..973025bd2e3 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -45,7 +45,7 @@ RSpec.describe Issues::UpdateService, :mailer do end def update_issue(opts) - described_class.new(project: project, current_user: user, params: opts).execute(issue) + described_class.new(container: project, current_user: user, params: opts).execute(issue) end it_behaves_like 'issuable update service updating last_edited_at values' do @@ -106,29 +106,29 @@ RSpec.describe Issues::UpdateService, :mailer do context 'when updating milestone' do before do - update_issue({ milestone: nil }) + update_issue({ milestone_id: nil }) end it 'updates issue milestone when passing `milestone` param' do - expect { update_issue({ milestone: milestone }) } + expect { update_issue({ milestone_id: milestone.id }) } .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 }) + update_issue({ milestone_id: milestone.id }) end context 'when milestone remains unchanged' do before do - update_issue({ title: 'abc', milestone: milestone }) + update_issue({ title: 'abc', milestone_id: milestone.id }) end it "does not trigger 'issuableMilestoneUpdated'" do expect(GraphqlTriggers).not_to receive(:issuable_milestone_updated) - update_issue({ milestone: milestone }) + update_issue({ milestone_id: milestone.id }) end end end @@ -420,7 +420,7 @@ RSpec.describe Issues::UpdateService, :mailer do opts[:move_between_ids] = [issue_1.id, issue_2.id] - described_class.new(project: issue_3.project, current_user: user, params: opts).execute(issue_3) + described_class.new(container: 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 @@ -428,7 +428,7 @@ RSpec.describe Issues::UpdateService, :mailer do context 'when current user cannot admin issues in the project' do it 'filters out params that cannot be set without the :admin_issue permission' do described_class.new( - project: project, current_user: guest, params: opts.merge( + container: project, current_user: guest, params: opts.merge( confidential: true, issue_type: 'test_case' ) @@ -755,14 +755,14 @@ RSpec.describe Issues::UpdateService, :mailer do end it 'marks todos as done' do - update_issue(milestone: create(:milestone, project: project)) + update_issue(milestone_id: create(:milestone, project: project).id) expect(todo.reload.done?).to eq true end it 'sends notifications for subscribers of changed milestone', :sidekiq_might_not_need_inline do perform_enqueued_jobs do - update_issue(milestone: create(:milestone, project: project)) + update_issue(milestone_id: create(:milestone, project: project).id) end should_email(subscriber) @@ -779,7 +779,7 @@ RSpec.describe Issues::UpdateService, :mailer do expect(service).to receive(:delete_cache).and_call_original end - update_issue(milestone: milestone) + update_issue(milestone_id: milestone.id) end end @@ -803,7 +803,7 @@ RSpec.describe Issues::UpdateService, :mailer do expect(service).to receive(:delete_cache).and_call_original end - update_issue(milestone: new_milestone) + update_issue(milestone_id: new_milestone.id) end end @@ -838,7 +838,7 @@ RSpec.describe Issues::UpdateService, :mailer do opts = { label_ids: [label.id] } perform_enqueued_jobs do - @issue = described_class.new(project: project, current_user: user, params: opts).execute(issue) + @issue = described_class.new(container: project, current_user: user, params: opts).execute(issue) end should_email(subscriber) @@ -854,7 +854,7 @@ RSpec.describe Issues::UpdateService, :mailer do opts = { label_ids: [label.id, label2.id] } perform_enqueued_jobs do - @issue = described_class.new(project: project, current_user: user, params: opts).execute(issue) + @issue = described_class.new(container: project, current_user: user, params: opts).execute(issue) end should_not_email(subscriber) @@ -865,7 +865,7 @@ RSpec.describe Issues::UpdateService, :mailer do opts = { label_ids: [label2.id] } perform_enqueued_jobs do - @issue = described_class.new(project: project, current_user: user, params: opts).execute(issue) + @issue = described_class.new(container: project, current_user: user, params: opts).execute(issue) end should_not_email(subscriber) @@ -897,7 +897,7 @@ RSpec.describe Issues::UpdateService, :mailer do line_number: 1 } } - service = described_class.new(project: project, current_user: user, params: params) + service = described_class.new(container: project, current_user: user, params: params) expect(Spam::SpamActionService).not_to receive(:new) @@ -915,7 +915,7 @@ RSpec.describe Issues::UpdateService, :mailer do line_number: 1 } } - service = described_class.new(project: project, current_user: user, params: params) + service = described_class.new(container: project, current_user: user, params: params) expect(service).to receive(:after_update).with(issue, {}) @@ -991,7 +991,7 @@ RSpec.describe Issues::UpdateService, :mailer do context 'updating labels' do let(:label3) { create(:label, project: project) } - let(:result) { described_class.new(project: project, current_user: user, params: params).execute(issue).reload } + let(:result) { described_class.new(container: 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] } } @@ -1063,7 +1063,7 @@ RSpec.describe Issues::UpdateService, :mailer do end context 'updating dates' do - subject(:result) { described_class.new(project: project, current_user: user, params: params).execute(issue) } + subject(:result) { described_class.new(container: project, current_user: user, params: params).execute(issue) } let(:updated_date) { 1.week.from_now.to_date } @@ -1428,7 +1428,7 @@ RSpec.describe Issues::UpdateService, :mailer do it 'raises an error for invalid move ids' do opts = { move_between_ids: [9000, non_existing_record_id] } - expect { described_class.new(project: issue.project, current_user: user, params: opts).execute(issue) } + expect { described_class.new(container: issue.project, current_user: user, params: opts).execute(issue) } .to raise_error(ActiveRecord::RecordNotFound) end end @@ -1473,7 +1473,33 @@ 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: project, current_user: user, params: params).execute(existing_issue) } + let(:issuable) { described_class.new(container: project, current_user: user, params: params).execute(existing_issue) } + end + + context 'with quick actions' do + context 'as work item' do + let(:opts) { { description: "/shrug" } } + + context 'when work item type is not the default Issue' do + let(:issue) { create(:work_item, :task, description: "") } + + it 'does not apply the quick action' do + expect do + update_issue(opts) + end.to change(issue, :description).to("/shrug") + end + end + + context 'when work item type is the default Issue' do + let(:issue) { create(:work_item, :issue, description: "") } + + it 'does not apply the quick action' do + expect do + update_issue(opts) + end.to change(issue, :description).to(" ¯\\_(ツ)_/¯") + end + end + end end end end diff --git a/spec/services/issues/zoom_link_service_spec.rb b/spec/services/issues/zoom_link_service_spec.rb index ad1f91ab5e6..230e4c1b5e1 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(project: project, current_user: user, params: { issue: issue }) } + let(:service) { described_class.new(container: project, current_user: user, params: { issue: issue }) } let(:zoom_link) { 'https://zoom.us/j/123456789' } before do |