diff options
author | Ryan Scott <ryan@ryan-scott.me> | 2017-03-30 04:39:06 +0300 |
---|---|---|
committer | Sean McGivern <sean@gitlab.com> | 2017-07-20 17:33:24 +0300 |
commit | 01c9488f4a559063eba77074ba2d369de87b8018 (patch) | |
tree | ffd18d3ebd174cf47ab9eb71cbacd940d4cf2831 /spec | |
parent | b6555693a8e445405c5746b7c76c9f603395bba2 (diff) |
Added slash command to close an issue as a duplicate. Closes #26372
Diffstat (limited to 'spec')
-rw-r--r-- | spec/features/issues/user_uses_slash_commands_spec.rb | 41 | ||||
-rw-r--r-- | spec/services/issues/update_service_spec.rb | 56 | ||||
-rw-r--r-- | spec/services/quick_actions/interpret_service_spec.rb | 36 | ||||
-rw-r--r-- | spec/services/system_note_service_spec.rb | 25 |
4 files changed, 158 insertions, 0 deletions
diff --git a/spec/features/issues/user_uses_slash_commands_spec.rb b/spec/features/issues/user_uses_slash_commands_spec.rb index 1cd1f016674..d5de060b033 100644 --- a/spec/features/issues/user_uses_slash_commands_spec.rb +++ b/spec/features/issues/user_uses_slash_commands_spec.rb @@ -134,5 +134,46 @@ feature 'Issues > User uses quick actions', feature: true, js: true do expect(page).not_to have_content '/wip' end end + + describe 'mark issue as duplicate' do + let(:issue) { create(:issue, project: project) } + let(:original_issue) { create(:issue, project: project) } + + context 'when the current user can update issues' do + it 'does not create a note, and marks the issue as a duplicate' do + write_note("/duplicate ##{original_issue.to_reference}") + + expect(page).not_to have_content "/duplicate #{original_issue.to_reference}" + expect(page).to have_content 'Commands applied' + expect(page).to have_content "marked this issue as a duplicate of #{original_issue.to_reference}" + + issue.reload + + expect(issue.closed?).to be_truthy + end + end + + context 'when the current user cannot update the issue' do + let(:guest) { create(:user) } + before do + project.team << [guest, :guest] + logout + login_with(guest) + visit namespace_project_issue_path(project.namespace, project, issue) + end + + it 'does not create a note, and does not mark the issue as a duplicate' do + write_note("/duplicate ##{original_issue.to_reference}") + + expect(page).to have_content "/duplicate ##{original_issue.to_reference}" + expect(page).not_to have_content 'Commands applied' + expect(page).not_to have_content "marked this issue as a duplicate of #{original_issue.to_reference}" + + issue.reload + + expect(issue.closed?).to be_falsey + end + end + end end end diff --git a/spec/services/issues/update_service_spec.rb b/spec/services/issues/update_service_spec.rb index d0b991f19ab..3e7abf85106 100644 --- a/spec/services/issues/update_service_spec.rb +++ b/spec/services/issues/update_service_spec.rb @@ -491,6 +491,62 @@ describe Issues::UpdateService, services: true do include_examples 'updating mentions', Issues::UpdateService end + context 'duplicate issue' do + let(:issues_finder) { spy(:issues_finder) } + let(:close_service) { spy(:close_service) } + + before do + allow(IssuesFinder).to receive(:new).and_return(issues_finder) + allow(Issues::CloseService).to receive(:new).and_return(close_service) + allow(SystemNoteService).to receive(:cross_reference) + allow(SystemNoteService).to receive(:mark_duplicate_issue) + end + + context 'invalid original_issue_id' do + let(:original_issue_id) { double } + before { update_issue({ original_issue_id: original_issue_id }) } + + it 'finds the root issue' do + expect(issues_finder).to have_received(:find).with(original_issue_id) + end + + it 'does not close the issue' do + expect(close_service).not_to have_received(:execute) + end + + it 'does not create system notes' do + expect(SystemNoteService).not_to have_received(:cross_reference) + expect(SystemNoteService).not_to have_received(:mark_duplicate_issue) + end + end + + context 'valid original_issue_id' do + let(:original_issue) { create(:issue, project: project) } + let(:original_issue_id) { double } + + before do + allow(issues_finder).to receive(:find).and_return(original_issue) + update_issue({ original_issue_id: original_issue_id }) + end + + it 'finds the root issue' do + expect(issues_finder).to have_received(:find).with(original_issue_id) + end + + it 'closes the issue' do + expect(close_service).to have_received(:execute).with(issue) + end + + it 'creates a system note that this issue is a duplicate' do + expect(SystemNoteService).to have_received(:mark_duplicate_issue).with(issue, project, user, original_issue) + end + + it 'creates a cross reference system note in the other issue' do + expect(SystemNoteService).to have_received(:cross_reference).with(original_issue, issue, user) + end + end + end + include_examples 'issuable update service' do let(:open_issuable) { issue } let(:closed_issuable) { create(:closed_issue, project: project) } diff --git a/spec/services/quick_actions/interpret_service_spec.rb b/spec/services/quick_actions/interpret_service_spec.rb index a2db3f68ff7..3e4aa66756c 100644 --- a/spec/services/quick_actions/interpret_service_spec.rb +++ b/spec/services/quick_actions/interpret_service_spec.rb @@ -261,6 +261,17 @@ describe QuickActions::InterpretService, services: true do end end + shared_examples 'duplicate command' do + let(:issue_duplicate) { create(:issue, project: project) } + + it 'fetches issue and populates original_issue_id if content contains /duplicate issue_reference' do + issue_duplicate # populate the issue + _, updates = service.execute(content, issuable) + + expect(updates).to eq(original_issue_id: issue_duplicate.id) + end + end + it_behaves_like 'reopen command' do let(:content) { '/reopen' } let(:issuable) { issue } @@ -644,6 +655,26 @@ describe QuickActions::InterpretService, services: true do let(:issuable) { issue } end + it_behaves_like 'duplicate command' do + let(:content) { "/duplicate #{issue_duplicate.to_reference}" } + let(:issuable) { issue } + end + + it_behaves_like 'empty command' do + let(:content) { '/duplicate #{issue.to_reference}' } + let(:issuable) { issue } + end + + it_behaves_like 'empty command' do + let(:content) { '/duplicate' } + let(:issuable) { issue } + end + + it_behaves_like 'empty command' do + let(:content) { '/duplicate imaginary#1234' } + let(:issuable) { issue } + end + context 'when current_user cannot :admin_issue' do let(:visitor) { create(:user) } let(:issue) { create(:issue, project: project, author: visitor) } @@ -693,6 +724,11 @@ describe QuickActions::InterpretService, services: true do let(:content) { '/remove_due_date' } let(:issuable) { issue } end + + it_behaves_like 'empty command' do + let(:content) { '/duplicate #{issue.to_reference}' } + let(:issuable) { issue } + end end context '/award command' do diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb index 60477b8e9ba..db120889119 100644 --- a/spec/services/system_note_service_spec.rb +++ b/spec/services/system_note_service_spec.rb @@ -1101,4 +1101,29 @@ describe SystemNoteService, services: true do expect(subject.note).to include(diffs_project_merge_request_url(project, merge_request, diff_id: diff_id, anchor: line_code)) end end + + describe '.mark_duplicate_issue' do + subject { described_class.mark_duplicate_issue(noteable, project, author, original_issue) } + + context 'within the same project' do + let(:original_issue) { create(:issue, project: project) } + + it_behaves_like 'a system note' do + let(:action) { 'duplicate' } + end + + it { expect(subject.note).to eq "marked this issue as a duplicate of #{original_issue.to_reference}" } + end + + context 'across different projects' do + let(:other_project) { create(:empty_project) } + let(:original_issue) { create(:issue, project: other_project) } + + it_behaves_like 'a system note' do + let(:action) { 'duplicate' } + end + + it { expect(subject.note).to eq "marked this issue as a duplicate of #{original_issue.to_reference(project)}" } + end + end end |