v3: add ability to sort branches
This commit is contained in:
parent
0249140dc8
commit
33d31131c1
|
@ -1,7 +1,10 @@
|
||||||
module Travis::API::V3
|
module Travis::API::V3
|
||||||
class Queries::Branches < Query
|
class Queries::Branches < Query
|
||||||
|
sortable_by :name, last_build: "builds.started_at".freeze
|
||||||
|
default_sort "last_build:desc"
|
||||||
|
|
||||||
def find(repository)
|
def find(repository)
|
||||||
repository.branches
|
sort repository.branches
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -9,7 +9,7 @@ module Travis::API::V3
|
||||||
def query(type, main_type: self.main_type, params: self.params)
|
def query(type, main_type: self.main_type, params: self.params)
|
||||||
main_type = type if main_type == :owner
|
main_type = type if main_type == :owner
|
||||||
params = params.merge("#{type}.login" => params["owner.login".freeze]) if params["owner.login".freeze]
|
params = params.merge("#{type}.login" => params["owner.login".freeze]) if params["owner.login".freeze]
|
||||||
Queries[type].new(params, main_type)
|
Queries[type].new(params, main_type, service: @service)
|
||||||
end
|
end
|
||||||
|
|
||||||
def find!(type)
|
def find!(type)
|
||||||
|
|
|
@ -20,8 +20,11 @@ module Travis::API::V3
|
||||||
end
|
end
|
||||||
RUBY
|
RUBY
|
||||||
|
|
||||||
|
def self.type
|
||||||
|
name[/[^:]+$/].underscore
|
||||||
|
end
|
||||||
|
|
||||||
def self.params(*list, prefix: nil, method_name: nil)
|
def self.params(*list, prefix: nil, method_name: nil)
|
||||||
type = name[/[^:]+$/].underscore
|
|
||||||
prefix ||= type.to_s
|
prefix ||= type.to_s
|
||||||
check_type = method_name.nil? and type != prefix
|
check_type = method_name.nil? and type != prefix
|
||||||
list.each do |entry|
|
list.each do |entry|
|
||||||
|
@ -35,12 +38,48 @@ module Travis::API::V3
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.prefix(input)
|
||||||
|
return input if input.is_a? String
|
||||||
|
"#{type}.#{input}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.sortable_by(*params, **mapping)
|
||||||
|
params.each { |param| sort_by[param.to_s] = prefix(param) }
|
||||||
|
mapping.each { |key, value| sort_by[key.to_s] = prefix(value) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.sortable?
|
||||||
|
!sort_by.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
@sort_by = {}
|
||||||
|
def self.sort_by
|
||||||
|
@sort_by ||= superclass.sort_by.dup
|
||||||
|
end
|
||||||
|
|
||||||
|
@default_sort = ""
|
||||||
|
def self.default_sort(value = nil)
|
||||||
|
@default_sort = value.to_s if value
|
||||||
|
@default_sort ||= superclass.default_sort
|
||||||
|
end
|
||||||
|
|
||||||
attr_reader :params, :main_type
|
attr_reader :params, :main_type
|
||||||
|
|
||||||
def initialize(params, main_type, includes: nil)
|
def initialize(params, main_type, includes: nil, service: nil)
|
||||||
@params = params
|
@params = params
|
||||||
@main_type = main_type.to_s
|
@main_type = main_type.to_s
|
||||||
@includes = includes
|
@includes = includes
|
||||||
|
@service = service
|
||||||
|
end
|
||||||
|
|
||||||
|
def warn(*args)
|
||||||
|
return unless @service
|
||||||
|
@service.warn(*args)
|
||||||
|
end
|
||||||
|
|
||||||
|
def ignored_value(param, value, reason: nil, **info)
|
||||||
|
message = reason ? "query value #{value} for #{param} #{reason}, ignored" : "query value #{value} for #{param} ignored"
|
||||||
|
warn(message, warning_type: :ignored_value, parameter: param, value: value, **info)
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform_async(identifier, *args)
|
def perform_async(identifier, *args)
|
||||||
|
@ -72,6 +111,45 @@ module Travis::API::V3
|
||||||
value.split(?,.freeze)
|
value.split(?,.freeze)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def sort(collection)
|
||||||
|
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)
|
||||||
|
first = false
|
||||||
|
else
|
||||||
|
ignored_value("sort_by".freeze, field_with_order, reason: "not a valid sort mode".freeze)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
collection
|
||||||
|
end
|
||||||
|
|
||||||
|
def sort_by?(field, order)
|
||||||
|
return false unless order == "asc".freeze or order == "desc".freeze
|
||||||
|
self.class.sort_by.include?(field)
|
||||||
|
end
|
||||||
|
|
||||||
|
def sort_by(collection, field, order: nil, first: false)
|
||||||
|
raise ArgumentError, 'cannot sort by that' unless sort_by?(field, order)
|
||||||
|
actual = self.class.sort_by.fetch(field)
|
||||||
|
line = "#{actual} #{order.upcase}"
|
||||||
|
|
||||||
|
if sort_join?(collection, actual)
|
||||||
|
collection = collection.joins(actual.to_sym)
|
||||||
|
elsif actual != field and sort_join?(collection, field)
|
||||||
|
collection = collection.joins(field.to_sym)
|
||||||
|
end
|
||||||
|
|
||||||
|
first ? collection.reorder(line) : collection.order(line)
|
||||||
|
end
|
||||||
|
|
||||||
|
def sort_join?(collection, field)
|
||||||
|
!collection.reflect_on_association(field.to_sym).nil?
|
||||||
|
end
|
||||||
|
|
||||||
def user_condition(value)
|
def user_condition(value)
|
||||||
case value
|
case value
|
||||||
when String then { login: value }
|
when String then { login: value }
|
||||||
|
|
|
@ -26,6 +26,7 @@ module Travis::API::V3
|
||||||
|
|
||||||
def self.paginate(**options)
|
def self.paginate(**options)
|
||||||
params("limit".freeze, "offset".freeze)
|
params("limit".freeze, "offset".freeze)
|
||||||
|
params("sort_by".freeze) if query_factory.sortable?
|
||||||
@paginator = Paginator.new(**options)
|
@paginator = Paginator.new(**options)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -37,6 +38,10 @@ module Travis::API::V3
|
||||||
!!@paginator if defined? @paginator
|
!!@paginator if defined? @paginator
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.query_factory
|
||||||
|
Queries[result_type]
|
||||||
|
end
|
||||||
|
|
||||||
attr_accessor :access_control, :params
|
attr_accessor :access_control, :params
|
||||||
|
|
||||||
def initialize(access_control, params)
|
def initialize(access_control, params)
|
||||||
|
@ -47,7 +52,7 @@ module Travis::API::V3
|
||||||
end
|
end
|
||||||
|
|
||||||
def query(type = result_type)
|
def query(type = result_type)
|
||||||
@queries[type] ||= Queries[type].new(params, result_type)
|
@queries[type] ||= Queries[type].new(params, result_type, service: self)
|
||||||
end
|
end
|
||||||
|
|
||||||
def github(user = nil)
|
def github(user = nil)
|
||||||
|
@ -81,7 +86,21 @@ module Travis::API::V3
|
||||||
def run
|
def run
|
||||||
not_found unless result = run!
|
not_found unless result = run!
|
||||||
result = result(result_type, result) unless result.is_a? Result
|
result = result(result_type, result) unless result.is_a? Result
|
||||||
self.class.paginate? ? paginate(result) : result
|
result = paginate(result) if self.class.paginate?
|
||||||
|
apply_warnings(result)
|
||||||
|
result
|
||||||
|
end
|
||||||
|
|
||||||
|
def warnings
|
||||||
|
@warnings ||= []
|
||||||
|
end
|
||||||
|
|
||||||
|
def warn(*args)
|
||||||
|
warnings << args
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply_warnings(result)
|
||||||
|
warnings.each { |args| result.warn(*args) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def paginate(result)
|
def paginate(result)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module Travis::API::V3
|
module Travis::API::V3
|
||||||
class Services::Branches::Find < Service
|
class Services::Branches::Find < Service
|
||||||
paginate
|
paginate
|
||||||
|
|
||||||
def run!
|
def run!
|
||||||
query.find(find(:repository))
|
query.find(find(:repository))
|
||||||
end
|
end
|
||||||
|
|
|
@ -171,4 +171,60 @@ describe Travis::API::V3::Services::Branches::Find do
|
||||||
"exists_on_github" => true }]}
|
"exists_on_github" => true }]}
|
||||||
}
|
}
|
||||||
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 }
|
||||||
|
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=name&limit=1",
|
||||||
|
"offset" => 0,
|
||||||
|
"limit" => 1 },
|
||||||
|
"last" => {
|
||||||
|
"@href" => "/v3/repo/#{repo.id}/branches?sort_by=name&limit=1",
|
||||||
|
"offset" => 0,
|
||||||
|
"limit" => 1 }}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "sorting by name:desc" do
|
||||||
|
before { get("/v3/repo/#{repo.id}/branches?sort_by=name%3Adesc&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=name%3Adesc&limit=1",
|
||||||
|
"offset" => 0,
|
||||||
|
"limit" => 1 },
|
||||||
|
"last" => {
|
||||||
|
"@href" => "/v3/repo/#{repo.id}/branches?sort_by=name%3Adesc&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 }
|
||||||
|
example { expect(parsed_body["@warnings"]).to be == [{
|
||||||
|
"@type" => "warning",
|
||||||
|
"message" => "query value foo for sort_by not a valid sort mode, ignored",
|
||||||
|
"warning_type"=> "ignored_value",
|
||||||
|
"parameter" => "sort_by",
|
||||||
|
"value" => "foo"
|
||||||
|
}]}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue
Block a user