Show commands applied message when promoting issues
Fix 'commands applied' messages not being shown when issue is promoted to epic using slash commands.
This commit is contained in:
parent
4b0036b87e
commit
78dc1b58a6
9 changed files with 84 additions and 25 deletions
|
@ -21,7 +21,7 @@ module Notes
|
||||||
|
|
||||||
if quick_actions_service.supported?(note)
|
if quick_actions_service.supported?(note)
|
||||||
options = { merge_request_diff_head_sha: merge_request_diff_head_sha }
|
options = { merge_request_diff_head_sha: merge_request_diff_head_sha }
|
||||||
content, command_params = quick_actions_service.extract_commands(note, options)
|
content, update_params = quick_actions_service.execute(note, options)
|
||||||
|
|
||||||
only_commands = content.empty?
|
only_commands = content.empty?
|
||||||
|
|
||||||
|
@ -43,16 +43,17 @@ module Notes
|
||||||
Suggestions::CreateService.new(note).execute
|
Suggestions::CreateService.new(note).execute
|
||||||
end
|
end
|
||||||
|
|
||||||
if command_params.present?
|
if quick_actions_service.commands_executed_count.to_i > 0
|
||||||
quick_actions_service.execute(command_params, note)
|
if update_params.present?
|
||||||
|
quick_actions_service.apply_updates(update_params, note)
|
||||||
|
note.commands_changes = update_params
|
||||||
|
end
|
||||||
|
|
||||||
# We must add the error after we call #save because errors are reset
|
# We must add the error after we call #save because errors are reset
|
||||||
# when #save is called
|
# when #save is called
|
||||||
if only_commands
|
if only_commands
|
||||||
note.errors.add(:commands_only, 'Commands applied')
|
note.errors.add(:commands_only, 'Commands applied')
|
||||||
end
|
end
|
||||||
|
|
||||||
note.commands_changes = command_params
|
|
||||||
end
|
end
|
||||||
|
|
||||||
note
|
note
|
||||||
|
|
|
@ -1,7 +1,18 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# QuickActionsService class
|
||||||
|
#
|
||||||
|
# Executes quick actions commands extracted from note text
|
||||||
|
#
|
||||||
|
# Most commands returns parameters to be applied later
|
||||||
|
# using QuickActionService#apply_updates
|
||||||
|
#
|
||||||
module Notes
|
module Notes
|
||||||
class QuickActionsService < BaseService
|
class QuickActionsService < BaseService
|
||||||
|
attr_reader :interpret_service
|
||||||
|
|
||||||
|
delegate :commands_executed_count, to: :interpret_service, allow_nil: true
|
||||||
|
|
||||||
UPDATE_SERVICES = {
|
UPDATE_SERVICES = {
|
||||||
'Issue' => Issues::UpdateService,
|
'Issue' => Issues::UpdateService,
|
||||||
'MergeRequest' => MergeRequests::UpdateService,
|
'MergeRequest' => MergeRequests::UpdateService,
|
||||||
|
@ -25,18 +36,21 @@ module Notes
|
||||||
self.class.supported?(note)
|
self.class.supported?(note)
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_commands(note, options = {})
|
def execute(note, options = {})
|
||||||
return [note.note, {}] unless supported?(note)
|
return [note.note, {}] unless supported?(note)
|
||||||
|
|
||||||
QuickActions::InterpretService.new(project, current_user, options)
|
@interpret_service = QuickActions::InterpretService.new(project, current_user, options)
|
||||||
.execute(note.note, note.noteable)
|
|
||||||
|
@interpret_service.execute(note.note, note.noteable)
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute(command_params, note)
|
# Applies updates extracted to note#noteable
|
||||||
return if command_params.empty?
|
# The update parameters are extracted on self#execute
|
||||||
|
def apply_updates(update_params, note)
|
||||||
|
return if update_params.empty?
|
||||||
return unless supported?(note)
|
return unless supported?(note)
|
||||||
|
|
||||||
self.class.noteable_update_service(note).new(note.parent, current_user, command_params).execute(note.noteable)
|
self.class.noteable_update_service(note).new(note.parent, current_user, update_params).execute(note.noteable)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -7,6 +7,11 @@ module QuickActions
|
||||||
|
|
||||||
attr_reader :issuable
|
attr_reader :issuable
|
||||||
|
|
||||||
|
# Counts how many commands have been executed.
|
||||||
|
# Used to display relevant feedback on UI when a note
|
||||||
|
# with only commands has been processed.
|
||||||
|
attr_accessor :commands_executed_count
|
||||||
|
|
||||||
SHRUG = '¯\\_(ツ)_/¯'.freeze
|
SHRUG = '¯\\_(ツ)_/¯'.freeze
|
||||||
TABLEFLIP = '(╯°□°)╯︵ ┻━┻'.freeze
|
TABLEFLIP = '(╯°□°)╯︵ ┻━┻'.freeze
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,8 @@ module Gitlab
|
||||||
def execute(context, arg)
|
def execute(context, arg)
|
||||||
return if noop? || !available?(context)
|
return if noop? || !available?(context)
|
||||||
|
|
||||||
|
count_commands_executed_in(context)
|
||||||
|
|
||||||
execute_block(action_block, context, arg)
|
execute_block(action_block, context, arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -73,6 +75,13 @@ module Gitlab
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def count_commands_executed_in(context)
|
||||||
|
return unless context.respond_to?(:commands_executed_count=)
|
||||||
|
|
||||||
|
context.commands_executed_count ||= 0
|
||||||
|
context.commands_executed_count += 1
|
||||||
|
end
|
||||||
|
|
||||||
def execute_block(block, context, arg)
|
def execute_block(block, context, arg)
|
||||||
if arg.present?
|
if arg.present?
|
||||||
parsed = parse_params(arg, context)
|
parsed = parse_params(arg, context)
|
||||||
|
|
|
@ -243,7 +243,9 @@ describe 'Issues > User uses quick actions', :js do
|
||||||
it 'does not move the issue' do
|
it 'does not move the issue' do
|
||||||
add_note("/move not/valid")
|
add_note("/move not/valid")
|
||||||
|
|
||||||
expect(page).not_to have_content 'Commands applied'
|
wait_for_requests
|
||||||
|
|
||||||
|
expect(page).to have_content 'Commands applied'
|
||||||
expect(issue.reload).to be_open
|
expect(issue.reload).to be_open
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,7 @@ describe Gitlab::QuickActions::CommandDefinition do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#execute" do
|
describe "#execute" do
|
||||||
let(:context) { OpenStruct.new(run: false) }
|
let(:context) { OpenStruct.new(run: false, commands_executed_count: nil) }
|
||||||
|
|
||||||
context "when the command is a noop" do
|
context "when the command is a noop" do
|
||||||
it "doesn't execute the command" do
|
it "doesn't execute the command" do
|
||||||
|
@ -80,6 +80,7 @@ describe Gitlab::QuickActions::CommandDefinition do
|
||||||
|
|
||||||
subject.execute(context, nil)
|
subject.execute(context, nil)
|
||||||
|
|
||||||
|
expect(context.commands_executed_count).to be_nil
|
||||||
expect(context.run).to be false
|
expect(context.run).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -97,6 +98,7 @@ describe Gitlab::QuickActions::CommandDefinition do
|
||||||
it "doesn't execute the command" do
|
it "doesn't execute the command" do
|
||||||
subject.execute(context, nil)
|
subject.execute(context, nil)
|
||||||
|
|
||||||
|
expect(context.commands_executed_count).to be_nil
|
||||||
expect(context.run).to be false
|
expect(context.run).to be false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -112,6 +114,7 @@ describe Gitlab::QuickActions::CommandDefinition do
|
||||||
subject.execute(context, true)
|
subject.execute(context, true)
|
||||||
|
|
||||||
expect(context.run).to be true
|
expect(context.run).to be true
|
||||||
|
expect(context.commands_executed_count).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -120,6 +123,7 @@ describe Gitlab::QuickActions::CommandDefinition do
|
||||||
subject.execute(context, nil)
|
subject.execute(context, nil)
|
||||||
|
|
||||||
expect(context.run).to be true
|
expect(context.run).to be true
|
||||||
|
expect(context.commands_executed_count).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -134,6 +138,7 @@ describe Gitlab::QuickActions::CommandDefinition do
|
||||||
subject.execute(context, true)
|
subject.execute(context, true)
|
||||||
|
|
||||||
expect(context.run).to be true
|
expect(context.run).to be true
|
||||||
|
expect(context.commands_executed_count).to eq(1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -220,6 +220,19 @@ describe Notes::CreateService do
|
||||||
expect(note.note).to eq "HELLO\nWORLD"
|
expect(note.note).to eq "HELLO\nWORLD"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when note only have commands' do
|
||||||
|
it 'adds commands applied message to note errors' do
|
||||||
|
note_text = %(/close)
|
||||||
|
service = double(:service)
|
||||||
|
allow(Issues::UpdateService).to receive(:new).and_return(service)
|
||||||
|
expect(service).to receive(:execute)
|
||||||
|
|
||||||
|
note = described_class.new(project, user, opts.merge(note: note_text)).execute
|
||||||
|
|
||||||
|
expect(note.errors[:commands_only]).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'as a user who cannot update the target' do
|
context 'as a user who cannot update the target' do
|
||||||
|
|
|
@ -28,8 +28,8 @@ describe Notes::QuickActionsService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'closes noteable, sets labels, assigns, and sets milestone to noteable, and leave no note' do
|
it 'closes noteable, sets labels, assigns, and sets milestone to noteable, and leave no note' do
|
||||||
content, command_params = service.extract_commands(note)
|
content, update_params = service.execute(note)
|
||||||
service.execute(command_params, note)
|
service.apply_updates(update_params, note)
|
||||||
|
|
||||||
expect(content).to eq ''
|
expect(content).to eq ''
|
||||||
expect(note.noteable).to be_closed
|
expect(note.noteable).to be_closed
|
||||||
|
@ -47,8 +47,8 @@ describe Notes::QuickActionsService do
|
||||||
let(:note_text) { '/reopen' }
|
let(:note_text) { '/reopen' }
|
||||||
|
|
||||||
it 'opens the noteable, and leave no note' do
|
it 'opens the noteable, and leave no note' do
|
||||||
content, command_params = service.extract_commands(note)
|
content, update_params = service.execute(note)
|
||||||
service.execute(command_params, note)
|
service.apply_updates(update_params, note)
|
||||||
|
|
||||||
expect(content).to eq ''
|
expect(content).to eq ''
|
||||||
expect(note.noteable).to be_open
|
expect(note.noteable).to be_open
|
||||||
|
@ -59,8 +59,8 @@ describe Notes::QuickActionsService do
|
||||||
let(:note_text) { '/spend 1h' }
|
let(:note_text) { '/spend 1h' }
|
||||||
|
|
||||||
it 'updates the spent time on the noteable' do
|
it 'updates the spent time on the noteable' do
|
||||||
content, command_params = service.extract_commands(note)
|
content, update_params = service.execute(note)
|
||||||
service.execute(command_params, note)
|
service.apply_updates(update_params, note)
|
||||||
|
|
||||||
expect(content).to eq ''
|
expect(content).to eq ''
|
||||||
expect(note.noteable.time_spent).to eq(3600)
|
expect(note.noteable.time_spent).to eq(3600)
|
||||||
|
@ -75,8 +75,8 @@ describe Notes::QuickActionsService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'closes noteable, sets labels, assigns, and sets milestone to noteable' do
|
it 'closes noteable, sets labels, assigns, and sets milestone to noteable' do
|
||||||
content, command_params = service.extract_commands(note)
|
content, update_params = service.execute(note)
|
||||||
service.execute(command_params, note)
|
service.apply_updates(update_params, note)
|
||||||
|
|
||||||
expect(content).to eq "HELLO\nWORLD"
|
expect(content).to eq "HELLO\nWORLD"
|
||||||
expect(note.noteable).to be_closed
|
expect(note.noteable).to be_closed
|
||||||
|
@ -94,8 +94,8 @@ describe Notes::QuickActionsService do
|
||||||
let(:note_text) { "HELLO\n/reopen\nWORLD" }
|
let(:note_text) { "HELLO\n/reopen\nWORLD" }
|
||||||
|
|
||||||
it 'opens the noteable' do
|
it 'opens the noteable' do
|
||||||
content, command_params = service.extract_commands(note)
|
content, update_params = service.execute(note)
|
||||||
service.execute(command_params, note)
|
service.apply_updates(update_params, note)
|
||||||
|
|
||||||
expect(content).to eq "HELLO\nWORLD"
|
expect(content).to eq "HELLO\nWORLD"
|
||||||
expect(note.noteable).to be_open
|
expect(note.noteable).to be_open
|
||||||
|
@ -190,8 +190,8 @@ describe Notes::QuickActionsService do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'adds only one assignee from the list' do
|
it 'adds only one assignee from the list' do
|
||||||
_, command_params = service.extract_commands(note)
|
_, update_params = service.execute(note)
|
||||||
service.execute(command_params, note)
|
service.apply_updates(update_params, note)
|
||||||
|
|
||||||
expect(note.noteable.assignees.count).to eq(1)
|
expect(note.noteable.assignees.count).to eq(1)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1526,5 +1526,15 @@ describe QuickActions::InterpretService do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "#commands_executed_count" do
|
||||||
|
it 'counts commands executed' do
|
||||||
|
content = "/close and \n/assign me and \n/title new title"
|
||||||
|
|
||||||
|
service.execute(content, issue)
|
||||||
|
|
||||||
|
expect(service.commands_executed_count).to eq(3)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue