Merge pull request #203 from travis-ci/rkh-branches-filtering-and-sorting
better branches filtering and sorting
This commit is contained in:
commit
aa222ad6b2
|
@ -1,10 +1,33 @@
|
|||
module Travis::API::V3
|
||||
class Queries::Branches < Query
|
||||
sortable_by :name, last_build: "builds.started_at".freeze
|
||||
default_sort "last_build:desc"
|
||||
params :exists_on_github, prefix: :branch
|
||||
|
||||
sortable_by :name,
|
||||
last_build: "builds.started_at".freeze,
|
||||
exists_on_github: sort_condition(:exists_on_github),
|
||||
default_branch: sort_condition(name: "repositories.default_branch")
|
||||
|
||||
default_sort "default_branch,exists_on_github,last_build:desc"
|
||||
|
||||
def find(repository)
|
||||
sort repository.branches
|
||||
sort(filter(repository.branches), repository: repository)
|
||||
end
|
||||
|
||||
def sort_by(collection, field, repository: nil, **options)
|
||||
return super unless field == "default_branch".freeze
|
||||
|
||||
if repository
|
||||
options[:sql] = sort_condition(name: quote(repository.default_branch_name))
|
||||
else
|
||||
collection = collection.joins(:repository)
|
||||
end
|
||||
|
||||
super(collection, field, **options)
|
||||
end
|
||||
|
||||
def filter(list)
|
||||
list = list.where(exists_on_github: bool(exists_on_github)) unless exists_on_github.nil?
|
||||
list
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,6 +48,13 @@ module Travis::API::V3
|
|||
mapping.each { |key, value| sort_by[key.to_s] = prefix(value) }
|
||||
end
|
||||
|
||||
def self.sort_condition(condition)
|
||||
if condition.is_a? Hash
|
||||
condition = condition.map { |e| e.map { |v| prefix(v) }.join(" = ".freeze) }.join(" and ".freeze)
|
||||
end
|
||||
"(case when #{prefix(condition)} then 1 else 2 end)"
|
||||
end
|
||||
|
||||
def self.sortable?
|
||||
!sort_by.empty?
|
||||
end
|
||||
|
@ -111,14 +118,14 @@ module Travis::API::V3
|
|||
value.split(?,.freeze)
|
||||
end
|
||||
|
||||
def sort(collection)
|
||||
def sort(collection, **options)
|
||||
return collection unless sort_by = params["sort_by".freeze] || self.class.default_sort and not sort_by.empty?
|
||||
first = true
|
||||
list(sort_by).each do |field_with_order|
|
||||
field, order = field_with_order.split(?:.freeze, 2)
|
||||
order ||= "asc".freeze
|
||||
if sort_by? field, order
|
||||
collection = sort_by(collection, field, order: order, first: first)
|
||||
collection = sort_by(collection, field, order: order, first: first, **options)
|
||||
first = false
|
||||
else
|
||||
ignored_value("sort_by".freeze, field_with_order, reason: "not a valid sort mode".freeze)
|
||||
|
@ -132,9 +139,9 @@ module Travis::API::V3
|
|||
self.class.sort_by.include?(field)
|
||||
end
|
||||
|
||||
def sort_by(collection, field, order: nil, first: false)
|
||||
def sort_by(collection, field, order: nil, first: false, sql: nil, **)
|
||||
raise ArgumentError, 'cannot sort by that' unless sort_by?(field, order)
|
||||
actual = self.class.sort_by.fetch(field)
|
||||
actual = sql || self.class.sort_by.fetch(field)
|
||||
line = "#{actual} #{order.upcase}"
|
||||
|
||||
if sort_join?(collection, actual)
|
||||
|
@ -150,6 +157,14 @@ module Travis::API::V3
|
|||
!collection.reflect_on_association(field.to_sym).nil?
|
||||
end
|
||||
|
||||
def sort_condition(*args)
|
||||
self.class.sort_condition(*args)
|
||||
end
|
||||
|
||||
def quote(value)
|
||||
ActiveRecord::Base.connection.quote(value)
|
||||
end
|
||||
|
||||
def user_condition(value)
|
||||
case value
|
||||
when String then { login: value }
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
module Travis::API::V3
|
||||
class Services::Branches::Find < Service
|
||||
params :exists_on_github, prefix: :branch
|
||||
paginate
|
||||
|
||||
def run!
|
||||
|
|
|
@ -172,6 +172,20 @@ describe Travis::API::V3::Services::Branches::Find do
|
|||
}
|
||||
end
|
||||
|
||||
describe "filtering by exists_on_github" do
|
||||
describe "false" do
|
||||
before { get("/v3/repo/#{repo.id}/branches?branch.exists_on_github=false") }
|
||||
example { expect(last_response).to be_ok }
|
||||
example { expect(parsed_body["branches"]).to be_empty }
|
||||
end
|
||||
|
||||
describe "true" do
|
||||
before { get("/v3/repo/#{repo.id}/branches?branch.exists_on_github=true") }
|
||||
example { expect(last_response).to be_ok }
|
||||
example { expect(parsed_body["branches"]).not_to be_empty }
|
||||
end
|
||||
end
|
||||
|
||||
describe "sorting by name" do
|
||||
before { get("/v3/repo/#{repo.id}/branches?sort_by=name&limit=1") }
|
||||
example { expect(last_response).to be_ok }
|
||||
|
@ -216,6 +230,50 @@ describe Travis::API::V3::Services::Branches::Find do
|
|||
}
|
||||
end
|
||||
|
||||
describe "sorting by exists_on_github" do
|
||||
before { get("/v3/repo/#{repo.id}/branches?sort_by=exists_on_github&limit=1") }
|
||||
example { expect(last_response).to be_ok }
|
||||
example { expect(parsed_body["@pagination"]).to be == {
|
||||
"limit" => 1,
|
||||
"offset" => 0,
|
||||
"count" => 1,
|
||||
"is_first" => true,
|
||||
"is_last" => true,
|
||||
"next" => nil,
|
||||
"prev" => nil,
|
||||
"first" => {
|
||||
"@href" => "/v3/repo/#{repo.id}/branches?sort_by=exists_on_github&limit=1",
|
||||
"offset" => 0,
|
||||
"limit" => 1 },
|
||||
"last" => {
|
||||
"@href" => "/v3/repo/#{repo.id}/branches?sort_by=exists_on_github&limit=1",
|
||||
"offset" => 0,
|
||||
"limit" => 1 }}
|
||||
}
|
||||
end
|
||||
|
||||
describe "sorting by default_branch" do
|
||||
before { get("/v3/repo/#{repo.id}/branches?sort_by=default_branch&limit=1") }
|
||||
example { expect(last_response).to be_ok }
|
||||
example { expect(parsed_body["@pagination"]).to be == {
|
||||
"limit" => 1,
|
||||
"offset" => 0,
|
||||
"count" => 1,
|
||||
"is_first" => true,
|
||||
"is_last" => true,
|
||||
"next" => nil,
|
||||
"prev" => nil,
|
||||
"first" => {
|
||||
"@href" => "/v3/repo/#{repo.id}/branches?sort_by=default_branch&limit=1",
|
||||
"offset" => 0,
|
||||
"limit" => 1 },
|
||||
"last" => {
|
||||
"@href" => "/v3/repo/#{repo.id}/branches?sort_by=default_branch&limit=1",
|
||||
"offset" => 0,
|
||||
"limit" => 1 }}
|
||||
}
|
||||
end
|
||||
|
||||
describe "sorting by unknown sort field" do
|
||||
before { get("/v3/repo/#{repo.id}/branches?sort_by=name:desc,foo&limit=1") }
|
||||
example { expect(last_response).to be_ok }
|
||||
|
|
Loading…
Reference in New Issue
Block a user