hanami-controller/test/integration/mime_type_test.rb

351 lines
10 KiB
Ruby

require 'test_helper'
require 'hanami/router'
MimeRoutes = Hanami::Router.new do
get '/', to: 'mimes#default'
get '/custom', to: 'mimes#custom'
get '/configuration', to: 'mimes#configuration'
get '/accept', to: 'mimes#accept'
get '/restricted', to: 'mimes#restricted'
get '/latin', to: 'mimes#latin'
get '/nocontent', to: 'mimes#no_content'
get '/response', to: 'mimes#default_response'
get '/overwritten_format', to: 'mimes#override_default_response'
get '/custom_from_accept', to: 'mimes#custom_from_accept'
end
module Mimes
class Default
include Hanami::Action
def call(params)
self.body = format
end
end
class Configuration
include Hanami::Action
configuration.default_request_format :html
configuration.default_charset 'ISO-8859-1'
def call(params)
self.body = format
end
end
class Custom
include Hanami::Action
def call(params)
self.format = :xml
self.body = format
end
end
class Latin
include Hanami::Action
def call(params)
self.charset = 'latin1'
self.format = :html
self.body = format
end
end
class Accept
include Hanami::Action
def call(params)
self.headers.merge!({'X-AcceptDefault' => accept?('application/octet-stream').to_s })
self.headers.merge!({'X-AcceptHtml' => accept?('text/html').to_s })
self.headers.merge!({'X-AcceptXml' => accept?('application/xml').to_s })
self.headers.merge!({'X-AcceptJson' => accept?('text/json').to_s })
self.body = format
end
end
class CustomFromAccept
include Hanami::Action
configuration.format custom: 'application/custom'
accept :json, :custom
def call(params)
self.body = format
end
end
class Restricted
include Hanami::Action
configuration.format custom: 'application/custom'
accept :html, :json, :custom
def call(params)
self.body = format.to_s
end
end
class NoContent
include Hanami::Action
def call(params)
self.status = 204
end
end
class DefaultResponse
include Hanami::Action
configuration.default_request_format :html
configuration.default_response_format :json
def call(params)
self.body = configuration.default_request_format
end
end
class OverrideDefaultResponse
include Hanami::Action
configuration.default_response_format :json
def call(params)
self.format = :xml
end
end
end
describe 'Content type' do
before do
@app = Rack::MockRequest.new(MimeRoutes)
end
it 'fallbacks to the default "Content-Type" header when the request is lacking of this information' do
response = @app.get('/')
response.headers['Content-Type'].must_equal 'application/octet-stream; charset=utf-8'
response.body.must_equal 'all'
end
it 'fallbacks to the default format and charset, set in the configuration' do
response = @app.get('/configuration')
response.headers['Content-Type'].must_equal 'text/html; charset=ISO-8859-1'
response.body.must_equal 'html'
end
it 'returns the specified "Content-Type" header' do
response = @app.get('/custom')
response.headers['Content-Type'].must_equal 'application/xml; charset=utf-8'
response.body.must_equal 'xml'
end
it 'returns the custom charser header' do
response = @app.get('/latin')
response.headers['Content-Type'].must_equal 'text/html; charset=latin1'
response.body.must_equal 'html'
end
it 'uses default_response_format if set in the configuration regardless of request format' do
response = @app.get('/response')
response.headers['Content-Type'].must_equal 'application/json; charset=utf-8'
response.body.must_equal 'html'
end
it 'allows to override default_response_format' do
response = @app.get('/overwritten_format')
response.headers['Content-Type'].must_equal 'application/xml; charset=utf-8'
end
# FIXME Review if this test must be in place
it 'does not produce a "Content-Type" header when the request has a 204 No Content status'
# it 'does not produce a "Content-Type" header when the request has a 204 No Content status' do
# response = @app.get('/nocontent')
# response.headers['Content-Type'].must_be_nil
# response.body.must_equal ''
# end
describe 'when Accept is sent' do
it 'sets "Content-Type" header according to wildcard value' do
response = @app.get('/', 'HTTP_ACCEPT' => '*/*')
content_type = 'application/octet-stream; charset=utf-8'
response.headers['Content-Type'].must_equal content_type
response.body.must_equal 'all'
end
it 'sets "Content-Type" header according to exact value' do
headers = {'HTTP_ACCEPT' => 'application/custom'}
response = @app.get('/custom_from_accept', headers)
content_type = 'application/custom; charset=utf-8'
response.headers['Content-Type'].must_equal content_type
response.body.must_equal 'custom'
end
it 'sets "Content-Type" header according to weighted value' do
accept = 'application/custom;q=0.9,application/json;q=0.5'
headers = {'HTTP_ACCEPT' => accept}
response = @app.get('/custom_from_accept', headers)
content_type = 'application/custom; charset=utf-8'
response.headers['Content-Type'].must_equal content_type
response.body.must_equal 'custom'
end
it 'sets "Content-Type" header according to weighted, unordered value' do
accept = 'application/custom;q=0.1, application/json;q=0.5'
headers = {'HTTP_ACCEPT' => accept}
response = @app.get('/custom_from_accept', headers)
content_type = 'application/json; charset=utf-8'
response.headers['Content-Type'].must_equal content_type
response.body.must_equal 'json'
end
it 'sets "Content-Type" header according to exact and weighted value' do
accept = 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8'
response = @app.get('/', 'HTTP_ACCEPT' => accept)
response.headers['Content-Type'].must_equal 'text/html; charset=utf-8'
response.body.must_equal 'html'
end
it 'sets "Content-Type" header according to quality scale value' do
accept = 'application/json;q=0.6,application/xml;q=0.9,*/*;q=0.8'
headers = {'HTTP_ACCEPT' => accept}
response = @app.get('/', headers)
content_type = 'application/xml; charset=utf-8'
response.headers['Content-Type'].must_equal content_type
response.body.must_equal 'xml'
end
end
end
describe 'Accept' do
before do
@app = Rack::MockRequest.new(MimeRoutes)
@response = @app.get('/accept', 'HTTP_ACCEPT' => accept)
end
describe 'when Accept is missing' do
let(:accept) { nil }
it 'accepts all' do
@response.headers['X-AcceptDefault'].must_equal 'true'
@response.headers['X-AcceptHtml'].must_equal 'true'
@response.headers['X-AcceptXml'].must_equal 'true'
@response.headers['X-AcceptJson'].must_equal 'true'
@response.body.must_equal 'all'
end
end
describe 'when Accept is sent' do
describe 'when "*/*"' do
let(:accept) { '*/*' }
it 'accepts all' do
@response.headers['X-AcceptDefault'].must_equal 'true'
@response.headers['X-AcceptHtml'].must_equal 'true'
@response.headers['X-AcceptXml'].must_equal 'true'
@response.headers['X-AcceptJson'].must_equal 'true'
@response.body.must_equal 'all'
end
end
describe 'when "text/html"' do
let(:accept) { 'text/html' }
it 'accepts selected mime types' do
@response.headers['X-AcceptDefault'].must_equal 'false'
@response.headers['X-AcceptHtml'].must_equal 'true'
@response.headers['X-AcceptXml'].must_equal 'false'
@response.headers['X-AcceptJson'].must_equal 'false'
@response.body.must_equal 'html'
end
end
describe 'when weighted' do
let(:accept) { 'text/html,application/xhtml+xml,application/xml;q=0.9' }
it 'accepts selected mime types' do
@response.headers['X-AcceptDefault'].must_equal 'false'
@response.headers['X-AcceptHtml'].must_equal 'true'
@response.headers['X-AcceptXml'].must_equal 'true'
@response.headers['X-AcceptJson'].must_equal 'false'
@response.body.must_equal 'html'
end
end
end
end
describe 'Restricted Accept' do
before do
@app = Rack::MockRequest.new(MimeRoutes)
@response = @app.get('/restricted', 'HTTP_ACCEPT' => accept)
end
describe 'when Accept is missing' do
let(:accept) { nil }
it 'returns the mime type according to the application defined policy' do
@response.status.must_equal 200
@response.body.must_equal 'all'
end
end
describe 'when Accept is sent' do
describe 'when "*/*"' do
let(:accept) { '*/*' }
it 'returns the mime type according to the application defined policy' do
@response.status.must_equal 200
@response.body.must_equal 'all'
end
end
describe 'when accepted' do
let(:accept) { 'text/html' }
it 'accepts selected mime types' do
@response.status.must_equal 200
@response.body.must_equal 'html'
end
end
describe 'when custom mime type' do
let(:accept) { 'application/custom' }
it 'accepts selected mime types' do
@response.status.must_equal 200
@response.body.must_equal 'custom'
end
end
describe 'when not accepted' do
let(:accept) { 'application/xml' }
it 'accepts selected mime types' do
@response.status.must_equal 406
end
end
describe 'when weighted' do
describe 'with an accepted format as first choice' do
let(:accept) { 'text/html,application/xhtml+xml,application/xml;q=0.9' }
it 'accepts selected mime types' do
@response.status.must_equal 200
@response.body.must_equal 'html'
end
end
describe 'with an accepted format as last choice' do
let(:accept) { 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,*/*;q=0.5' }
it 'accepts selected mime types' do
@response.status.must_equal 200
@response.body.must_equal 'html'
end
end
end
end
end