Merge branch '20378-natural-sort-issue-numbers' into 'master'
Change issues sentence to use natural sorting Closes #20378 See merge request !7110
This commit is contained in:
commit
3ff8d8020e
5 changed files with 132 additions and 9 deletions
|
@ -56,11 +56,12 @@ module MergeRequestsHelper
|
|||
end
|
||||
|
||||
def issues_sentence(issues)
|
||||
# Sorting based on the `#123` or `group/project#123` reference will sort
|
||||
# local issues first.
|
||||
issues.map do |issue|
|
||||
# Issuable sorter will sort local issues, then issues from the same
|
||||
# namespace, then all other issues.
|
||||
issues = Gitlab::IssuableSorter.sort(@project, issues).map do |issue|
|
||||
issue.to_reference(@project)
|
||||
end.sort.to_sentence
|
||||
end
|
||||
issues.to_sentence
|
||||
end
|
||||
|
||||
def mr_closes_issues
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
title: Change issues list in MR to natural sorting
|
||||
merge_request: 7110
|
||||
author: Jeff Stubler
|
29
lib/gitlab/issuable_sorter.rb
Normal file
29
lib/gitlab/issuable_sorter.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
module Gitlab
|
||||
module IssuableSorter
|
||||
class << self
|
||||
def sort(project, issuables, &sort_key)
|
||||
grouped_items = issuables.group_by do |issuable|
|
||||
if issuable.project.id == project.id
|
||||
:project_ref
|
||||
elsif issuable.project.namespace.id == project.namespace.id
|
||||
:namespace_ref
|
||||
else
|
||||
:full_ref
|
||||
end
|
||||
end
|
||||
|
||||
natural_sort_issuables(grouped_items[:project_ref], project) +
|
||||
natural_sort_issuables(grouped_items[:namespace_ref], project) +
|
||||
natural_sort_issuables(grouped_items[:full_ref], project)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def natural_sort_issuables(issuables, project)
|
||||
VersionSorter.sort(issuables || []) do |issuable|
|
||||
issuable.to_reference(project)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -22,24 +22,51 @@ describe MergeRequestsHelper do
|
|||
end
|
||||
|
||||
describe '#issues_sentence' do
|
||||
let(:project) { create :project }
|
||||
|
||||
subject { issues_sentence(issues) }
|
||||
let(:issues) do
|
||||
[build(:issue, iid: 1), build(:issue, iid: 2), build(:issue, iid: 3)]
|
||||
[build(:issue, iid: 2, project: project),
|
||||
build(:issue, iid: 3, project: project),
|
||||
build(:issue, iid: 1, project: project)]
|
||||
end
|
||||
|
||||
it { is_expected.to eq('#1, #2, and #3') }
|
||||
it do
|
||||
@project = project
|
||||
|
||||
is_expected.to eq('#1, #2, and #3')
|
||||
end
|
||||
|
||||
context 'for JIRA issues' do
|
||||
let(:project) { create(:empty_project) }
|
||||
let(:issues) do
|
||||
[
|
||||
ExternalIssue.new('JIRA-123', project),
|
||||
ExternalIssue.new('JIRA-456', project),
|
||||
ExternalIssue.new('FOOBAR-7890', project)
|
||||
ExternalIssue.new('FOOBAR-7890', project),
|
||||
ExternalIssue.new('JIRA-123', project)
|
||||
]
|
||||
end
|
||||
|
||||
it { is_expected.to eq('FOOBAR-7890, JIRA-123, and JIRA-456') }
|
||||
it do
|
||||
@project = project
|
||||
is_expected.to eq('FOOBAR-7890, JIRA-123, and JIRA-456')
|
||||
end
|
||||
end
|
||||
|
||||
context 'for issues from multiple namespaces' do
|
||||
let(:project) { create(:project) }
|
||||
let(:other_project) { create(:project) }
|
||||
let(:issues) do
|
||||
[build(:issue, iid: 2, project: project),
|
||||
build(:issue, iid: 3, project: other_project),
|
||||
build(:issue, iid: 1, project: project)]
|
||||
end
|
||||
|
||||
it do
|
||||
@project = project
|
||||
|
||||
is_expected.to eq("#1, #2, and #{other_project.namespace.path}/#{other_project.path}#3")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
62
spec/lib/gitlab/issuable_sorter_spec.rb
Normal file
62
spec/lib/gitlab/issuable_sorter_spec.rb
Normal file
|
@ -0,0 +1,62 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Gitlab::IssuableSorter, lib: true do
|
||||
let(:namespace1) { build(:namespace, id: 1) }
|
||||
let(:project1) { build(:project, id: 1, namespace: namespace1) }
|
||||
|
||||
let(:project2) { build(:project, id: 2, path: "a", namespace: project1.namespace) }
|
||||
let(:project3) { build(:project, id: 3, path: "b", namespace: project1.namespace) }
|
||||
|
||||
let(:namespace2) { build(:namespace, id: 2, path: "a") }
|
||||
let(:namespace3) { build(:namespace, id: 3, path: "b") }
|
||||
let(:project4) { build(:project, id: 4, path: "a", namespace: namespace2) }
|
||||
let(:project5) { build(:project, id: 5, path: "b", namespace: namespace2) }
|
||||
let(:project6) { build(:project, id: 6, path: "a", namespace: namespace3) }
|
||||
|
||||
let(:unsorted) { [sorted[2], sorted[3], sorted[0], sorted[1]] }
|
||||
|
||||
let(:sorted) do
|
||||
[build(:issue, iid: 1, project: project1),
|
||||
build(:issue, iid: 2, project: project1),
|
||||
build(:issue, iid: 10, project: project1),
|
||||
build(:issue, iid: 20, project: project1)]
|
||||
end
|
||||
|
||||
it 'sorts references by a given key' do
|
||||
expect(described_class.sort(project1, unsorted)).to eq(sorted)
|
||||
end
|
||||
|
||||
context 'for JIRA issues' do
|
||||
let(:sorted) do
|
||||
[ExternalIssue.new('JIRA-1', project1),
|
||||
ExternalIssue.new('JIRA-2', project1),
|
||||
ExternalIssue.new('JIRA-10', project1),
|
||||
ExternalIssue.new('JIRA-20', project1)]
|
||||
end
|
||||
|
||||
it 'sorts references by a given key' do
|
||||
expect(described_class.sort(project1, unsorted)).to eq(sorted)
|
||||
end
|
||||
end
|
||||
|
||||
context 'for references from multiple projects and namespaces' do
|
||||
let(:sorted) do
|
||||
[build(:issue, iid: 1, project: project1),
|
||||
build(:issue, iid: 2, project: project1),
|
||||
build(:issue, iid: 10, project: project1),
|
||||
build(:issue, iid: 1, project: project2),
|
||||
build(:issue, iid: 1, project: project3),
|
||||
build(:issue, iid: 1, project: project4),
|
||||
build(:issue, iid: 1, project: project5),
|
||||
build(:issue, iid: 1, project: project6)]
|
||||
end
|
||||
let(:unsorted) do
|
||||
[sorted[3], sorted[1], sorted[4], sorted[2],
|
||||
sorted[6], sorted[5], sorted[0], sorted[7]]
|
||||
end
|
||||
|
||||
it 'sorts references by project and then by a given key' do
|
||||
expect(subject.sort(project1, unsorted)).to eq(sorted)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue