summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab/slash_commands
diff options
context:
space:
mode:
authorSean McGivern <sean@gitlab.com>2018-03-12 15:29:45 +0000
committerSean McGivern <sean@gitlab.com>2018-03-15 13:09:11 +0000
commit0fa139dfda0b2f5d7b15ba60d7b3a4a6d9a22c49 (patch)
treef79e08530601d79aefa6e16f6ee6626aea1f1c5d /spec/lib/gitlab/slash_commands
parent82b6222022c496290066fbdd6c3c2490bd23622c (diff)
downloadgitlab-ce-0fa139dfda0b2f5d7b15ba60d7b3a4a6d9a22c49.tar.gz
Add slash command for moving an issue
Carried over from https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/8857
Diffstat (limited to 'spec/lib/gitlab/slash_commands')
-rw-r--r--spec/lib/gitlab/slash_commands/command_spec.rb5
-rw-r--r--spec/lib/gitlab/slash_commands/issue_move_spec.rb117
-rw-r--r--spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb26
3 files changed, 148 insertions, 0 deletions
diff --git a/spec/lib/gitlab/slash_commands/command_spec.rb b/spec/lib/gitlab/slash_commands/command_spec.rb
index e3447d974aa..194cae8c645 100644
--- a/spec/lib/gitlab/slash_commands/command_spec.rb
+++ b/spec/lib/gitlab/slash_commands/command_spec.rb
@@ -108,5 +108,10 @@ describe Gitlab::SlashCommands::Command do
it { is_expected.to eq(Gitlab::SlashCommands::IssueSearch) }
end
+
+ context 'IssueMove is triggered' do
+ let(:params) { { text: 'issue move #78291 to gitlab/gitlab-ci' } }
+ it { is_expected.to eq(Gitlab::SlashCommands::IssueMove) }
+ end
end
end
diff --git a/spec/lib/gitlab/slash_commands/issue_move_spec.rb b/spec/lib/gitlab/slash_commands/issue_move_spec.rb
new file mode 100644
index 00000000000..d41441c9472
--- /dev/null
+++ b/spec/lib/gitlab/slash_commands/issue_move_spec.rb
@@ -0,0 +1,117 @@
+require 'spec_helper'
+
+describe Gitlab::SlashCommands::IssueMove, service: true do
+ describe '#match' do
+ shared_examples_for 'move command' do |text_command|
+ it 'can be parsed to extract the needed fields' do
+ match_data = described_class.match(text_command)
+
+ expect(match_data['iid']).to eq('123456')
+ expect(match_data['project_path']).to eq('gitlab/gitlab-ci')
+ end
+ end
+
+ it_behaves_like 'move command', 'issue move #123456 to gitlab/gitlab-ci'
+ it_behaves_like 'move command', 'issue move #123456 gitlab/gitlab-ci'
+ it_behaves_like 'move command', 'issue move #123456 gitlab/gitlab-ci '
+ it_behaves_like 'move command', 'issue move 123456 to gitlab/gitlab-ci'
+ it_behaves_like 'move command', 'issue move 123456 gitlab/gitlab-ci'
+ it_behaves_like 'move command', 'issue move 123456 gitlab/gitlab-ci '
+ end
+
+ describe '#execute' do
+ set(:user) { create(:user) }
+ set(:issue) { create(:issue) }
+ set(:chat_name) { create(:chat_name, user: user) }
+ set(:project) { issue.project }
+ set(:other_project) { create(:project, namespace: project.namespace) }
+
+ before do
+ [project, other_project].each { |prj| prj.add_master(user) }
+ end
+
+ subject { described_class.new(project, chat_name) }
+
+ def process_message(message)
+ subject.execute(described_class.match(message))
+ end
+
+ context 'when the user can move the issue' do
+ context 'when the move fails' do
+ it 'returns the error message' do
+ message = "issue move #{issue.iid} #{project.full_path}"
+
+ expect(process_message(message)).to include(response_type: :ephemeral,
+ text: a_string_matching('Cannot move issue'))
+ end
+ end
+
+ context 'when the move succeeds' do
+ let(:message) { "issue move #{issue.iid} #{other_project.full_path}" }
+
+ it 'moves the issue to the new destination' do
+ expect { process_message(message) }.to change { Issue.count }.by(1)
+
+ new_issue = issue.reload.moved_to
+
+ expect(new_issue.state).to eq('opened')
+ expect(new_issue.project_id).to eq(other_project.id)
+ expect(new_issue.author_id).to eq(issue.author_id)
+
+ expect(issue.state).to eq('closed')
+ expect(issue.project_id).to eq(project.id)
+ end
+
+ it 'returns the new issue' do
+ expect(process_message(message))
+ .to include(response_type: :in_channel,
+ attachments: [a_hash_including(title_link: a_string_including(other_project.full_path))])
+ end
+
+ it 'mentions the old issue' do
+ expect(process_message(message))
+ .to include(attachments: [a_hash_including(pretext: a_string_including(project.full_path))])
+ end
+ end
+ end
+
+ context 'when the issue does not exist' do
+ it 'returns not found' do
+ message = "issue move #{issue.iid.succ} #{other_project.full_path}"
+
+ expect(process_message(message)).to include(response_type: :ephemeral,
+ text: a_string_matching('not found'))
+ end
+ end
+
+ context 'when the target project does not exist' do
+ it 'returns not found' do
+ message = "issue move #{issue.iid} #{other_project.full_path}/foo"
+
+ expect(process_message(message)).to include(response_type: :ephemeral,
+ text: a_string_matching('not found'))
+ end
+ end
+
+ context 'when the user cannot see the target project' do
+ it 'returns not found' do
+ message = "issue move #{issue.iid} #{other_project.full_path}"
+ other_project.team.truncate
+
+ expect(process_message(message)).to include(response_type: :ephemeral,
+ text: a_string_matching('not found'))
+ end
+ end
+
+ context 'when the user does not have the required permissions on the target project' do
+ it 'returns the error message' do
+ message = "issue move #{issue.iid} #{other_project.full_path}"
+ other_project.team.truncate
+ other_project.team.add_guest(user)
+
+ expect(process_message(message)).to include(response_type: :ephemeral,
+ text: a_string_matching('Cannot move issue'))
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb b/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
new file mode 100644
index 00000000000..58c341a284e
--- /dev/null
+++ b/spec/lib/gitlab/slash_commands/presenters/issue_move_spec.rb
@@ -0,0 +1,26 @@
+require 'spec_helper'
+
+describe Gitlab::SlashCommands::Presenters::IssueMove do
+ set(:admin) { create(:admin) }
+ set(:project) { create(:project) }
+ set(:other_project) { create(:project) }
+ set(:old_issue) { create(:issue, project: project) }
+ set(:new_issue) { Issues::MoveService.new(project, admin).execute(old_issue, other_project) }
+ let(:attachment) { subject[:attachments].first }
+
+ subject { described_class.new(new_issue).present(old_issue) }
+
+ it { is_expected.to be_a(Hash) }
+
+ it 'shows the new issue' do
+ expect(subject[:response_type]).to be(:in_channel)
+ expect(subject).to have_key(:attachments)
+ expect(attachment[:title]).to start_with(new_issue.title)
+ expect(attachment[:title_link]).to include(other_project.full_path)
+ end
+
+ it 'mentions the old issue and the new issue in the pretext' do
+ expect(attachment[:pretext]).to include(project.full_path)
+ expect(attachment[:pretext]).to include(other_project.full_path)
+ end
+end