GitLab steht wegen Wartungsarbeiten am Montag, den 10. Mai, zwischen 17:00 und 19:00 Uhr nicht zur Verfügung.

Commit 78dc1b58 authored by Felipe Artur's avatar Felipe Artur Committed by Sean McGivern

Show commands applied message when promoting issues

Fix 'commands applied' messages not being shown when issue is promoted to epic
using slash commands.
parent 4b0036b8
...@@ -21,7 +21,7 @@ def execute ...@@ -21,7 +21,7 @@ def execute
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 @@ def execute ...@@ -43,16 +43,17 @@ def execute
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
......
# 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 @@ def supported?(note) ...@@ -25,18 +36,21 @@ def supported?(note)
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 @@ class InterpretService < BaseService ...@@ -7,6 +7,11 @@ class InterpretService < BaseService
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 @@ def explain(context, arg) ...@@ -48,6 +48,8 @@ def explain(context, arg)
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 @@ def to_h(context) ...@@ -73,6 +75,13 @@ def to_h(context)
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 @@ ...@@ -243,7 +243,9 @@
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 @@ ...@@ -72,7 +72,7 @@
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 @@ ...@@ -80,6 +80,7 @@
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 @@ ...@@ -97,6 +98,7 @@
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 @@ ...@@ -112,6 +114,7 @@
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 @@ ...@@ -120,6 +123,7 @@
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 @@ ...@@ -134,6 +138,7 @@
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 @@ ...@@ -220,6 +220,19 @@
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 @@ ...@@ -28,8 +28,8 @@
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 @@ ...@@ -47,8 +47,8 @@
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 @@ ...@@ -59,8 +59,8 @@
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 @@ ...@@ -75,8 +75,8 @@
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 @@ ...@@ -94,8 +94,8 @@
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 @@ ...@@ -190,8 +190,8 @@
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 @@ ...@@ -1526,5 +1526,15 @@
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
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment