Add the /title slash command
Signed-off-by: Rémy Coutable <remy@rymai.me>
This commit is contained in:
parent
7cc4ab14b8
commit
39f7f63fe9
6 changed files with 89 additions and 12 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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|
|
||||
|
|
|
@ -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 |
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue