aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/testing/integration.rb
diff options
context:
space:
mode:
authorKasper Timm Hansen <kaspth@gmail.com>2015-09-19 00:11:18 +0200
committerKasper Timm Hansen <kaspth@gmail.com>2016-01-04 23:07:34 +0100
commit52bb2d36d3141dcd8217221065d9b5fa2b12deba (patch)
tree806f79dd361e1bb2a881dd628dcbfc7df82d5d1d /actionpack/lib/action_dispatch/testing/integration.rb
parent904e3f4465cb2b874bd99000e96e2e6e0e03844c (diff)
downloadrails-52bb2d36d3141dcd8217221065d9b5fa2b12deba.tar.gz
rails-52bb2d36d3141dcd8217221065d9b5fa2b12deba.tar.bz2
rails-52bb2d36d3141dcd8217221065d9b5fa2b12deba.zip
Add `as` to encode a request as a specific mime type.
Turns ``` post articles_path(format: :json), params: { article: { name: 'Ahoy!' } }.to_json, headers: { 'Content-Type' => 'application/json' } ``` into ``` post articles_path, params: { article: { name: 'Ahoy!' } }, as: :json ```
Diffstat (limited to 'actionpack/lib/action_dispatch/testing/integration.rb')
-rw-r--r--actionpack/lib/action_dispatch/testing/integration.rb83
1 files changed, 79 insertions, 4 deletions
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb
index 711ca10419..cade3bf6b3 100644
--- a/actionpack/lib/action_dispatch/testing/integration.rb
+++ b/actionpack/lib/action_dispatch/testing/integration.rb
@@ -321,7 +321,9 @@ module ActionDispatch
end
# Performs the actual request.
- def process(method, path, params: nil, headers: nil, env: nil, xhr: false)
+ def process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: nil)
+ request_encoder = RequestEncoder.encoder(as)
+
if path =~ %r{://}
location = URI.parse(path)
https! URI::HTTPS === location if location.scheme
@@ -330,14 +332,17 @@ module ActionDispatch
url_host += ":#{location.port}" if default != location.port
host! url_host
end
- path = location.query ? "#{location.path}?#{location.query}" : location.path
+ path = request_encoder.append_format_to location.path
+ path = location.query ? "#{path}?#{location.query}" : path
+ else
+ path = request_encoder.append_format_to path
end
hostname, port = host.split(':')
request_env = {
:method => method,
- :params => params,
+ :params => request_encoder.encode_params(params),
"SERVER_NAME" => hostname,
"SERVER_PORT" => port || (https? ? "443" : "80"),
@@ -347,7 +352,7 @@ module ActionDispatch
"REQUEST_URI" => path,
"HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
- "CONTENT_TYPE" => "application/x-www-form-urlencoded",
+ "CONTENT_TYPE" => request_encoder.content_type,
"HTTP_ACCEPT" => accept
}
@@ -387,6 +392,48 @@ module ActionDispatch
def build_full_uri(path, env)
"#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}"
end
+
+ class RequestEncoder # :nodoc:
+ @encoders = {}
+
+ def initialize(mime_name, param_encoder, url_encoded_form = false)
+ @mime = Mime[mime_name]
+
+ unless @mime
+ raise ArgumentError, "Can't register a request encoder for " \
+ "unregistered MIME Type: #{mime_name}. See `Mime::Type.register`."
+ end
+
+ @url_encoded_form = url_encoded_form
+ @path_format = ".#{@mime.symbol}" unless @url_encoded_form
+ @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc
+ end
+
+ def append_format_to(path)
+ path << @path_format unless @url_encoded_form
+ path
+ end
+
+ def content_type
+ @mime.to_s
+ end
+
+ def encode_params(params)
+ @param_encoder.call(params)
+ 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)
+ end
+
+ register_encoder :json
+
+ WWWFormEncoder = new(:url_encoded_form, -> params { params }, true)
+ end
end
module Runner
@@ -643,6 +690,30 @@ module ActionDispatch
# end
# end
#
+ # You can also test your JSON API easily by setting what the request should
+ # be encoded as:
+ #
+ # require 'test_helper'
+ #
+ # class ApiTest < ActionDispatch::IntegrationTest
+ # test "creates articles" do
+ # assert_difference -> { Article.count } do
+ # post articles_path, params: { article: { title: 'Ahoy!' } }, as: :json
+ # end
+ #
+ # assert_response :success
+ # end
+ # end
+ #
+ # The `as` option sets the format to JSON, sets the content type to
+ # 'application/json' and encodes the parameters as JSON.
+ #
+ # 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
+ #
# Consult the Rails Testing Guide for more.
class IntegrationTest < ActiveSupport::TestCase
@@ -671,5 +742,9 @@ module ActionDispatch
def document_root_element
html_document.root
end
+
+ def self.register_encoder(*args, &param_encoder)
+ Integration::Session::RequestEncoder.register_encoder(*args, &param_encoder)
+ end
end
end