Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
cf21118f
Commit
cf21118f
authored
Feb 19, 2019
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab-ce master
parents
d0e7914f
9b581d41
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
187 additions
and
28 deletions
+187
-28
app/validators/url_validator.rb
app/validators/url_validator.rb
+1
-1
changelogs/unreleased/54796-api-sort-tie-breaker-for-pagination.yml
.../unreleased/54796-api-sort-tie-breaker-for-pagination.yml
+5
-0
doc/user/admin_area/settings/index.md
doc/user/admin_area/settings/index.md
+4
-0
lib/api/helpers.rb
lib/api/helpers.rb
+7
-1
lib/api/issues.rb
lib/api/issues.rb
+1
-2
lib/api/merge_requests.rb
lib/api/merge_requests.rb
+1
-1
lib/api/notes.rb
lib/api/notes.rb
+1
-1
lib/api/users.rb
lib/api/users.rb
+1
-1
spec/lib/gitlab/current_settings_spec.rb
spec/lib/gitlab/current_settings_spec.rb
+3
-4
spec/models/lfs_download_object_spec.rb
spec/models/lfs_download_object_spec.rb
+1
-3
spec/requests/api/issues_spec.rb
spec/requests/api/issues_spec.rb
+93
-9
spec/support/shared_examples/requests/api/merge_requests_list.rb
...pport/shared_examples/requests/api/merge_requests_list.rb
+32
-0
spec/support/shared_examples/requests/api/notes.rb
spec/support/shared_examples/requests/api/notes.rb
+37
-5
No files found.
app/validators/url_validator.rb
View file @
cf21118f
...
@@ -93,6 +93,6 @@ class UrlValidator < ActiveModel::EachValidator
...
@@ -93,6 +93,6 @@ class UrlValidator < ActiveModel::EachValidator
end
end
def
allow_setting_local_requests?
def
allow_setting_local_requests?
ApplicationSetting
.
current
&
.
allow_local_requests_from_hooks_and_services?
Gitlab
::
CurrentSettings
.
allow_local_requests_from_hooks_and_services?
end
end
end
end
changelogs/unreleased/54796-api-sort-tie-breaker-for-pagination.yml
0 → 100644
View file @
cf21118f
---
title
:
'
API:
Sort
tie
breaker
with
id
DESC'
merge_request
:
25311
author
:
Nermin Vehabovic
type
:
changed
doc/user/admin_area/settings/index.md
View file @
cf21118f
...
@@ -15,6 +15,10 @@ include:
...
@@ -15,6 +15,10 @@ include:
-
[
Visibility and access controls
](
visibility_and_access_controls.md
)
-
[
Visibility and access controls
](
visibility_and_access_controls.md
)
-
[
Custom templates repository
](
instance_template_repository.md
)
-
[
Custom templates repository
](
instance_template_repository.md
)
NOTE:
**Note:**
You can change the
[
first day of the week
](
../../profile/preferences.md
)
for the entire GitLab instance
in the
**Localization**
section of
**Admin area > Settings > Preferences**
.
## GitLab.com admin area settings
## GitLab.com admin area settings
Most of the settings under the admin area change the behavior of the whole
Most of the settings under the admin area change the behavior of the whole
...
...
lib/api/helpers.rb
View file @
cf21118f
...
@@ -312,6 +312,12 @@ module API
...
@@ -312,6 +312,12 @@ module API
items
.
search
(
text
)
items
.
search
(
text
)
end
end
def
order_options_with_tie_breaker
order_options
=
{
params
[
:order_by
]
=>
params
[
:sort
]
}
order_options
[
'id'
]
||=
'desc'
order_options
end
# error helpers
# error helpers
def
forbidden!
(
reason
=
nil
)
def
forbidden!
(
reason
=
nil
)
...
@@ -406,7 +412,7 @@ module API
...
@@ -406,7 +412,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
reorder_projects
(
projects
)
def
reorder_projects
(
projects
)
projects
.
reorder
(
params
[
:order_by
]
=>
params
[
:sort
]
)
projects
.
reorder
(
order_options_with_tie_breaker
)
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
...
...
lib/api/issues.rb
View file @
cf21118f
...
@@ -31,8 +31,7 @@ module API
...
@@ -31,8 +31,7 @@ module API
issues
=
IssuesFinder
.
new
(
current_user
,
args
).
execute
issues
=
IssuesFinder
.
new
(
current_user
,
args
).
execute
.
preload
(
:assignees
,
:labels
,
:notes
,
:timelogs
,
:project
,
:author
,
:closed_by
)
.
preload
(
:assignees
,
:labels
,
:notes
,
:timelogs
,
:project
,
:author
,
:closed_by
)
issues
.
reorder
(
order_options_with_tie_breaker
)
issues
.
reorder
(
args
[
:order_by
]
=>
args
[
:sort
])
end
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: enable CodeReuse/ActiveRecord
...
...
lib/api/merge_requests.rb
View file @
cf21118f
...
@@ -40,7 +40,7 @@ module API
...
@@ -40,7 +40,7 @@ module API
args
[
:scope
]
=
args
[
:scope
].
underscore
if
args
[
:scope
]
args
[
:scope
]
=
args
[
:scope
].
underscore
if
args
[
:scope
]
merge_requests
=
MergeRequestsFinder
.
new
(
current_user
,
args
).
execute
merge_requests
=
MergeRequestsFinder
.
new
(
current_user
,
args
).
execute
.
reorder
(
args
[
:order_by
]
=>
args
[
:sort
]
)
.
reorder
(
order_options_with_tie_breaker
)
merge_requests
=
paginate
(
merge_requests
)
merge_requests
=
paginate
(
merge_requests
)
.
preload
(
:source_project
,
:target_project
)
.
preload
(
:source_project
,
:target_project
)
...
...
lib/api/notes.rb
View file @
cf21118f
...
@@ -39,7 +39,7 @@ module API
...
@@ -39,7 +39,7 @@ module API
# at the DB query level (which we cannot in that case), the current
# at the DB query level (which we cannot in that case), the current
# page can have less elements than :per_page even if
# page can have less elements than :per_page even if
# there's more than one page.
# there's more than one page.
raw_notes
=
noteable
.
notes
.
with_metadata
.
reorder
(
params
[
:order_by
]
=>
params
[
:sort
]
)
raw_notes
=
noteable
.
notes
.
with_metadata
.
reorder
(
order_options_with_tie_breaker
)
notes
=
notes
=
# paginate() only works with a relation. This could lead to a
# paginate() only works with a relation. This could lead to a
# mismatch between the pagination headers info and the actual notes
# mismatch between the pagination headers info and the actual notes
...
...
lib/api/users.rb
View file @
cf21118f
...
@@ -26,7 +26,7 @@ module API
...
@@ -26,7 +26,7 @@ module API
# rubocop: disable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def
reorder_users
(
users
)
def
reorder_users
(
users
)
if
params
[
:order_by
]
&&
params
[
:sort
]
if
params
[
:order_by
]
&&
params
[
:sort
]
users
.
reorder
(
params
[
:order_by
]
=>
params
[
:sort
]
)
users
.
reorder
(
order_options_with_tie_breaker
)
else
else
users
users
end
end
...
...
spec/lib/gitlab/current_settings_spec.rb
View file @
cf21118f
...
@@ -14,9 +14,8 @@ describe Gitlab::CurrentSettings do
...
@@ -14,9 +14,8 @@ describe Gitlab::CurrentSettings do
describe
'#current_application_settings'
,
:use_clean_rails_memory_store_caching
do
describe
'#current_application_settings'
,
:use_clean_rails_memory_store_caching
do
it
'allows keys to be called directly'
do
it
'allows keys to be called directly'
do
db_settings
=
create
(
:application_setting
,
db_settings
=
ApplicationSetting
.
first
||
create
(
:application_setting
)
home_page_url:
'http://mydomain.com'
,
db_settings
.
update!
(
home_page_url:
'http://mydomain.com'
,
signup_enabled:
false
)
signup_enabled:
false
)
expect
(
described_class
.
home_page_url
).
to
eq
(
db_settings
.
home_page_url
)
expect
(
described_class
.
home_page_url
).
to
eq
(
db_settings
.
home_page_url
)
expect
(
described_class
.
signup_enabled?
).
to
be_falsey
expect
(
described_class
.
signup_enabled?
).
to
be_falsey
...
@@ -109,7 +108,7 @@ describe Gitlab::CurrentSettings do
...
@@ -109,7 +108,7 @@ describe Gitlab::CurrentSettings do
context
'with pending migrations'
do
context
'with pending migrations'
do
before
do
before
do
expect
(
ActiveRecord
::
Migrator
).
to
receive
(
:needs_migration?
).
and_return
(
true
)
allow
(
ActiveRecord
::
Migrator
).
to
receive
(
:needs_migration?
).
and_return
(
true
)
end
end
shared_examples
'a non-persisted ApplicationSetting object'
do
shared_examples
'a non-persisted ApplicationSetting object'
do
...
...
spec/models/lfs_download_object_spec.rb
View file @
cf21118f
...
@@ -46,9 +46,7 @@ describe LfsDownloadObject do
...
@@ -46,9 +46,7 @@ describe LfsDownloadObject do
subject
{
described_class
.
new
(
oid:
oid
,
size:
size
,
link:
'http://192.168.1.1'
)
}
subject
{
described_class
.
new
(
oid:
oid
,
size:
size
,
link:
'http://192.168.1.1'
)
}
before
do
before
do
allow
(
ApplicationSetting
)
stub_application_setting
(
allow_local_requests_from_hooks_and_services:
setting
)
.
to
receive
(
:current
)
.
and_return
(
ApplicationSetting
.
build_from_defaults
(
allow_local_requests_from_hooks_and_services:
setting
))
end
end
context
'are allowed'
do
context
'are allowed'
do
...
...
spec/requests/api/issues_spec.rb
View file @
cf21118f
...
@@ -363,10 +363,38 @@ describe API::Issues do
...
@@ -363,10 +363,38 @@ describe API::Issues do
expect_paginated_array_response
([])
expect_paginated_array_response
([])
end
end
it
'sorts by created_at descending by default'
do
context
'without sort params'
do
get
api
(
'/issues'
,
user
)
it
'sorts by created_at descending by default'
do
get
api
(
'/issues'
,
user
)
expect_paginated_array_response
([
issue
.
id
,
closed_issue
.
id
])
expect_paginated_array_response
([
issue
.
id
,
closed_issue
.
id
])
end
context
'with 2 issues with same created_at'
do
let!
(
:closed_issue2
)
do
create
:closed_issue
,
author:
user
,
assignees:
[
user
],
project:
project
,
milestone:
milestone
,
created_at:
closed_issue
.
created_at
,
updated_at:
1
.
hour
.
ago
,
title:
issue_title
,
description:
issue_description
end
it
'page breaks first page correctly'
do
get
api
(
'/issues?per_page=2'
,
user
)
expect_paginated_array_response
([
issue
.
id
,
closed_issue2
.
id
])
end
it
'page breaks second page correctly'
do
get
api
(
'/issues?per_page=2&page=2'
,
user
)
expect_paginated_array_response
([
closed_issue
.
id
])
end
end
end
end
it
'sorts ascending when requested'
do
it
'sorts ascending when requested'
do
...
@@ -617,10 +645,38 @@ describe API::Issues do
...
@@ -617,10 +645,38 @@ describe API::Issues do
expect_paginated_array_response
(
group_confidential_issue
.
id
)
expect_paginated_array_response
(
group_confidential_issue
.
id
)
end
end
it
'sorts by created_at descending by default'
do
context
'without sort params'
do
get
api
(
base_url
,
user
)
it
'sorts by created_at descending by default'
do
get
api
(
base_url
,
user
)
expect_paginated_array_response
([
group_closed_issue
.
id
,
group_confidential_issue
.
id
,
group_issue
.
id
])
expect_paginated_array_response
([
group_closed_issue
.
id
,
group_confidential_issue
.
id
,
group_issue
.
id
])
end
context
'with 2 issues with same created_at'
do
let!
(
:group_issue2
)
do
create
:issue
,
author:
user
,
assignees:
[
user
],
project:
group_project
,
milestone:
group_milestone
,
updated_at:
1
.
hour
.
ago
,
title:
issue_title
,
description:
issue_description
,
created_at:
group_issue
.
created_at
end
it
'page breaks first page correctly'
do
get
api
(
"
#{
base_url
}
?per_page=3"
,
user
)
expect_paginated_array_response
([
group_closed_issue
.
id
,
group_confidential_issue
.
id
,
group_issue2
.
id
])
end
it
'page breaks second page correctly'
do
get
api
(
"
#{
base_url
}
?per_page=3&page=2"
,
user
)
expect_paginated_array_response
([
group_issue
.
id
])
end
end
end
end
it
'sorts ascending when requested'
do
it
'sorts ascending when requested'
do
...
@@ -832,10 +888,38 @@ describe API::Issues do
...
@@ -832,10 +888,38 @@ describe API::Issues do
expect_paginated_array_response
([
issue
.
id
,
closed_issue
.
id
])
expect_paginated_array_response
([
issue
.
id
,
closed_issue
.
id
])
end
end
it
'sorts by created_at descending by default'
do
context
'without sort params'
do
get
api
(
"
#{
base_url
}
/issues"
,
user
)
it
'sorts by created_at descending by default'
do
get
api
(
"
#{
base_url
}
/issues"
,
user
)
expect_paginated_array_response
([
issue
.
id
,
confidential_issue
.
id
,
closed_issue
.
id
])
expect_paginated_array_response
([
issue
.
id
,
confidential_issue
.
id
,
closed_issue
.
id
])
end
context
'with 2 issues with same created_at'
do
let!
(
:closed_issue2
)
do
create
:closed_issue
,
author:
user
,
assignees:
[
user
],
project:
project
,
milestone:
milestone
,
created_at:
closed_issue
.
created_at
,
updated_at:
1
.
hour
.
ago
,
title:
issue_title
,
description:
issue_description
end
it
'page breaks first page correctly'
do
get
api
(
"
#{
base_url
}
/issues?per_page=3"
,
user
)
expect_paginated_array_response
([
issue
.
id
,
confidential_issue
.
id
,
closed_issue2
.
id
])
end
it
'page breaks second page correctly'
do
get
api
(
"
#{
base_url
}
/issues?per_page=3&page=2"
,
user
)
expect_paginated_array_response
([
closed_issue
.
id
])
end
end
end
end
it
'sorts ascending when requested'
do
it
'sorts ascending when requested'
do
...
...
spec/support/shared_examples/requests/api/merge_requests_list.rb
View file @
cf21118f
...
@@ -257,6 +257,38 @@ shared_examples 'merge requests list' do
...
@@ -257,6 +257,38 @@ shared_examples 'merge requests list' do
expect
(
response_dates
).
to
eq
(
response_dates
.
sort
.
reverse
)
expect
(
response_dates
).
to
eq
(
response_dates
.
sort
.
reverse
)
end
end
context
'2 merge requests with equal created_at'
do
let!
(
:closed_mr2
)
do
create
:merge_request
,
state:
'closed'
,
milestone:
milestone1
,
author:
user
,
assignee:
user
,
source_project:
project
,
target_project:
project
,
title:
"Test"
,
created_at:
@mr_earlier
.
created_at
end
it
'page breaks first page correctly'
do
get
api
(
"
#{
endpoint_path
}
?sort=desc&per_page=4"
,
user
)
response_ids
=
json_response
.
map
{
|
merge_request
|
merge_request
[
'id'
]
}
expect
(
response_ids
).
to
include
(
closed_mr2
.
id
)
expect
(
response_ids
).
not_to
include
(
@mr_earlier
.
id
)
end
it
'page breaks second page correctly'
do
get
api
(
"
#{
endpoint_path
}
?sort=desc&per_page=4&page=2"
,
user
)
response_ids
=
json_response
.
map
{
|
merge_request
|
merge_request
[
'id'
]
}
expect
(
response_ids
).
not_to
include
(
closed_mr2
.
id
)
expect
(
response_ids
).
to
include
(
@mr_earlier
.
id
)
end
end
it
'returns an array of merge_requests ordered by updated_at'
do
it
'returns an array of merge_requests ordered by updated_at'
do
path
=
endpoint_path
+
'?order_by=updated_at'
path
=
endpoint_path
+
'?order_by=updated_at'
...
...
spec/support/shared_examples/requests/api/notes.rb
View file @
cf21118f
...
@@ -8,13 +8,45 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
...
@@ -8,13 +8,45 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
create_list
(
:note
,
3
,
params
)
create_list
(
:note
,
3
,
params
)
end
end
it
'sorts by created_at in descending order by default'
do
context
'without sort params'
do
get
api
(
"/
#{
parent_type
}
/
#{
parent
.
id
}
/
#{
noteable_type
}
/
#{
noteable
[
id_name
]
}
/notes"
,
user
)
it
'sorts by created_at in descending order by default'
do
get
api
(
"/
#{
parent_type
}
/
#{
parent
.
id
}
/
#{
noteable_type
}
/
#{
noteable
[
id_name
]
}
/notes"
,
user
)
response_dates
=
json_response
.
map
{
|
note
|
note
[
'created_at'
]
}
response_dates
=
json_response
.
map
{
|
note
|
note
[
'created_at'
]
}
expect
(
json_response
.
length
).
to
eq
(
4
)
expect
(
json_response
.
length
).
to
eq
(
4
)
expect
(
response_dates
).
to
eq
(
response_dates
.
sort
.
reverse
)
expect
(
response_dates
).
to
eq
(
response_dates
.
sort
.
reverse
)
end
context
'2 notes with equal created_at'
do
before
do
@first_note
=
Note
.
first
params
=
{
noteable:
noteable
,
author:
user
}
params
[
:project
]
=
parent
if
parent
.
is_a?
(
Project
)
params
[
:created_at
]
=
@first_note
.
created_at
@note2
=
create
(
:note
,
params
)
end
it
'page breaks first page correctly'
do
get
api
(
"/
#{
parent_type
}
/
#{
parent
.
id
}
/
#{
noteable_type
}
/
#{
noteable
[
id_name
]
}
/notes?per_page=4"
,
user
)
response_ids
=
json_response
.
map
{
|
note
|
note
[
'id'
]
}
expect
(
response_ids
).
to
include
(
@note2
.
id
)
expect
(
response_ids
).
not_to
include
(
@first_note
.
id
)
end
it
'page breaks second page correctly'
do
get
api
(
"/
#{
parent_type
}
/
#{
parent
.
id
}
/
#{
noteable_type
}
/
#{
noteable
[
id_name
]
}
/notes?per_page=4&page=2"
,
user
)
response_ids
=
json_response
.
map
{
|
note
|
note
[
'id'
]
}
expect
(
response_ids
).
not_to
include
(
@note2
.
id
)
expect
(
response_ids
).
to
include
(
@first_note
.
id
)
end
end
end
end
it
'sorts by ascending order when requested'
do
it
'sorts by ascending order when requested'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment