v3: add attributes to service index

This commit is contained in:
Konstantin Haase 2015-03-09 19:48:52 +01:00
parent 9b8a99ea33
commit 9449ada1cd
4 changed files with 100 additions and 28 deletions

View File

@ -9,9 +9,12 @@ module Travis::API::V3
attr_accessor :resolver_cache
def [](key)
def [](key, raise_unknown = true)
return key unless key.is_a? Symbol
resolver_cache[key] ||= const_get(key.to_s.camelize, false)
rescue NameError => e
raise e if raise_unknown
raise e unless e.message.include?(key.to_s.camelize)
end
def extended(base)

View File

@ -14,7 +14,7 @@ module Travis::API::V3
def self.representation(name, *fields)
fields.each do |field|
class_eval "def #{field}; @model.#{field}; end" unless method_defined?(field)
available_fields << field.to_s
available_attributes << field.to_s
end
representations[name] = fields
end
@ -23,8 +23,8 @@ module Travis::API::V3
@representations ||= {}
end
def self.available_fields
@available_fields ||= Set.new
def self.available_attributes
@available_attributes ||= Set.new
end
def self.render(model, representation = :standard, **options)
@ -70,7 +70,7 @@ module Travis::API::V3
include.each do |qualified_field|
raise WrongParams, 'illegal format for include parameter'.freeze unless /\A(?<prefix>\w+)\.(?<field>\w+)\Z$/ =~ qualified_field
next if prefix != excepted_type
raise WrongParams, 'no field %p to include'.freeze % qualified_field unless self.class.available_fields.include?(field)
raise WrongParams, 'no field %p to include'.freeze % qualified_field unless self.class.available_attributes.include?(field)
field &&= field.to_sym
fields << field unless fields.include?(field)

View File

@ -25,16 +25,19 @@ module Travis::API::V3
def render_json
resources = { }
routes.resources.each do |resource|
resources[resource.identifier] ||= {}
data = resources[resource.identifier] ||= { :@type => :resource, :actions => {} }
if renderer = Renderer[resource.identifier, false] and renderer.respond_to? :available_attributes
data[:attributes] = renderer.available_attributes
end
resource.services.each do |(request_method, sub_route), service|
list = resources[resource.identifier][service] ||= []
list = resources[resource.identifier][:actions][service] ||= []
pattern = sub_route ? resource.route + sub_route : resource.route
pattern.to_templates.each do |template|
list << { 'request_method'.freeze => request_method, 'uri_template'.freeze => prefix + template }
list << { :@type => :template, :request_method => request_method, :uri_template => prefix + template }
end
end
end
{ :@type => 'home'.freeze, :resources => resources }
{ :@type => :home, :resources => resources }
end
def render_json_home

View File

@ -7,25 +7,91 @@ describe Travis::API::V3::ServiceIndex do
let(:response) { get(path, {}, headers) }
describe "custom json entry point" do
let(:expected_resources) {{
"repository" => {
"find" => [{"request_method"=>"GET", "uri_template"=>"#{path}repo/{repository.id}"}],
"enable" => [{"request_method"=>"POST", "uri_template"=>"#{path}repo/{repository.id}/enable"}],
"disable" => [{"request_method"=>"POST", "uri_template"=>"#{path}repo/{repository.id}/disable"}] },
"repositories" => {
"for_current_user" => [{"request_method"=>"GET", "uri_template"=>"#{path}repos"}] },
"branch" => {
"find" => [{"request_method"=>"GET", "uri_template"=>"#{path}repo/{repository.id}/branch/{branch.name}"}]},
"build" => {
"find" => [{"request_method"=>"GET", "uri_template"=>"#{path}build/{build.id}"}] },
"organizations" => {
"for_current_user" => [{"request_method"=>"GET", "uri_template"=>"#{path}orgs"}] },
"organization" => {
"find" => [{"request_method"=>"GET", "uri_template"=>"#{path}org/{organization.id}"}] },
"requests" => {
"find" => [{"request_method"=>"GET", "uri_template"=>"#{path}repo/{repository.id}/requests"}],
"create" => [{"request_method"=>"POST", "uri_template"=>"#{path}repo/{repository.id}/requests"}]}
}}
let(:expected_resources) {
{"requests"=>
{"@type"=>"resource",
"actions"=>
{"find"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}repo/{repository.id}/requests"}],
"create"=>
[{"@type"=>"template",
"request_method"=>"POST",
"uri_template"=>"#{path}repo/{repository.id}/requests"}]}},
"branch"=>
{"@type"=>"resource",
"actions"=>
{"find"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}repo/{repository.id}/branch/{branch.name}"}]},
"attributes"=>["name", "last_build", "repository"]},
"repository"=>
{"@type"=>"resource",
"actions"=>
{"find"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}repo/{repository.id}"}],
"enable"=>
[{"@type"=>"template",
"request_method"=>"POST",
"uri_template"=>"#{path}repo/{repository.id}/enable"}],
"disable"=>
[{"@type"=>"template",
"request_method"=>"POST",
"uri_template"=>"#{path}repo/{repository.id}/disable"}]},
"attributes"=>
["id",
"slug",
"name",
"description",
"github_language",
"active",
"private",
"owner",
"last_build",
"default_branch"]},
"repositories"=>
{"@type"=>"resource",
"actions"=>
{"for_current_user"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}repos"}]}},
"build"=>
{"@type"=>"resource",
"actions"=>
{"find"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}build/{build.id}"}]},
"attributes"=>
["id",
"number",
"state",
"duration",
"started_at",
"finished_at",
"repository",
"branch"]},
"organization"=>
{"@type"=>"resource",
"actions"=>
{"find"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}org/{organization.id}"}]},
"attributes"=>["id", "login", "name", "github_id"]},
"organizations"=>
{"@type"=>"resource",
"actions"=>
{"for_current_user"=>
[{"@type"=>"template",
"request_method"=>"GET",
"uri_template"=>"#{path}orgs"}]}}}
}
describe 'with /v3 prefix' do
let(:path) { '/v3/' }