Allow passing more than one mime type in Accept

This commit is contained in:
Piotr Sarnacki 2013-02-16 04:47:27 +01:00
parent 1d7be066cb
commit 212eb6d9d3
8 changed files with 65 additions and 13 deletions

View File

@ -6,8 +6,9 @@ class Travis::Api::App
# convert (in addition to the return values supported by Sinatra, of
# course). These values will be encoded in JSON.
module RespondWith
include Accept
def respond_with(resource, options = {})
options[:format] ||= env['travis.format']
result = respond(resource, options)
result = result ? result.to_json : 404
halt result
@ -21,15 +22,24 @@ class Travis::Api::App
private
def respond(resource, options)
responders(resource, options).each do |const|
responder = const.new(self, resource, options)
resource = responder.apply if responder.apply?
resource = apply_service_responder(resource, options)
acceptable_formats.find do |accept|
responders(resource, options).find do |const|
responder = const.new(self, resource, options.dup.merge(accept: accept))
responder.apply if responder.apply?
end
end
end
def apply_service_responder(resource, options)
responder = Responders::Service.new(self, resource, options)
resource = responder.apply if responder.apply?
resource
end
def responders(resource, options)
[:Service, :Json, :Image, :Xml, :Plain].map do |name|
[:Json, :Image, :Xml, :Plain].map do |name|
Responders.const_get(name)
end
end

View File

@ -24,6 +24,7 @@ class Travis::Api::App
def extract_format
env['PATH_INFO'].sub!(FORMAT, '')
env['travis.format_from_path'] = $1
env['travis.format'] = $1 || accept_format
end

View File

@ -31,5 +31,19 @@ module Travis::Api::App::Responders
def headers
endpoint.headers
end
def apply?
acceptable_format?
end
def format
self.class.name.split('::').last.downcase
end
def acceptable_format?
if accept = options[:accept]
accept.accepts?(Rack::Mime.mime_type(".#{format}"))
end
end
end
end

View File

@ -1,7 +1,7 @@
module Travis::Api::App::Responders
class Image < Base
def apply?
options[:format] == 'png'
def format
'png'
end
def apply

View File

@ -4,7 +4,7 @@ class Travis::Api::App
include Helpers::Accept
def apply?
options[:format] == 'json' && !resource.is_a?(String) && !resource.nil?
super && !resource.is_a?(String) && !resource.nil?
end
def apply

View File

@ -1,12 +1,16 @@
module Travis::Api::App::Responders
class Plain < Base
def format
'txt'
end
def apply?
# make sure that we don't leak anything by processing only Log
# instances here. I don't want to create entire new API builder just
# for log's content for now.
#
# TODO: think how to handle other formats correctly
options[:format] == 'txt' && resource.is_a?(Log)
super && resource.is_a?(Log)
end
def apply

View File

@ -15,10 +15,6 @@ module Travis::Api::App::Responders
started: 'Building'
}
def apply?
options[:format] == 'xml'
end
def apply
halt TEMPLATE % data
end

View File

@ -0,0 +1,27 @@
require 'spec_helper'
describe 'App' do
before do
FactoryGirl.create(:test, :number => '3.1', :queue => 'builds.common')
add_endpoint '/foo' do
get '/' do
respond_with(Log.first)
end
get '/hash' do
respond_with foo: 'bar'
end
end
end
it 'gives priority to format given the url' do
response = get '/foo.txt', {}, 'HTTP_ACCEPT' => 'application/json'
response.content_type.should =~ /^text\/plain/
end
it 'responds with first available type' do
response = get '/foo', {}, 'HTTP_ACCEPT' => 'image/jpeg, application/json'
response.content_type.should =~ /^application\/json/
end
end