Commit 07cc1885 authored by Sean McGivern's avatar Sean McGivern

Merge branch...

Merge branch '53459-quick-action-adds-multiple-labels-to-issue-if-middle-words-overlap-with-existing-label' into 'master'

Resolve "Quick Action Adds Multiple Labels to Issue If Middle Words Overlap with Existing Label"

Closes #53459

See merge request gitlab-org/gitlab-ce!26602
parents 128871be 3bc30185
...@@ -96,14 +96,27 @@ module QuickActions ...@@ -96,14 +96,27 @@ module QuickActions
end end
def find_labels(labels_params = nil) def find_labels(labels_params = nil)
extract_references(labels_params, :label) | find_labels_by_name_no_tilde(labels_params)
end
def find_labels_by_name_no_tilde(labels_params)
return Label.none if label_with_tilde?(labels_params)
finder_params = { include_ancestor_groups: true } finder_params = { include_ancestor_groups: true }
finder_params[:project_id] = project.id if project finder_params[:project_id] = project.id if project
finder_params[:group_id] = group.id if group finder_params[:group_id] = group.id if group
finder_params[:name] = labels_params.split if labels_params finder_params[:name] = extract_label_names(labels_params) if labels_params
result = LabelsFinder.new(current_user, finder_params).execute LabelsFinder.new(current_user, finder_params).execute
end
def label_with_tilde?(labels_params)
labels_params&.include?('~')
end
extract_references(labels_params, :label) | result def extract_label_names(labels_params)
# '"A" "A B C" A B' => ["A", "A B C", "A", "B"]
labels_params.scan(/"([^"]+)"|([^ ]+)/).flatten.compact
end end
def find_label_references(labels_param) def find_label_references(labels_param)
......
---
title: Fix quick actions add label name middle word overlaps
merge_request: 26602
author: Jacopo Beschi @jacopo-beschi
type: fixed
...@@ -31,7 +31,7 @@ discussions, and descriptions: ...@@ -31,7 +31,7 @@ discussions, and descriptions:
| `/reassign @user1 @user2` | Change assignee | ✓ | ✓ | | `/reassign @user1 @user2` | Change assignee | ✓ | ✓ |
| `/milestone %milestone` | Set milestone | ✓ | ✓ | | `/milestone %milestone` | Set milestone | ✓ | ✓ |
| `/remove_milestone` | Remove milestone | ✓ | ✓ | | `/remove_milestone` | Remove milestone | ✓ | ✓ |
| `/label ~label1 ~label2` | Add label(s) | ✓ | ✓ | | `/label ~label1 ~label2` | Add label(s). Label names can also start without ~ but mixed syntax is not supported. | ✓ | ✓ |
| `/unlabel ~label1 ~label2` | Remove all or specific label(s)| ✓ | ✓ | | `/unlabel ~label1 ~label2` | Remove all or specific label(s)| ✓ | ✓ |
| `/relabel ~label1 ~label2` | Replace label | ✓ | ✓ | | `/relabel ~label1 ~label2` | Replace label | ✓ | ✓ |
| <code>/copy_metadata #issue &#124; !merge_request</code> | Copy labels and milestone from other issue or merge request | ✓ | ✓ | | <code>/copy_metadata #issue &#124; !merge_request</code> | Copy labels and milestone from other issue or merge request | ✓ | ✓ |
......
...@@ -10,6 +10,7 @@ describe QuickActions::InterpretService do ...@@ -10,6 +10,7 @@ describe QuickActions::InterpretService do
let(:milestone) { create(:milestone, project: project, title: '9.10') } let(:milestone) { create(:milestone, project: project, title: '9.10') }
let(:commit) { create(:commit, project: project) } let(:commit) { create(:commit, project: project) }
let(:inprogress) { create(:label, project: project, title: 'In Progress') } let(:inprogress) { create(:label, project: project, title: 'In Progress') }
let(:helmchart) { create(:label, project: project, title: 'Helm Chart Registry') }
let(:bug) { create(:label, project: project, title: 'Bug') } let(:bug) { create(:label, project: project, title: 'Bug') }
let(:note) { build(:note, commit_id: merge_request.diff_head_sha) } let(:note) { build(:note, commit_id: merge_request.diff_head_sha) }
let(:service) { described_class.new(project, developer) } let(:service) { described_class.new(project, developer) }
...@@ -94,6 +95,26 @@ describe QuickActions::InterpretService do ...@@ -94,6 +95,26 @@ describe QuickActions::InterpretService do
end end
end end
shared_examples 'multiword label name starting without ~' do
it 'fetches label ids and populates add_label_ids if content contains /label' do
helmchart # populate the label
_, updates = service.execute(content, issuable)
expect(updates).to eq(add_label_ids: [helmchart.id])
end
end
shared_examples 'label name is included in the middle of another label name' do
it 'ignores the sublabel when the content contains the includer label name' do
helmchart # populate the label
create(:label, project: project, title: 'Chart')
_, updates = service.execute(content, issuable)
expect(updates).to eq(add_label_ids: [helmchart.id])
end
end
shared_examples 'unlabel command' do shared_examples 'unlabel command' do
it 'fetches label ids and populates remove_label_ids if content contains /unlabel' do it 'fetches label ids and populates remove_label_ids if content contains /unlabel' do
issuable.update!(label_ids: [inprogress.id]) # populate the label issuable.update!(label_ids: [inprogress.id]) # populate the label
...@@ -624,6 +645,26 @@ describe QuickActions::InterpretService do ...@@ -624,6 +645,26 @@ describe QuickActions::InterpretService do
let(:issuable) { issue } let(:issuable) { issue }
end end
it_behaves_like 'multiword label name starting without ~' do
let(:content) { %(/label "#{helmchart.title}") }
let(:issuable) { issue }
end
it_behaves_like 'multiword label name starting without ~' do
let(:content) { %(/label "#{helmchart.title}") }
let(:issuable) { merge_request }
end
it_behaves_like 'label name is included in the middle of another label name' do
let(:content) { %(/label ~"#{helmchart.title}") }
let(:issuable) { issue }
end
it_behaves_like 'label name is included in the middle of another label name' do
let(:content) { %(/label ~"#{helmchart.title}") }
let(:issuable) { merge_request }
end
it_behaves_like 'unlabel command' do it_behaves_like 'unlabel command' do
let(:content) { %(/unlabel ~"#{inprogress.title}") } let(:content) { %(/unlabel ~"#{inprogress.title}") }
let(:issuable) { issue } let(:issuable) { issue }
......
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