aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorKasper Timm Hansen <kaspth@gmail.com>2016-02-10 21:46:51 +0100
committerKasper Timm Hansen <kaspth@gmail.com>2016-02-10 21:46:51 +0100
commiteee3534b1a5614d824a34e2c761faaeab07c2eb4 (patch)
tree4de249ed1a91c151200d7d09355f3ba3e2bd44f8 /actionpack
parent688996da7b25080a1a2ef74f5b4789f3e5eb670d (diff)
downloadrails-eee3534b1a5614d824a34e2c761faaeab07c2eb4.tar.gz
rails-eee3534b1a5614d824a34e2c761faaeab07c2eb4.tar.bz2
rails-eee3534b1a5614d824a34e2c761faaeab07c2eb4.zip
Add `parsed_body` to spare writing out parsing routines.
When testing: ```ruby post articles_path, params: { article: { title: 'Ahoy!' } }, as: :json ``` It's common to want to make assertions on the response body. Perhaps the server responded with JSON, so you write `JSON.parse(response.body)`. But that gets tedious real quick. Instead add `parsed_body` which will automatically parse the reponse body as what the last request was encoded `as`.
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb38
-rw-r--r--actionpack/lib/action_dispatch/testing/test_response.rb6
-rw-r--r--actionpack/test/controller/integration_test.rb35
3 files changed, 56 insertions, 23 deletions
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 61bd39c186..742bce1ca6 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -381,6 +381,7 @@ module ActionDispatch
response = _mock_session.last_response
@response = ActionDispatch::TestResponse.from_response(response)
@response.request = @request
+ @response.response_parser = request_encoder
@html_document = nil
@url_options = nil
@@ -396,7 +397,7 @@ module ActionDispatch
class RequestEncoder # :nodoc:
@encoders = {}
- def initialize(mime_name, param_encoder, url_encoded_form = false)
+ def initialize(mime_name, param_encoder, response_parser, url_encoded_form = false)
@mime = Mime[mime_name]
unless @mime
@@ -406,7 +407,8 @@ module ActionDispatch
@url_encoded_form = url_encoded_form
@path_format = ".#{@mime.symbol}" unless @url_encoded_form
- @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc
+ @response_parser = response_parser || -> body { body }
+ @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc
end
def append_format_to(path)
@@ -422,17 +424,21 @@ module ActionDispatch
@param_encoder.call(params)
end
+ def parse_body(body)
+ @response_parser.call(body)
+ end
+
def self.encoder(name)
@encoders[name] || WWWFormEncoder
end
- def self.register_encoder(mime_name, &param_encoder)
- @encoders[mime_name] = new(mime_name, param_encoder)
+ def self.register_encoder(mime_name, param_encoder: nil, response_parser: nil)
+ @encoders[mime_name] = new(mime_name, param_encoder, response_parser)
end
- register_encoder :json
+ register_encoder :json, response_parser: -> body { JSON.parse(body) }
- WWWFormEncoder = new(:url_encoded_form, -> params { params }, true)
+ WWWFormEncoder = new(:url_encoded_form, -> params { params }, nil, true)
end
end
@@ -696,23 +702,31 @@ module ActionDispatch
# require 'test_helper'
#
# class ApiTest < ActionDispatch::IntegrationTest
- # test "creates articles" do
+ # test 'creates articles' do
# assert_difference -> { Article.count } do
# post articles_path, params: { article: { title: 'Ahoy!' } }, as: :json
# end
#
# assert_response :success
+ # assert_equal({ id: Arcticle.last.id, title: 'Ahoy!' }, response.parsed_body)
# end
# end
#
# The `as` option sets the format to JSON, sets the content type to
# 'application/json' and encodes the parameters as JSON.
#
+ # Calling `parsed_body` on the response parses the response body as what
+ # the last request was encoded as. If the request wasn't encoded `as` something,
+ # it's the same as calling `body`.
+ #
# For any custom MIME Types you've registered, you can even add your own encoders with:
#
- # ActionDispatch::IntegrationTest.register_encoder :wibble do |params|
- # params.to_wibble
- # end
+ # ActionDispatch::IntegrationTest.register_encoder :wibble,
+ # param_encoder: -> params { params.to_wibble },
+ # response_parser: -> body { body }
+ #
+ # Where `param_encoder` defines how the params should be encoded and
+ # `response_parser` defines how the response body should be parsed.
#
# Consult the Rails Testing Guide for more.
@@ -743,8 +757,8 @@ module ActionDispatch
html_document.root
end
- def self.register_encoder(*args, &param_encoder)
- Integration::Session::RequestEncoder.register_encoder(*args, &param_encoder)
+ def self.register_encoder(*args)
+ Integration::Session::RequestEncoder.register_encoder(*args)
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/test_response.rb b/actionpack/lib/action_dispatch/testing/test_response.rb
index 4b79a90242..58d3e6eb0f 100644
--- a/actionpack/lib/action_dispatch/testing/test_response.rb
+++ b/actionpack/lib/action_dispatch/testing/test_response.rb
@@ -18,5 +18,11 @@ module ActionDispatch
# Was there a server-side error?
alias_method :error?, :server_error?
+
+ attr_writer :response_parser # :nodoc:
+
+ def parsed_body
+ @response_parser.parse_body(body)
+ end
end
end
diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb
index 296bc1baad..cb524bacb2 100644
--- a/actionpack/test/controller/integration_test.rb
+++ b/actionpack/test/controller/integration_test.rb
@@ -1129,13 +1129,23 @@ end
class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
class FooController < ActionController::Base
- def foos
+ def foos_json
+ render json: params.permit(:foo)
+ end
+
+ def foos_wibble
render plain: 'ok'
end
end
def test_encoding_as_json
- assert_encoded_as :json, content_type: 'application/json'
+ post_to_foos as: :json do
+ assert_response :success
+ assert_match 'foos_json.json', request.path
+ assert_equal 'application/json', request.content_type
+ assert_equal({ 'foo' => 'fighters' }, request.request_parameters)
+ assert_equal({ 'foo' => 'fighters' }, response.parsed_body)
+ end
end
def test_encoding_as_without_mime_registration
@@ -1147,25 +1157,28 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest
def test_registering_custom_encoder
Mime::Type.register 'text/wibble', :wibble
- ActionDispatch::IntegrationTest.register_encoder(:wibble, &:itself)
+ ActionDispatch::IntegrationTest.register_encoder(:wibble,
+ param_encoder: -> params { params })
- assert_encoded_as :wibble, content_type: 'text/wibble',
- parsed_parameters: Hash.new # Unregistered MIME Type can't be parsed
+ post_to_foos as: :wibble do
+ assert_response :success
+ assert_match 'foos_wibble.wibble', request.path
+ assert_equal 'text/wibble', request.content_type
+ assert_equal Hash.new, request.request_parameters # Unregistered MIME Type can't be parsed.
+ assert_equal 'ok', response.parsed_body
+ end
ensure
Mime::Type.unregister :wibble
end
private
- def assert_encoded_as(format, content_type:, parsed_parameters: { 'foo' => 'fighters' })
+ def post_to_foos(as:)
with_routing do |routes|
routes.draw { post ':action' => FooController }
- post '/foos', params: { foo: 'fighters' }, as: format
+ post "/foos_#{as}", params: { foo: 'fighters' }, as: as
- assert_response :success
- assert_match "foos.#{format}", request.path
- assert_equal content_type, request.content_type
- assert_equal parsed_parameters, request.request_parameters
+ yield
end
end
end