1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Add both HTTP Response Code and Type to assertion messages

Also, refactor logic to convert between symbol and response code,
via the AssertionResponse class
This commit is contained in:
Sean Collins 2016-01-05 14:08:17 -07:00
parent 64448c29de
commit a4032ca072
5 changed files with 84 additions and 17 deletions

View file

@ -1,3 +1,7 @@
* Provide the name of HTTP Status code in assertions.
*Sean Collins*
* More explicit error message when running `rake routes`. `CONTROLLER` argument
can now be supplied in different ways:
`Rails::WelcomeController`, `Rails::Welcome`, `rails/welcome`

View file

@ -95,6 +95,7 @@ module ActionDispatch
autoload :TestProcess
autoload :TestRequest
autoload :TestResponse
autoload :AssertionResponse
end
end

View file

@ -0,0 +1,49 @@
module ActionDispatch
# This is a class that abstracts away an asserted response.
# It purposely does not inherit from Response, because it doesn't need it.
# That means it does not have headers or a body.
#
# As an input to the initializer, we take a Fixnum, a String, or a Symbol.
# If it's a Fixnum or String, we figure out what its symbolized name.
# If it's a Symbol, we figure out what its corresponding code is.
# The resulting code will be a Fixnum, for real HTTP codes, and it will
# be a String for the pseudo-HTTP codes, such as:
# :success, :missing, :redirect and :error
class AssertionResponse
attr_reader :code, :name
GENERIC_RESPONSE_CODES = { # :nodoc:
success: "2XX",
missing: "404",
redirect: "3XX",
error: "5XX"
}
def initialize(code_or_name)
if code_or_name.is_a?(Symbol)
@name = code_or_name
@code = code_from_name(code_or_name)
else
@name = name_from_code(code_or_name)
@code = code_or_name
end
raise ArgumentError, "Invalid response name: #{name}" if @code.nil?
raise ArgumentError, "Invalid response code: #{code}" if @name.nil?
end
def code_and_name
"#{code}: #{name}"
end
private
def code_from_name(name)
GENERIC_RESPONSE_CODES[name] || Rack::Utils::SYMBOL_TO_STATUS_CODE[name]
end
def name_from_code(code)
GENERIC_RESPONSE_CODES.invert[code] || Rack::Utils::HTTP_STATUS_CODES[code]
end
end
end

View file

@ -1,4 +1,3 @@
module ActionDispatch
module Assertions
# A small suite of assertions that test responses from \Rails applications.
@ -29,18 +28,10 @@ module ActionDispatch
def assert_response(type, message = nil)
message ||= generate_response_message(type)
if Symbol === type
if [:success, :missing, :redirect, :error].include?(type)
assert @response.send(RESPONSE_PREDICATES[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
@ -85,8 +76,9 @@ module ActionDispatch
end
end
def generate_response_message(type, code = @response.response_code)
"Expected response to be a <#{type}>, but was a <#{code}>"
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
end
@ -95,6 +87,14 @@ module ActionDispatch
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

View file

@ -74,7 +74,18 @@ module ActionDispatch
@response.status = 404
error = assert_raises(Minitest::Assertion) { assert_response :success }
expected = "Expected response to be a <success>, but was a <404>"
expected = "Expected response to be a <2XX: success>,"\
" but was a <404: Not Found>"
assert_match expected, error.message
end
def test_error_message_shows_404_when_asserted_for_200
@response = ActionDispatch::Response.new
@response.status = 404
error = assert_raises(Minitest::Assertion) { assert_response 200 }
expected = "Expected response to be a <200: OK>,"\
" but was a <404: Not Found>"
assert_match expected, error.message
end
@ -84,7 +95,8 @@ module ActionDispatch
@response.location = 'http://test.host/posts/redirect/1'
error = assert_raises(Minitest::Assertion) { assert_response :success }
expected = "Expected response to be a <success>, but was a <302>" \
expected = "Expected response to be a <2XX: success>,"\
" but was a <302: Found>" \
" redirect to <http://test.host/posts/redirect/1>"
assert_match expected, error.message
end
@ -95,7 +107,8 @@ module ActionDispatch
@response.location = 'http://test.host/posts/redirect/2'
error = assert_raises(Minitest::Assertion) { assert_response 301 }
expected = "Expected response to be a <301>, but was a <302>" \
expected = "Expected response to be a <301: Moved Permanently>,"\
" but was a <302: Found>" \
" redirect to <http://test.host/posts/redirect/2>"
assert_match expected, error.message
end