Allow passing more than one mime type in Accept
This commit is contained in:
parent
1d7be066cb
commit
212eb6d9d3
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
module Travis::Api::App::Responders
|
||||
class Image < Base
|
||||
def apply?
|
||||
options[:format] == 'png'
|
||||
def format
|
||||
'png'
|
||||
end
|
||||
|
||||
def apply
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -15,10 +15,6 @@ module Travis::Api::App::Responders
|
|||
started: 'Building'
|
||||
}
|
||||
|
||||
def apply?
|
||||
options[:format] == 'xml'
|
||||
end
|
||||
|
||||
def apply
|
||||
halt TEMPLATE % data
|
||||
end
|
||||
|
|
27
spec/integration/formats_handling_spec.rb
Normal file
27
spec/integration/formats_handling_spec.rb
Normal 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
|
Loading…
Reference in New Issue
Block a user