summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRémy Coutable <remy@rymai.me>2016-08-09 20:54:18 +0200
committerRémy Coutable <remy@rymai.me>2016-08-13 00:06:12 +0200
commit39f7f63fe951ff861ad151125188e6cdd598b6ff (patch)
tree8fa991298d3be0c8537f8402f4e17a5cd5e2eb28
parent7cc4ab14b8a2f1d7d374a320b79374764527659f (diff)
downloadgitlab-ce-39f7f63fe951ff861ad151125188e6cdd598b6ff.tar.gz
Add the /title slash command
Signed-off-by: Rémy Coutable <remy@rymai.me>
-rw-r--r--app/services/issuable_base_service.rb2
-rw-r--r--app/services/slash_commands/interpret_service.rb6
-rw-r--r--doc/workflow/slash_commands.md3
-rw-r--r--spec/lib/gitlab/email/handler/create_note_handler_spec.rb15
-rw-r--r--spec/services/slash_commands/interpret_service_spec.rb38
-rw-r--r--spec/support/issuable_slash_commands_shared_examples.rb37
6 files changed, 89 insertions, 12 deletions
diff --git a/app/services/issuable_base_service.rb b/app/services/issuable_base_service.rb
index 3512e2b735e..1ef7a2433dc 100644
--- a/app/services/issuable_base_service.rb
+++ b/app/services/issuable_base_service.rb
@@ -86,7 +86,7 @@ class IssuableBaseService < BaseService
remove_label_ids = attributes.delete(:remove_label_ids)
new_label_ids = base_label_ids
- new_label_ids = label_ids if label_ids && (merge_all || (add_label_ids.empty? && remove_label_ids.empty?))
+ new_label_ids = label_ids if label_ids && (merge_all || (add_label_ids.blank? && remove_label_ids.blank?))
new_label_ids |= add_label_ids if add_label_ids
new_label_ids -= remove_label_ids if remove_label_ids
diff --git a/app/services/slash_commands/interpret_service.rb b/app/services/slash_commands/interpret_service.rb
index bff61683976..74825f30868 100644
--- a/app/services/slash_commands/interpret_service.rb
+++ b/app/services/slash_commands/interpret_service.rb
@@ -34,6 +34,12 @@ module SlashCommands
@updates[:state_event] = 'reopen'
end
+ desc 'Change title'
+ params '<New title>'
+ command :title do |title_param|
+ @updates[:title] = title_param
+ end
+
desc 'Reassign'
params '@user'
command :assign, :reassign do |assignee_param|
diff --git a/doc/workflow/slash_commands.md b/doc/workflow/slash_commands.md
index 3bfc66309ba..bf5b8ebe1c8 100644
--- a/doc/workflow/slash_commands.md
+++ b/doc/workflow/slash_commands.md
@@ -13,6 +13,7 @@ do.
|:---------------------------|:--------------------|:-------------|
| `/close` | None | Close the issue or merge request |
| `/open` | `/reopen` | Reopen the issue or merge request |
+| `/title <New title>` | None | Change title |
| `/assign @username` | `/reassign` | Reassign |
| `/unassign` | `/remove_assignee` | Remove assignee |
| `/milestone %milestone` | None | Change milestone |
@@ -24,5 +25,5 @@ do.
| `/done` | None | Mark todo as done |
| `/subscribe` | None | Subscribe |
| `/unsubscribe` | None | Unsubscribe |
-| `/due_date` | None | Set a due date |
+| `/due_date <YYYY-MM-DD> | <N days>` | None | Set a due date |
| `/clear_due_date` | None | Remove due date |
diff --git a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
index e2339c5e103..afb072105cf 100644
--- a/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/create_note_handler_spec.rb
@@ -64,10 +64,21 @@ describe Gitlab::Email::Handler::CreateNoteHandler, lib: true do
context 'because the note was commands only' do
let!(:email_raw) { fixture_file("emails/commands_only_reply.eml") }
- it 'raises a CommandsOnlyNoteError' do
- expect { receiver.execute }.not_to raise_error
+ context 'and current user cannot update noteable' do
+ it 'raises a CommandsOnlyNoteError' do
+ expect { receiver.execute }.to raise_error(Gitlab::Email::InvalidNoteError)
+ end
end
+ context 'and current user can update noteable' do
+ before do
+ project.team << [user, :developer]
+ end
+
+ it 'raises a CommandsOnlyNoteError' do
+ expect { receiver.execute }.not_to raise_error
+ end
+ end
end
end
diff --git a/spec/services/slash_commands/interpret_service_spec.rb b/spec/services/slash_commands/interpret_service_spec.rb
index d03c84f59b3..66ebe091893 100644
--- a/spec/services/slash_commands/interpret_service_spec.rb
+++ b/spec/services/slash_commands/interpret_service_spec.rb
@@ -15,6 +15,7 @@ describe SlashCommands::InterpretService, services: true do
is_expected.to match_array([
:open, :reopen,
:close,
+ :title,
:assign, :reassign,
:unassign, :remove_assignee,
:milestone,
@@ -53,6 +54,14 @@ describe SlashCommands::InterpretService, services: true do
end
end
+ shared_examples 'title command' do
+ it 'populates title: "A brand new title" if content contains /title A brand new title' do
+ changes = service.execute(content, issuable)
+
+ expect(changes).to eq(title: 'A brand new title')
+ end
+ end
+
shared_examples 'assign command' do
it 'fetches assignee and populates assignee_id if content contains /assign' do
changes = service.execute(content, issuable)
@@ -190,6 +199,21 @@ describe SlashCommands::InterpretService, services: true do
let(:issuable) { merge_request }
end
+ it_behaves_like 'title command' do
+ let(:content) { '/title A brand new title' }
+ let(:issuable) { issue }
+ end
+
+ it_behaves_like 'title command' do
+ let(:content) { '/title A brand new title' }
+ let(:issuable) { merge_request }
+ end
+
+ it_behaves_like 'empty command' do
+ let(:content) { '/title' }
+ let(:issuable) { issue }
+ end
+
it_behaves_like 'assign command' do
let(:content) { "/assign @#{user.username}" }
let(:issuable) { issue }
@@ -200,16 +224,14 @@ describe SlashCommands::InterpretService, services: true do
let(:issuable) { merge_request }
end
- it 'does not populate assignee_id if content contains /assign with an unknown user' do
- changes = service.execute('/assign joe', issue)
-
- expect(changes).to be_empty
+ it_behaves_like 'empty command' do
+ let(:content) { '/assign @abcd1234' }
+ let(:issuable) { issue }
end
- it 'does not populate assignee_id if content contains /assign without user' do
- changes = service.execute('/assign', issue)
-
- expect(changes).to be_empty
+ it_behaves_like 'empty command' do
+ let(:content) { '/assign' }
+ let(:issuable) { issue }
end
it_behaves_like 'unassign command' do
diff --git a/spec/support/issuable_slash_commands_shared_examples.rb b/spec/support/issuable_slash_commands_shared_examples.rb
index 824ccb0ddfb..4f2e7c3bee8 100644
--- a/spec/support/issuable_slash_commands_shared_examples.rb
+++ b/spec/support/issuable_slash_commands_shared_examples.rb
@@ -166,6 +166,43 @@ shared_examples 'issuable record that supports slash commands in its description
end
end
+ context "with a note changing the #{issuable_type}'s title" do
+ context "when current user can change title of #{issuable_type}" do
+ it "reopens the #{issuable_type}" do
+ page.within('.js-main-target-form') do
+ fill_in 'note[note]', with: "/title Awesome new title"
+ click_button 'Comment'
+ end
+
+ expect(page).not_to have_content '/title'
+ expect(page).to have_content 'Your commands are being executed.'
+
+ expect(issuable.reload.title).to eq 'Awesome new title'
+ end
+ end
+
+ context "when current user cannot change title of #{issuable_type}" do
+ before do
+ logout
+ login_with(guest)
+ visit public_send("namespace_project_#{issuable_type}_path", project.namespace, project, issuable)
+ end
+
+ it "does not reopen the #{issuable_type}" do
+ current_title = issuable.title
+ page.within('.js-main-target-form') do
+ fill_in 'note[note]', with: "/title Awesome new title"
+ click_button 'Comment'
+ end
+
+ expect(page).not_to have_content '/title'
+ expect(page).not_to have_content 'Your commands are being executed.'
+
+ expect(issuable.reload.title).not_to eq 'Awesome new title'
+ end
+ end
+ end
+
context "with a note marking the #{issuable_type} as todo" do
it "creates a new todo for the #{issuable_type}" do
page.within('.js-main-target-form') do