aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_dispatch/testing/assertions
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib/action_dispatch/testing/assertions')
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/response.rb65
-rw-r--r--actionpack/lib/action_dispatch/testing/assertions/routing.rb41
2 files changed, 65 insertions, 41 deletions
diff --git a/actionpack/lib/action_dispatch/testing/assertions/response.rb b/actionpack/lib/action_dispatch/testing/assertions/response.rb
index 13a72220b3..817737341c 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/response.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/response.rb
@@ -1,8 +1,14 @@
-
module ActionDispatch
module Assertions
# A small suite of assertions that test responses from \Rails applications.
module ResponseAssertions
+ RESPONSE_PREDICATES = { # :nodoc:
+ success: :successful?,
+ missing: :not_found?,
+ redirect: :redirection?,
+ error: :server_error?,
+ }
+
# Asserts that the response is one of the following types:
#
# * <tt>:success</tt> - Status code was in the 200-299 range
@@ -14,45 +20,37 @@ module ActionDispatch
# or its symbolic equivalent <tt>assert_response(:not_implemented)</tt>.
# See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.
#
- # # assert that the response was a redirection
+ # # Asserts that the response was a redirection
# assert_response :redirect
#
- # # assert that the response code was status code 401 (unauthorized)
+ # # Asserts that the response code was status code 401 (unauthorized)
# assert_response 401
def assert_response(type, message = nil)
- message ||= "Expected response to be a <#{type}>, but was <#{@response.response_code}>"
+ message ||= generate_response_message(type)
- if Symbol === type
- if [:success, :missing, :redirect, :error].include?(type)
- assert @response.send("#{type}?"), message
- else
- code = Rack::Utils::SYMBOL_TO_STATUS_CODE[type]
- if code.nil?
- raise ArgumentError, "Invalid response type :#{type}"
- end
- assert_equal code, @response.response_code, message
- end
+ if RESPONSE_PREDICATES.keys.include?(type)
+ assert @response.send(RESPONSE_PREDICATES[type]), message
else
- assert_equal type, @response.response_code, message
+ assert_equal AssertionResponse.new(type).code, @response.response_code, message
end
end
- # Assert that the redirection options passed in match those of the redirect called in the latest action.
+ # Asserts that the redirection options passed in match those of the redirect called in the latest action.
# This match can be partial, such that <tt>assert_redirected_to(controller: "weblog")</tt> will also
# match the redirection of <tt>redirect_to(controller: "weblog", action: "show")</tt> and so on.
#
- # # assert that the redirection was to the "index" action on the WeblogController
+ # # Asserts that the redirection was to the "index" action on the WeblogController
# assert_redirected_to controller: "weblog", action: "index"
#
- # # assert that the redirection was to the named route login_url
+ # # Asserts that the redirection was to the named route login_url
# assert_redirected_to login_url
#
- # # assert 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
+ # # 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
@@ -77,6 +75,31 @@ module ActionDispatch
handle._compute_redirect_to_location(@request, fragment)
end
end
+
+ def generate_response_message(expected, actual = @response.response_code)
+ "Expected response to be a <#{code_with_name(expected)}>,"\
+ " but was a <#{code_with_name(actual)}>"
+ .concat(location_if_redirected).concat(response_body_if_short)
+ end
+
+ def response_body_if_short
+ return "" if @response.body.size > 500
+ "\nResponse body: #{@response.body}"
+ end
+
+ def location_if_redirected
+ return "" unless @response.redirection? && @response.location.present?
+ location = normalize_argument_to_redirection(@response.location)
+ " redirect to <#{location}>"
+ end
+
+ def code_with_name(code_or_name)
+ if RESPONSE_PREDICATES.values.include?("#{code_or_name}?".to_sym)
+ code_or_name = RESPONSE_PREDICATES.invert["#{code_or_name}?".to_sym]
+ end
+
+ AssertionResponse.new(code_or_name).code_and_name
+ end
end
end
end
diff --git a/actionpack/lib/action_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
index c94eea9134..454dcb9307 100644
--- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb
+++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb
@@ -1,7 +1,7 @@
-require 'uri'
-require 'active_support/core_ext/hash/indifferent_access'
-require 'active_support/core_ext/string/access'
-require 'action_controller/metal/exceptions'
+require "uri"
+require "active_support/core_ext/hash/indifferent_access"
+require "active_support/core_ext/string/access"
+require "action_controller/metal/exceptions"
module ActionDispatch
module Assertions
@@ -14,14 +14,14 @@ module ActionDispatch
# requiring a specific HTTP method. The hash should contain a :path with the incoming request path
# and a :method containing the required HTTP verb.
#
- # # assert that POSTing to /items will call the create action on ItemsController
+ # # Asserts that POSTing to /items will call the create action on ItemsController
# 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 string will end up in the params hash correctly. To test query strings you must use the
+ # 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:
#
- # # assert that a path of '/items/list/1?view=print' returns the correct options
+ # # 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" })
#
# The +message+ parameter allows you to pass in an error message that is displayed upon failure.
@@ -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,19 +75,20 @@ 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)
expected_path = uri.path.to_s.empty? ? "/" : uri.path
end
else
- expected_path = "/#{expected_path}" unless expected_path.first == '/'
+ expected_path = "/#{expected_path}" unless expected_path.first == "/"
end
# Load routes.rb if it hasn't been loaded.
- generated_path, extra_keys = @routes.generate_extras(options, defaults)
- found_extras = options.reject { |k, _| ! extra_keys.include? k }
+ options = options.clone
+ generated_path, query_string_keys = @routes.generate_extras(options, defaults)
+ found_extras = options.reject { |k, _| ! query_string_keys.include? k }
msg = message || sprintf("found extras <%s>, not <%s>", found_extras, extras)
assert_equal(extras, found_extras, msg)
@@ -104,21 +105,21 @@ module ActionDispatch
# The +extras+ hash allows you to specify options that would normally be provided as a query string to the action. The
# +message+ parameter allows you to specify a custom error message to display upon failure.
#
- # # Assert a basic route: a controller with the default action (index)
+ # # Asserts a basic route: a controller with the default action (index)
# assert_routing '/home', controller: 'home', action: 'index'
#
# # Test a route generated with a specific controller, action, and parameter (id)
# assert_routing '/entries/show/23', controller: 'entries', action: 'show', id: 23
#
- # # Assert a basic route (controller + default action), with an error message if it fails
+ # # Asserts a basic route (controller + default action), with an error message if it fails
# assert_routing '/store', { controller: 'store', action: 'index' }, {}, {}, 'Route for store index not generated properly'
#
# # Tests a route, providing a defaults hash
# assert_routing 'controller/action/9', {id: "9", item: "square"}, {controller: "controller", action: "action"}, {}, {item: "square"}
#
- # # Tests a route with a HTTP method
+ # # 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]
@@ -126,7 +127,7 @@ module ActionDispatch
options[:controller] = "/#{controller}"
end
- generate_options = options.dup.delete_if{ |k, _| defaults.key?(k) }
+ generate_options = options.dup.delete_if { |k, _| defaults.key?(k) }
assert_generates(path.is_a?(Hash) ? path[:path] : path, generate_options, defaults, extras, message)
end
@@ -165,7 +166,7 @@ module ActionDispatch
# ROUTES TODO: These assertions should really work in an integration context
def method_missing(selector, *args, &block)
- if defined?(@controller) && @controller && @routes && @routes.named_routes.route_defined?(selector)
+ if defined?(@controller) && @controller && defined?(@routes) && @routes && @routes.named_routes.route_defined?(selector)
@controller.send(selector, *args, &block)
else
super
@@ -183,7 +184,7 @@ module ActionDispatch
end
# Assume given controller
- request = ActionController::TestRequest.new
+ request = ActionController::TestRequest.create @controller.class
if path =~ %r{://}
fail_on(URI::InvalidURIError, msg) do
@@ -201,7 +202,7 @@ module ActionDispatch
request.request_method = method if method
params = fail_on(ActionController::RoutingError, msg) do
- @routes.recognize_path(path, { :method => method, :extras => extras })
+ @routes.recognize_path(path, method: method, extras: extras)
end
request.path_parameters = params.with_indifferent_access