Merge branch 'jprovazn-project-search' into 'master'

Order projects by name in the "Move issue" dropdown

See merge request gitlab-org/gitlab-ce!30778
This commit is contained in:
James Lopez 2019-07-22 11:44:22 +00:00
commit 86e002147c
6 changed files with 23 additions and 90 deletions

View file

@ -3,7 +3,9 @@
module Autocomplete
# Finder that retrieves a list of projects that an issue can be moved to.
class MoveToProjectFinder
attr_reader :current_user, :search, :project_id, :offset_id
attr_reader :current_user, :search, :project_id
LIMIT = 20
# current_user - The User object of the user that wants to view the list of
# projects.
@ -14,13 +16,10 @@ module Autocomplete
#
# * search: An optional search query to apply to the list of projects.
# * project_id: The ID of a project to exclude from the returned relation.
# * offset_id: The ID of a project to use for pagination. When given, only
# projects with a lower ID are included in the list.
def initialize(current_user, params = {})
@current_user = current_user
@search = params[:search]
@project_id = params[:project_id]
@offset_id = params[:offset_id]
end
def execute
@ -28,8 +27,8 @@ module Autocomplete
.projects_where_can_admin_issues
.optionally_search(search)
.excluding_project(project_id)
.paginate_in_descending_order_using_id(before: offset_id)
.eager_load_namespace_and_owner
.sorted_by_name_asc_limited(LIMIT)
end
end
end

View file

@ -357,6 +357,7 @@ class Project < ApplicationRecord
scope :sorted_by_activity, -> { reorder(Arel.sql("GREATEST(COALESCE(last_activity_at, '1970-01-01'), COALESCE(last_repository_updated_at, '1970-01-01')) DESC")) }
scope :sorted_by_stars_desc, -> { reorder(star_count: :desc) }
scope :sorted_by_stars_asc, -> { reorder(star_count: :asc) }
scope :sorted_by_name_asc_limited, ->(limit) { reorder(name: :asc).limit(limit) }
scope :in_namespace, ->(namespace_ids) { where(namespace_id: namespace_ids) }
scope :personal, ->(user) { where(namespace_id: user.namespace_id) }
@ -441,22 +442,6 @@ class Project < ApplicationRecord
without_deleted.find_by_id(id)
end
# Paginates a collection using a `WHERE id < ?` condition.
#
# before - A project ID to use for filtering out projects with an equal or
# greater ID. If no ID is given, all projects are included.
#
# limit - The maximum number of rows to include.
def self.paginate_in_descending_order_using_id(
before: nil,
limit: Kaminari.config.default_per_page
)
relation = order_id_desc.limit(limit)
relation = relation.where('projects.id < ?', before) if before
relation
end
def self.eager_load_namespace_and_owner
includes(namespace: :owner)
end

View file

@ -0,0 +1,5 @@
---
title: Order projects in 'Move issue' dropdown by name.
merge_request: 30778
author:
type: fixed

View file

@ -295,28 +295,6 @@ describe AutocompleteController do
end
end
context 'authorized projects with offset' do
before do
authorized_project2 = create(:project)
authorized_project3 = create(:project)
authorized_project.add_maintainer(user)
authorized_project2.add_maintainer(user)
authorized_project3.add_maintainer(user)
end
describe 'GET #projects with project ID and offset_id' do
before do
get(:projects, params: { project_id: project.id, offset_id: authorized_project.id })
end
it 'returns projects' do
expect(json_response).to be_kind_of(Array)
expect(json_response.size).to eq 2 # Of a total of 3
end
end
end
context 'authorized projects without admin_issue ability' do
before do
authorized_project.add_guest(user)

View file

@ -6,9 +6,9 @@ describe Autocomplete::MoveToProjectFinder do
let(:no_access_project) { create(:project) }
let(:guest_project) { create(:project) }
let(:reporter_project) { create(:project) }
let(:developer_project) { create(:project) }
let(:maintainer_project) { create(:project) }
let(:reporter_project) { create(:project, name: 'name') }
let(:developer_project) { create(:project, name: 'name2') }
let(:maintainer_project) { create(:project, name: 'name3') }
describe '#execute' do
context 'filter' do
@ -20,14 +20,14 @@ describe Autocomplete::MoveToProjectFinder do
expect(finder.execute).to be_empty
end
it 'returns projects equal or above Gitlab::Access::REPORTER ordered by id in descending order' do
it 'returns projects equal or above Gitlab::Access::REPORTER ordered by name' do
reporter_project.add_reporter(user)
developer_project.add_developer(user)
maintainer_project.add_maintainer(user)
finder = described_class.new(user, project_id: project.id)
expect(finder.execute.to_a).to eq([maintainer_project, developer_project, reporter_project])
expect(finder.execute.to_a).to eq([reporter_project, developer_project, maintainer_project])
end
it 'does not include the source project' do
@ -60,46 +60,32 @@ describe Autocomplete::MoveToProjectFinder do
expect(finder.execute.to_a).to eq([other_reporter_project])
end
it 'returns a page of projects ordered by id in descending order' do
allow(Kaminari.config).to receive(:default_per_page).and_return(2)
it 'returns a page of projects ordered by name' do
stub_const('Autocomplete::MoveToProjectFinder::LIMIT', 2)
projects = create_list(:project, 2) do |project|
projects = create_list(:project, 3) do |project|
project.add_developer(user)
end
finder = described_class.new(user, project_id: project.id)
page = finder.execute.to_a
expect(page.length).to eq(Kaminari.config.default_per_page)
expect(page[0]).to eq(projects.last)
end
it 'returns projects after the given offset id' do
reporter_project.add_reporter(user)
developer_project.add_developer(user)
maintainer_project.add_maintainer(user)
expect(described_class.new(user, project_id: project.id, offset_id: maintainer_project.id).execute.to_a)
.to eq([developer_project, reporter_project])
expect(described_class.new(user, project_id: project.id, offset_id: developer_project.id).execute.to_a)
.to eq([reporter_project])
expect(described_class.new(user, project_id: project.id, offset_id: reporter_project.id).execute.to_a)
.to be_empty
expected_projects = projects.sort_by(&:name).first(2)
expect(page.length).to eq(2)
expect(page).to eq(expected_projects)
end
end
context 'search' do
it 'returns projects matching a search query' do
foo_project = create(:project)
foo_project = create(:project, name: 'foo')
foo_project.add_maintainer(user)
wadus_project = create(:project, name: 'wadus')
wadus_project.add_maintainer(user)
expect(described_class.new(user, project_id: project.id).execute.to_a)
.to eq([wadus_project, foo_project])
.to eq([foo_project, wadus_project])
expect(described_class.new(user, project_id: project.id, search: 'wadus').execute.to_a)
.to eq([wadus_project])

View file

@ -1675,26 +1675,6 @@ describe Project do
end
end
describe '.paginate_in_descending_order_using_id' do
let!(:project1) { create(:project) }
let!(:project2) { create(:project) }
it 'orders the relation in descending order' do
expect(described_class.paginate_in_descending_order_using_id)
.to eq([project2, project1])
end
it 'applies a limit to the relation' do
expect(described_class.paginate_in_descending_order_using_id(limit: 1))
.to eq([project2])
end
it 'limits projects by and ID when given' do
expect(described_class.paginate_in_descending_order_using_id(before: project2.id))
.to eq([project1])
end
end
describe '.including_namespace_and_owner' do
it 'eager loads the namespace and namespace owner' do
create(:project)