Commit 878ad484 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'matbaj/gitlab-ce-add-inherit-command' into 'master'

Add copy_metadata quick action

Closes #38450

See merge request gitlab-org/gitlab-ce!18497
parents 906fc00c 6a88ffb4
......@@ -270,6 +270,26 @@ module QuickActions
end
end
desc 'Copy labels and milestone from other issue or merge request'
explanation do |source_issuable|
"Copy labels and milestone from #{source_issuable.to_reference}."
end
params '#issue | !merge_request'
condition do
issuable.persisted? &&
current_user.can?(:"update_#{issuable.to_ability_name}", issuable)
end
parse_params do |issuable_param|
extract_references(issuable_param, :issue).first ||
extract_references(issuable_param, :merge_request).first
end
command :copy_metadata do |source_issuable|
if source_issuable.present? && source_issuable.project.id == issuable.project.id
@updates[:add_label_ids] = source_issuable.labels.map(&:id)
@updates[:milestone_id] = source_issuable.milestone.id if source_issuable.milestone
end
end
desc 'Add a todo'
explanation 'Adds a todo.'
condition do
......
---
title: Add Copy metadata quick action
merge_request: 16473
author: Mateusz Bajorski
type: added
......@@ -38,6 +38,7 @@ do.
| `/award :emoji:` | Toggle award for :emoji: |
| `/board_move ~column` | Move issue to column on the board |
| `/duplicate #issue` | Closes this issue and marks it as a duplicate of another issue |
| `/move path/to/project` | Moves issue to another project |
| `/tableflip` | Append the comment with `(╯°□°)╯︵ ┻━┻` |
| `/shrug` | Append the comment with `¯\_(ツ)_/¯` |
\ No newline at end of file
| `/move path/to/project` | Moves issue to another project |
| `/tableflip` | Append the comment with `(╯°□°)╯︵ ┻━┻` |
| `/shrug` | Append the comment with `¯\_(ツ)_/¯` |
| <code>/copy_metadata #issue &#124; !merge_request</code> | Copy labels and milestone from other issue or merge request |
......@@ -306,6 +306,23 @@ describe QuickActions::InterpretService do
end
end
shared_examples 'copy_metadata command' do
it 'fetches issue or merge request and copies labels and milestone if content contains /copy_metadata reference' do
source_issuable # populate the issue
todo_label # populate this label
inreview_label # populate this label
_, updates = service.execute(content, issuable)
expect(updates[:add_label_ids]).to match_array([inreview_label.id, todo_label.id])
if source_issuable.milestone
expect(updates[:milestone_id]).to eq(source_issuable.milestone.id)
else
expect(updates).not_to have_key(:milestone_id)
end
end
end
shared_examples 'shrug command' do
it 'appends ¯\_(ツ)_/¯ to the comment' do
new_content, _ = service.execute(content, issuable)
......@@ -757,6 +774,65 @@ describe QuickActions::InterpretService do
let(:issuable) { issue }
end
context '/copy_metadata command' do
let(:todo_label) { create(:label, project: project, title: 'To Do') }
let(:inreview_label) { create(:label, project: project, title: 'In Review') }
it_behaves_like 'empty command' do
let(:content) { '/copy_metadata' }
let(:issuable) { issue }
end
it_behaves_like 'copy_metadata command' do
let(:source_issuable) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) }
let(:content) { "/copy_metadata #{source_issuable.to_reference}" }
let(:issuable) { issue }
end
context 'when the parent issuable has a milestone' do
it_behaves_like 'copy_metadata command' do
let(:source_issuable) { create(:labeled_issue, project: project, labels: [todo_label, inreview_label], milestone: milestone) }
let(:content) { "/copy_metadata #{source_issuable.to_reference(project)}" }
let(:issuable) { issue }
end
end
context 'when more than one issuable is passed' do
it_behaves_like 'copy_metadata command' do
let(:source_issuable) { create(:labeled_issue, project: project, labels: [inreview_label, todo_label]) }
let(:other_label) { create(:label, project: project, title: 'Other') }
let(:other_source_issuable) { create(:labeled_issue, project: project, labels: [other_label]) }
let(:content) { "/copy_metadata #{source_issuable.to_reference} #{other_source_issuable.to_reference}" }
let(:issuable) { issue }
end
end
context 'cross project references' do
it_behaves_like 'empty command' do
let(:other_project) { create(:project, :public) }
let(:source_issuable) { create(:labeled_issue, project: other_project, labels: [todo_label, inreview_label]) }
let(:content) { "/copy_metadata #{source_issuable.to_reference(project)}" }
let(:issuable) { issue }
end
it_behaves_like 'empty command' do
let(:content) { "/copy_metadata imaginary#1234" }
let(:issuable) { issue }
end
it_behaves_like 'empty command' do
let(:other_project) { create(:project, :private) }
let(:source_issuable) { create(:issue, project: other_project) }
let(:content) { "/copy_metadata #{source_issuable.to_reference(project)}" }
let(:issuable) { issue }
end
end
end
context '/duplicate command' do
it_behaves_like 'duplicate command' do
let(:issue_duplicate) { create(:issue, project: project) }
......
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