diff options
Diffstat (limited to 'actionpack/lib/action_dispatch/testing')
7 files changed, 178 insertions, 288 deletions
diff --git a/actionpack/lib/action_dispatch/testing/assertions.rb b/actionpack/lib/action_dispatch/testing/assertions.rb index b362931ef7..4ea18d671d 100644 --- a/actionpack/lib/action_dispatch/testing/assertions.rb +++ b/actionpack/lib/action_dispatch/testing/assertions.rb @@ -12,7 +12,7 @@ module ActionDispatch include Rails::Dom::Testing::Assertions def html_document - @html_document ||= if @response.content_type.to_s =~ /xml\z/ + @html_document ||= if @response.content_type.to_s.end_with?("xml") Nokogiri::XML::Document.parse(@response.body) else Nokogiri::HTML::Document.parse(@response.body) diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb index a2eaccd9ef..1baf979ac9 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/response.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb @@ -45,12 +45,12 @@ module ActionDispatch # # Asserts that the redirection was to the named route login_url # assert_redirected_to login_url # - # # Asserts that the redirection was to the url for @customer + # # Asserts that the redirection was to the URL for @customer # assert_redirected_to @customer # # # Asserts that the redirection matches the regular expression # assert_redirected_to %r(\Ahttp://example.org) - def assert_redirected_to(options = {}, message=nil) + def assert_redirected_to(options = {}, message = nil) assert_response(:redirect, message) return true if options === @response.location diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index e53bc6af12..8645df4370 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -18,8 +18,8 @@ module ActionDispatch # assert_recognizes({controller: 'items', action: 'create'}, {path: 'items', method: :post}) # # You can also pass in +extras+ with a hash containing URL parameters that would normally be in the query string. This can be used - # to assert that values in the query string will end up in the params hash correctly. To test query strings you must use the - # extras argument, appending the query string on the path directly will not work. For example: + # to assert that values in the query string will end up in the params hash correctly. To test query strings you must use the extras + # argument because appending the query string on the path directly will not work. For example: # # # Asserts that a path of '/items/list/1?view=print' returns the correct options # assert_recognizes({controller: 'items', action: 'list', id: '1', view: 'print'}, 'items/list/1', { view: "print" }) @@ -37,7 +37,7 @@ module ActionDispatch # # # Test a custom route # assert_recognizes({controller: 'items', action: 'show', id: '1'}, 'view/item1') - def assert_recognizes(expected_options, path, extras={}, msg=nil) + def assert_recognizes(expected_options, path, extras = {}, msg = nil) if path.is_a?(Hash) && path[:method].to_s == "all" [:get, :post, :put, :delete].each do |method| assert_recognizes(expected_options, path.merge(method: method), extras, msg) @@ -75,7 +75,7 @@ module ActionDispatch # # # Asserts that the generated route gives us our custom route # assert_generates "changesets/12", { controller: 'scm', action: 'show_diff', revision: "12" } - def assert_generates(expected_path, options, defaults={}, extras={}, message=nil) + def assert_generates(expected_path, options, defaults = {}, extras = {}, message = nil) if expected_path =~ %r{://} fail_on(URI::InvalidURIError, message) do uri = URI.parse(expected_path) @@ -119,7 +119,7 @@ module ActionDispatch # # # Tests a route with an HTTP method # assert_routing({ method: 'put', path: '/product/321' }, { controller: "product", action: "update", id: "321" }) - def assert_routing(path, options, defaults={}, extras={}, message=nil) + def assert_routing(path, options, defaults = {}, extras = {}, message = nil) assert_recognizes(options, path, extras, message) controller, default_controller = options[:controller], defaults[:controller] @@ -132,8 +132,7 @@ module ActionDispatch end # A helper to make it easier to test different route configurations. - # This method temporarily replaces @routes - # with a new RouteSet instance. + # This method temporarily replaces @routes with a new RouteSet instance. # # The new instance is yielded to the passed block. Typically the block # will create some routes using <tt>set.draw { match ... }</tt>: @@ -152,8 +151,11 @@ module ActionDispatch _routes = @routes @controller.singleton_class.include(_routes.url_helpers) - @controller.view_context_class = Class.new(@controller.view_context_class) do - include _routes.url_helpers + + if @controller.respond_to? :view_context_class + @controller.view_context_class = Class.new(@controller.view_context_class) do + include _routes.url_helpers + end end end yield @routes @@ -183,7 +185,6 @@ module ActionDispatch method = :get end - # Assume given controller request = ActionController::TestRequest.create @controller.class if path =~ %r{://} diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 720651fa1f..2416c58817 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -2,7 +2,6 @@ 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" @@ -11,99 +10,42 @@ require "action_dispatch/testing/request_encoder" module ActionDispatch module Integration #:nodoc: module RequestHelpers - # Performs a GET request with the given parameters. - # - # - +path+: The URI (as a String) on which you want to perform a GET - # request. - # - +params+: The HTTP parameters that you want to pass. This may - # be +nil+, - # a Hash, or a String that is appropriately encoded - # (<tt>application/x-www-form-urlencoded</tt> or - # <tt>multipart/form-data</tt>). - # - +headers+: Additional headers to pass, as a Hash. The headers will be - # merged into the Rack env hash. - # - +env+: Additional env to pass, as a Hash. The headers will be - # merged into the Rack env hash. - # - # This method returns a Response object, which one can use to - # inspect the details of the response. Furthermore, if this method was - # called from an ActionDispatch::IntegrationTest object, then that - # object's <tt>@response</tt> instance variable will point to the same - # response object. - # - # You can also perform POST, PATCH, PUT, DELETE, and HEAD requests with - # +#post+, +#patch+, +#put+, +#delete+, and +#head+. - # - # Example: - # - # get '/feed', params: { since: 201501011400 } - # post '/profile', headers: { "X-Test-Header" => "testvalue" } - def get(path, *args) - process_with_kwargs(:get, path, *args) + # Performs a GET request with the given parameters. See +#process+ for more + # details. + def get(path, **args) + process(:get, path, **args) end - # Performs a POST request with the given parameters. See +#get+ for more + # Performs a POST request with the given parameters. See +#process+ for more # details. - def post(path, *args) - process_with_kwargs(:post, path, *args) + def post(path, **args) + process(:post, path, **args) end - # Performs a PATCH request with the given parameters. See +#get+ for more + # Performs a PATCH request with the given parameters. See +#process+ for more # details. - def patch(path, *args) - process_with_kwargs(:patch, path, *args) + def patch(path, **args) + process(:patch, path, **args) end - # Performs a PUT request with the given parameters. See +#get+ for more + # Performs a PUT request with the given parameters. See +#process+ for more # details. - def put(path, *args) - process_with_kwargs(:put, path, *args) + def put(path, **args) + process(:put, path, **args) end - # Performs a DELETE request with the given parameters. See +#get+ for + # Performs a DELETE request with the given parameters. See +#process+ for # more details. - def delete(path, *args) - process_with_kwargs(:delete, path, *args) + def delete(path, **args) + process(:delete, path, **args) end - # Performs a HEAD request with the given parameters. See +#get+ for more + # Performs a HEAD request with the given parameters. See +#process+ for more # details. def head(path, *args) - process_with_kwargs(:head, path, *args) + process(:head, path, *args) end - # Performs an XMLHttpRequest request with the given parameters, mirroring - # an AJAX request made from JavaScript. - # - # The request_method is +:get+, +:post+, +:patch+, +:put+, +:delete+ or - # +:head+; the parameters are +nil+, a hash, or a url-encoded or multipart - # string; the headers are a hash. - # - # Example: - # - # xhr :get, '/feed', params: { since: 201501011400 } - def xml_http_request(request_method, path, *args) - if kwarg_request?(args) - params, headers, env = args.first.values_at(:params, :headers, :env) - else - params = args[0] - headers = args[1] - env = {} - - if params.present? || headers.present? - non_kwarg_request_warning - end - end - - ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc) - xhr and xml_http_request methods are deprecated in favor of - `get "/posts", xhr: true` and `post "/posts/1", xhr: true`. - MSG - - process(request_method, path, params: params, headers: headers, xhr: true) - end - alias xhr :xml_http_request - # Follow a single redirect response. If the last response was not a # redirect, an exception will be raised. Otherwise, the redirect is # performed on the location header. @@ -112,59 +54,6 @@ module ActionDispatch get(response.location) status end - - # Performs a request using the specified method, following any subsequent - # redirect. Note that the redirects are followed until the response is - # not a redirect--this means you may run into an infinite loop if your - # redirect loops back to itself. - # - # Example: - # - # request_via_redirect :post, '/welcome', - # 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.") - process_with_kwargs(http_method, path, *args) - - follow_redirect! while redirect? - status - end - - # 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.") - 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.") - 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.") - 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.") - 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.") - request_via_redirect(:delete, path, *args) - end end # An instance of this class represents a set of requests and responses @@ -179,7 +68,7 @@ module ActionDispatch DEFAULT_HOST = "www.example.com" include Minitest::Assertions - include RequestHelpers, Assertions + include TestProcess, RequestHelpers, Assertions %w( status status_message headers body redirect? ).each do |method| delegate method, to: :response, allow_nil: true @@ -255,8 +144,8 @@ module ActionDispatch self.host = DEFAULT_HOST self.remote_addr = "127.0.0.1" - self.accept = "text/xml,application/xml,application/xhtml+xml," + - "text/html;q=0.9,text/plain;q=0.8,image/png," + + self.accept = "text/xml,application/xml,application/xhtml+xml," \ + "text/html;q=0.9,text/plain;q=0.8,image/png," \ "*/*;q=0.5" unless defined? @named_routes_configured @@ -283,132 +172,125 @@ module ActionDispatch @https end - # Set the host name to use in the next request. + # Performs the actual request. # - # session.host! "www.example.com" - alias :host! :host= - - private - def _mock_session - @_mock_session ||= Rack::MockSession.new(@app, host) - end - - def process_with_kwargs(http_method, path, *args) - if kwarg_request?(args) - process(http_method, path, *args) - else - non_kwarg_request_warning if args.any? - process(http_method, path, params: args[0], headers: args[1]) - end - end - - REQUEST_KWARGS = %i(params headers env xhr as) - def kwarg_request?(args) - args[0].respond_to?(:keys) && args[0].keys.any? { |k| REQUEST_KWARGS.include?(k) } - end - - def non_kwarg_request_warning - ActiveSupport::Deprecation.warn(<<-MSG.strip_heredoc) - ActionDispatch::IntegrationTest HTTP request methods will accept only - the following keyword arguments in future Rails versions: - #{REQUEST_KWARGS.join(', ')} - - Examples: - - get '/profile', - params: { id: 1 }, - headers: { 'X-Extra-Header' => '123' }, - env: { 'action_dispatch.custom' => 'custom' }, - xhr: true, - as: :json - MSG + # - +method+: The HTTP method (GET, POST, PATCH, PUT, DELETE, HEAD, OPTIONS) + # as a symbol. + # - +path+: The URI (as a String) on which you want to perform the + # request. + # - +params+: The HTTP parameters that you want to pass. This may + # be +nil+, + # a Hash, or a String that is appropriately encoded + # (<tt>application/x-www-form-urlencoded</tt> or + # <tt>multipart/form-data</tt>). + # - +headers+: Additional headers to pass, as a Hash. The headers will be + # merged into the Rack env hash. + # - +env+: Additional env to pass, as a Hash. The headers will be + # merged into the Rack env hash. + # + # This method is rarely used directly. Use +#get+, +#post+, or other standard + # HTTP methods in integration tests. +#process+ is only required when using a + # request method that doesn't have a method defined in the integration tests. + # + # This method returns the response status, after performing the request. + # Furthermore, if this method was called from an ActionDispatch::IntegrationTest object, + # then that object's <tt>@response</tt> instance variable will point to a Response object + # which one can use to inspect the details of the response. + # + # Example: + # process :get, '/author', params: { since: 201501011400 } + 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 - # 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 path =~ %r{://} + path = build_expanded_path(path) do |location| + https! URI::HTTPS === location if location.scheme - if method == :get && as == :json && params - headers["X-Http-Method-Override"] = "GET" - method = :post + if url_host = location.host + default = Rack::Request::DEFAULT_PORTS[location.scheme] + url_host += ":#{location.port}" if default != location.port + host! url_host + end end + end - if path =~ %r{://} - path = build_expanded_path(path, request_encoder) do |location| - https! URI::HTTPS === location if location.scheme + hostname, port = host.split(":") - if url_host = location.host - default = Rack::Request::DEFAULT_PORTS[location.scheme] - url_host += ":#{location.port}" if default != location.port - host! url_host - end - end - elsif as - path = build_expanded_path(path, request_encoder) - end + request_env = { + :method => method, + :params => request_encoder.encode_params(params), - hostname, port = host.split(":") + "SERVER_NAME" => hostname, + "SERVER_PORT" => port || (https? ? "443" : "80"), + "HTTPS" => https? ? "on" : "off", + "rack.url_scheme" => https? ? "https" : "http", - request_env = { - :method => method, - :params => request_encoder.encode_params(params), + "REQUEST_URI" => path, + "HTTP_HOST" => host, + "REMOTE_ADDR" => remote_addr, + "CONTENT_TYPE" => request_encoder.content_type, + "HTTP_ACCEPT" => request_encoder.accept_header || accept + } - "SERVER_NAME" => hostname, - "SERVER_PORT" => port || (https? ? "443" : "80"), - "HTTPS" => https? ? "on" : "off", - "rack.url_scheme" => https? ? "https" : "http", + wrapped_headers = Http::Headers.from_hash({}) + wrapped_headers.merge!(headers) if headers - "REQUEST_URI" => path, - "HTTP_HOST" => host, - "REMOTE_ADDR" => remote_addr, - "CONTENT_TYPE" => request_encoder.content_type, - "HTTP_ACCEPT" => accept - } + if xhr + wrapped_headers["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" + wrapped_headers["HTTP_ACCEPT"] ||= [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ") + end - wrapped_headers = Http::Headers.from_hash({}) - wrapped_headers.merge!(headers) if headers + # This modifies the passed request_env directly. + 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) + end - if xhr - wrapped_headers["HTTP_X_REQUESTED_WITH"] = "XMLHttpRequest" - wrapped_headers["HTTP_ACCEPT"] ||= [Mime[:js], Mime[:html], Mime[:xml], "text/xml", "*/*"].join(", ") - end + session = Rack::Test::Session.new(_mock_session) - # this modifies the passed request_env directly - 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) - end + # NOTE: rack-test v0.5 doesn't build a default uri correctly + # Make sure requested path is always a full URI. + session.request(build_full_uri(path, request_env), request_env) - session = Rack::Test::Session.new(_mock_session) + @request_count += 1 + @request = ActionDispatch::Request.new(session.last_request.env) + response = _mock_session.last_response + @response = ActionDispatch::TestResponse.from_response(response) + @response.request = @request + @html_document = nil + @url_options = nil - # NOTE: rack-test v0.5 doesn't build a default uri correctly - # Make sure requested path is always a full uri - session.request(build_full_uri(path, request_env), request_env) + @controller = @request.controller_instance - @request_count += 1 - @request = ActionDispatch::Request.new(session.last_request.env) - response = _mock_session.last_response - @response = ActionDispatch::TestResponse.from_response(response) - @response.request = @request - @html_document = nil - @url_options = nil + response.status + end - @controller = @request.controller_instance + # Set the host name to use in the next request. + # + # session.host! "www.example.com" + alias :host! :host= - response.status + private + def _mock_session + @_mock_session ||= Rack::MockSession.new(@app, host) end def build_full_uri(path, env) "#{env['rack.url_scheme']}://#{env['SERVER_NAME']}:#{env['SERVER_PORT']}#{path}" end - def build_expanded_path(path, request_encoder) + def build_expanded_path(path) location = URI.parse(path) yield location if block_given? - path = request_encoder.append_format_to location.path + path = location.path location.query ? "#{path}?#{location.query}" : path end end @@ -442,8 +324,8 @@ module ActionDispatch def create_session(app) klass = APP_SESSIONS[app] ||= Class.new(Integration::Session) { - # If the app is a Rails app, make url_helpers available on the session - # This makes app.url_for and app.foo_path available in the console + # If the app is a Rails app, make url_helpers available on the session. + # This makes app.url_for and app.foo_path available in the console. if app.respond_to?(:routes) include app.routes.url_helpers include app.routes.mounted_helpers @@ -482,6 +364,7 @@ module ActionDispatch # simultaneously. def open_session dup.tap do |session| + session.reset! yield session if block_given? end end @@ -502,14 +385,15 @@ module ActionDispatch integration_session.default_url_options = options end - def respond_to_missing?(method, include_private = false) - integration_session.respond_to?(method, include_private) || super + private + def respond_to_missing?(method, _) + integration_session.respond_to?(method) || super end # Delegate unhandled messages to the current session instance. - def method_missing(sym, *args, &block) - if integration_session.respond_to?(sym) - integration_session.__send__(sym, *args, &block).tap do + def method_missing(method, *args, &block) + if integration_session.respond_to?(method) + integration_session.public_send(method, *args, &block).tap do copy_session_variables! end else @@ -688,17 +572,19 @@ module ActionDispatch # end # # assert_response :success - # assert_equal({ id: Arcticle.last.id, title: "Ahoy!" }, response.parsed_body) + # assert_equal({ id: Article.last.id, title: "Ahoy!" }, response.parsed_body) # end # end # - # The +as+ option sets the format to JSON, sets the content type to + # The +as+ option passes an "application/json" Accept header (thereby setting + # the request format to JSON unless overridden), sets the content type to # "application/json" and encodes the parameters as JSON. # # 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: + # Out of the box, only <tt>:json</tt> is supported. But for any custom MIME + # types you've registered, you can add your own encoders with: # # ActionDispatch::IntegrationTest.register_encoder :wibble, # param_encoder: -> params { params.to_wibble }, @@ -711,7 +597,7 @@ module ActionDispatch # Consult the Rails Testing Guide for more. class IntegrationTest < ActiveSupport::TestCase - include TestProcess + include TestProcess::FixtureFile module UrlOptions extend ActiveSupport::Concern diff --git a/actionpack/lib/action_dispatch/testing/request_encoder.rb b/actionpack/lib/action_dispatch/testing/request_encoder.rb index b0b994b2d0..8c27e9ecb7 100644 --- a/actionpack/lib/action_dispatch/testing/request_encoder.rb +++ b/actionpack/lib/action_dispatch/testing/request_encoder.rb @@ -1,10 +1,17 @@ module ActionDispatch class RequestEncoder # :nodoc: - @encoders = {} + class IdentityEncoder + def content_type; end + def accept_header; end + def encode_params(params); params; end + def response_parser; -> body { body }; end + end + + @encoders = { identity: IdentityEncoder.new } attr_reader :response_parser - def initialize(mime_name, param_encoder, response_parser, url_encoded_form = false) + def initialize(mime_name, param_encoder, response_parser) @mime = Mime[mime_name] unless @mime @@ -12,21 +19,15 @@ module ActionDispatch "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 + @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 + def content_type + @mime.to_s end - def content_type + def accept_header @mime.to_s end @@ -40,7 +41,7 @@ module ActionDispatch end def self.encoder(name) - @encoders[name] || WWWFormEncoder + @encoders[name] || @encoders[:identity] end def self.register_encoder(mime_name, param_encoder: nil, response_parser: nil) @@ -48,7 +49,5 @@ module ActionDispatch end register_encoder :json, response_parser: -> body { JSON.parse(body) } - - WWWFormEncoder = new(:url_encoded_form, -> params { params }, nil, true) end end diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb index 8b03b776fa..0282eb15c3 100644 --- a/actionpack/lib/action_dispatch/testing/test_process.rb +++ b/actionpack/lib/action_dispatch/testing/test_process.rb @@ -3,6 +3,26 @@ require "action_dispatch/middleware/flash" module ActionDispatch module TestProcess + module FixtureFile + # Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.fixture_path, path), type)</tt>: + # + # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png') + # + # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter. + # This will not affect other platforms: + # + # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary) + def fixture_file_upload(path, mime_type = nil, binary = false) + if self.class.respond_to?(:fixture_path) && self.class.fixture_path && + !File.exist?(path) + path = File.join(self.class.fixture_path, path) + end + Rack::Test::UploadedFile.new(path, mime_type, binary) + end + end + + include FixtureFile + def assigns(key = nil) raise NoMethodError, "assigns has been extracted to a gem. To continue using it, @@ -24,21 +44,5 @@ module ActionDispatch def redirect_to_url @response.redirect_url end - - # Shortcut for <tt>Rack::Test::UploadedFile.new(File.join(ActionDispatch::IntegrationTest.fixture_path, path), type)</tt>: - # - # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png') - # - # To upload binary files on Windows, pass <tt>:binary</tt> as the last parameter. - # This will not affect other platforms: - # - # post :change_avatar, avatar: fixture_file_upload('files/spongebob.png', 'image/png', :binary) - def fixture_file_upload(path, mime_type = nil, binary = false) - if self.class.respond_to?(:fixture_path) && self.class.fixture_path && - !File.exist?(path) - path = File.join(self.class.fixture_path, path) - end - Rack::Test::UploadedFile.new(path, mime_type, binary) - end end end diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb index 91b25ec155..ec949c869b 100644 --- a/actionpack/lib/action_dispatch/testing/test_request.rb +++ b/actionpack/lib/action_dispatch/testing/test_request.rb @@ -9,7 +9,7 @@ module ActionDispatch "HTTP_USER_AGENT" => "Rails Testing", ) - # Create a new test request with default `env` values + # Create a new test request with default `env` values. def self.create(env = {}) env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application env["rack.request.cookie_hash"] ||= {}.with_indifferent_access |