diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/testing/integration.rb')
-rw-r--r-- | actionpack/lib/action_dispatch/testing/integration.rb | 150 |
1 files changed, 57 insertions, 93 deletions
diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 10cd1e5787..13f7fc6fa6 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -1,10 +1,12 @@ -require 'stringio' -require 'uri' -require 'active_support/core_ext/kernel/singleton_class' -require 'active_support/core_ext/object/try' -require 'active_support/core_ext/string/strip' -require 'rack/test' -require 'minitest' +require "stringio" +require "uri" +require "active_support/core_ext/kernel/singleton_class" +require "active_support/core_ext/object/try" +require "active_support/core_ext/string/strip" +require "rack/test" +require "minitest" + +require "action_dispatch/testing/request_encoder" module ActionDispatch module Integration #:nodoc: @@ -122,7 +124,7 @@ module ActionDispatch # params: { ref_id: 14 }, # headers: { "X-Test-Header" => "testvalue" } def request_via_redirect(http_method, path, *args) - ActiveSupport::Deprecation.warn('`request_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.') + ActiveSupport::Deprecation.warn("`request_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.") process_with_kwargs(http_method, path, *args) follow_redirect! while redirect? @@ -132,35 +134,35 @@ module ActionDispatch # Performs a GET request, following any subsequent redirect. # See +request_via_redirect+ for more information. def get_via_redirect(path, *args) - ActiveSupport::Deprecation.warn('`get_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.') + ActiveSupport::Deprecation.warn("`get_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.") request_via_redirect(:get, path, *args) end # Performs a POST request, following any subsequent redirect. # See +request_via_redirect+ for more information. def post_via_redirect(path, *args) - ActiveSupport::Deprecation.warn('`post_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.') + ActiveSupport::Deprecation.warn("`post_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.") request_via_redirect(:post, path, *args) end # Performs a PATCH request, following any subsequent redirect. # See +request_via_redirect+ for more information. def patch_via_redirect(path, *args) - ActiveSupport::Deprecation.warn('`patch_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.') + ActiveSupport::Deprecation.warn("`patch_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.") request_via_redirect(:patch, path, *args) end # Performs a PUT request, following any subsequent redirect. # See +request_via_redirect+ for more information. def put_via_redirect(path, *args) - ActiveSupport::Deprecation.warn('`put_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.') + ActiveSupport::Deprecation.warn("`put_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.") request_via_redirect(:put, path, *args) end # Performs a DELETE request, following any subsequent redirect. # See +request_via_redirect+ for more information. def delete_via_redirect(path, *args) - ActiveSupport::Deprecation.warn('`delete_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.') + ActiveSupport::Deprecation.warn("`delete_via_redirect` is deprecated and will be removed in Rails 5.1. Please use `follow_redirect!` manually after the request call for the same behavior.") request_via_redirect(:delete, path, *args) end end @@ -180,11 +182,11 @@ module ActionDispatch include TestProcess, RequestHelpers, Assertions %w( status status_message headers body redirect? ).each do |method| - delegate method, :to => :response, :allow_nil => true + delegate method, to: :response, allow_nil: true end %w( path ).each do |method| - delegate method, :to => :request, :allow_nil => true + delegate method, to: :request, allow_nil: true end # The hostname used in the last request. @@ -235,7 +237,7 @@ module ActionDispatch url_options.reverse_merge!(@app.routes.default_url_options) end - url_options.reverse_merge!(:host => host, :protocol => https? ? "https" : "http") + url_options.reverse_merge!(host: host, protocol: https? ? "https" : "http") end end @@ -296,7 +298,7 @@ module ActionDispatch process(http_method, path, *args) else non_kwarg_request_warning if args.any? - process(http_method, path, { params: args[0], headers: args[1] }) + process(http_method, path, params: args[0], headers: args[1]) end end @@ -325,6 +327,12 @@ module ActionDispatch # Performs the actual request. def process(method, path, params: nil, headers: nil, env: nil, xhr: false, as: nil) request_encoder = RequestEncoder.encoder(as) + headers ||= {} + + if method == :get && as == :json && params + headers["X-Http-Method-Override"] = "GET" + method = :post + end if path =~ %r{://} path = build_expanded_path(path, request_encoder) do |location| @@ -340,7 +348,7 @@ module ActionDispatch path = build_expanded_path(path, request_encoder) end - hostname, port = host.split(':') + hostname, port = host.split(":") request_env = { :method => method, @@ -358,15 +366,17 @@ module ActionDispatch "HTTP_ACCEPT" => accept } + wrapped_headers = Http::Headers.from_hash({}) + wrapped_headers.merge!(headers) if headers + if xhr - headers ||= {} - headers['HTTP_X_REQUESTED_WITH'] = 'XMLHttpRequest' - headers['HTTP_ACCEPT'] ||= [Mime[:js], Mime[:html], Mime[:xml], 'text/xml', '*/*'].join(', ') + wrapped_headers["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" + wrapped_headers["HTTP_ACCEPT"] ||= [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ") end # this modifies the passed request_env directly - if headers.present? - Http::Headers.from_hash(request_env).merge!(headers) + if wrapped_headers.present? + Http::Headers.from_hash(request_env).merge!(wrapped_headers) end if env.present? Http::Headers.from_hash(request_env).merge!(env) @@ -383,7 +393,6 @@ module ActionDispatch response = _mock_session.last_response @response = ActionDispatch::TestResponse.from_response(response) @response.request = @request - @response.response_parser = RequestEncoder.parser(@response.content_type) @html_document = nil @url_options = nil @@ -402,59 +411,6 @@ module ActionDispatch path = request_encoder.append_format_to location.path location.query ? "#{path}?#{location.query}" : path end - - class RequestEncoder # :nodoc: - @encoders = {} - - attr_reader :response_parser - - def initialize(mime_name, param_encoder, response_parser, 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 - @response_parser = response_parser || -> body { body } - @param_encoder = param_encoder || :"to_#{@mime.symbol}".to_proc - end - - def append_format_to(path) - if @url_encoded_form - path - else - path + @path_format - end - end - - def content_type - @mime.to_s - end - - def encode_params(params) - @param_encoder.call(params) - end - - def self.parser(content_type) - mime = Mime::Type.lookup(content_type) - encoder(mime ? mime.ref : nil).response_parser - end - - def self.encoder(name) - @encoders[name] || WWWFormEncoder - end - - 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, response_parser: -> body { JSON.parse(body) } - - WWWFormEncoder = new(:url_encoded_form, -> params { params }, nil, true) - end end module Runner @@ -500,7 +456,7 @@ module ActionDispatch xml_http_request xhr get_via_redirect post_via_redirect).each do |method| define_method(method) do |*args| # reset the html_document variable, except for cookies/assigns calls - unless method == 'cookies' || method == 'assigns' + unless method == "cookies" || method == "assigns" @html_document = nil end @@ -711,38 +667,42 @@ module ActionDispatch # end # end # + # See the {request helpers documentation}[rdoc-ref:ActionDispatch::Integration::RequestHelpers] for help on how to + # use +get+, etc. + # + # === Changing the request encoding + # # You can also test your JSON API easily by setting what the request should # be encoded as: # - # require 'test_helper' + # 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 + # post articles_path, params: { article: { title: "Ahoy!" } }, as: :json # end # # assert_response :success - # assert_equal({ id: Arcticle.last.id, title: 'Ahoy!' }, response.parsed_body) + # 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. + # 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`. + # Calling +parsed_body+ on the response parses the response body based on the + # last response MIME type. # - # For any custom MIME Types you've registered, you can even add your own encoders with: + # For any custom MIME types you've registered, you can even add your own encoders with: # # 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 through - # `parsed_body`. + # Where +param_encoder+ defines how the params should be encoded and + # +response_parser+ defines how the response body should be parsed through + # +parsed_body+. # # Consult the Rails Testing Guide for more. @@ -769,7 +729,11 @@ module ActionDispatch module ClassMethods def app - defined?(@@app) ? @@app : ActionDispatch.test_app + if defined?(@@app) && @@app + @@app + else + ActionDispatch.test_app + end end def app=(app) @@ -777,7 +741,7 @@ module ActionDispatch end def register_encoder(*args) - Integration::Session::RequestEncoder.register_encoder(*args) + RequestEncoder.register_encoder(*args) end end |