aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/test/controller/action_pack_assertions_test.rb
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/test/controller/action_pack_assertions_test.rb')
-rw-r--r--actionpack/test/controller/action_pack_assertions_test.rb491
1 files changed, 491 insertions, 0 deletions
diff --git a/actionpack/test/controller/action_pack_assertions_test.rb b/actionpack/test/controller/action_pack_assertions_test.rb
new file mode 100644
index 0000000000..ecb8c37e6b
--- /dev/null
+++ b/actionpack/test/controller/action_pack_assertions_test.rb
@@ -0,0 +1,491 @@
+# frozen_string_literal: true
+
+require "abstract_unit"
+require "controller/fake_controllers"
+
+class ActionPackAssertionsController < ActionController::Base
+ def nothing() head :ok end
+
+ def hello_xml_world() render template: "test/hello_xml_world"; end
+
+ def hello_xml_world_pdf
+ self.content_type = "application/pdf"
+ render template: "test/hello_xml_world"
+ end
+
+ def hello_xml_world_pdf_header
+ response.headers["Content-Type"] = "application/pdf; charset=utf-8"
+ render template: "test/hello_xml_world"
+ end
+
+ def redirect_internal() redirect_to "/nothing"; end
+
+ def redirect_to_action() redirect_to action: "flash_me", id: 1, params: { "panda" => "fun" }; end
+
+ def redirect_to_controller() redirect_to controller: "elsewhere", action: "flash_me"; end
+
+ def redirect_to_controller_with_symbol() redirect_to controller: :elsewhere, action: :flash_me; end
+
+ def redirect_to_path() redirect_to "/some/path" end
+
+ def redirect_invalid_external_route() redirect_to "ht_tp://www.rubyonrails.org" end
+
+ def redirect_to_named_route() redirect_to route_one_url end
+
+ def redirect_external() redirect_to "http://www.rubyonrails.org"; end
+
+ def redirect_external_protocol_relative() redirect_to "//www.rubyonrails.org"; end
+
+ def response404() head "404 AWOL" end
+
+ def response500() head "500 Sorry" end
+
+ def response599() head "599 Whoah!" end
+
+ def flash_me
+ flash["hello"] = "my name is inigo montoya..."
+ render plain: "Inconceivable!"
+ end
+
+ def flash_me_naked
+ flash.clear
+ render plain: "wow!"
+ end
+
+ def assign_this
+ @howdy = "ho"
+ render inline: "Mr. Henke"
+ end
+
+ def render_based_on_parameters
+ render plain: "Mr. #{params[:name]}"
+ end
+
+ def render_url
+ render html: "<div>#{url_for(action: 'flash_me', only_path: true)}</div>"
+ end
+
+ def render_text_with_custom_content_type
+ render body: "Hello!", content_type: Mime[:rss]
+ end
+
+ def session_stuffing
+ session["xmas"] = "turkey"
+ render plain: "ho ho ho"
+ end
+
+ def raise_exception_on_get
+ raise "get" if request.get?
+ render plain: "request method: #{request.env['REQUEST_METHOD']}"
+ end
+
+ def raise_exception_on_post
+ raise "post" if request.post?
+ render plain: "request method: #{request.env['REQUEST_METHOD']}"
+ end
+
+ def render_file_absolute_path
+ render file: File.expand_path("../../README.rdoc", __dir__)
+ end
+
+ def render_file_relative_path
+ render file: "README.rdoc"
+ end
+end
+
+# Used to test that assert_response includes the exception message
+# in the failure message when an action raises and assert_response
+# is expecting something other than an error.
+class AssertResponseWithUnexpectedErrorController < ActionController::Base
+ def index
+ raise "FAIL"
+ end
+
+ def show
+ render plain: "Boom", status: 500
+ end
+end
+
+module Admin
+ class InnerModuleController < ActionController::Base
+ def index
+ head :ok
+ end
+
+ def redirect_to_index
+ redirect_to admin_inner_module_path
+ end
+
+ def redirect_to_absolute_controller
+ redirect_to controller: "/content"
+ end
+
+ def redirect_to_fellow_controller
+ redirect_to controller: "user"
+ end
+
+ def redirect_to_top_level_named_route
+ redirect_to top_level_url(id: "foo")
+ end
+ end
+end
+
+class ApiOnlyController < ActionController::API
+ def nothing
+ head :ok
+ end
+
+ def redirect_to_new_route
+ redirect_to new_route_url
+ end
+end
+
+class ActionPackAssertionsControllerTest < ActionController::TestCase
+ def test_render_file_absolute_path
+ get :render_file_absolute_path
+ assert_match(/\A= Action Pack/, @response.body)
+ end
+
+ def test_render_file_relative_path
+ get :render_file_relative_path
+ assert_match(/\A= Action Pack/, @response.body)
+ end
+
+ def test_get_request
+ assert_raise(RuntimeError) { get :raise_exception_on_get }
+ get :raise_exception_on_post
+ assert_equal "request method: GET", @response.body
+ end
+
+ def test_post_request
+ assert_raise(RuntimeError) { post :raise_exception_on_post }
+ post :raise_exception_on_get
+ assert_equal "request method: POST", @response.body
+ end
+
+ def test_get_post_request_switch
+ post :raise_exception_on_get
+ assert_equal "request method: POST", @response.body
+ get :raise_exception_on_post
+ assert_equal "request method: GET", @response.body
+ post :raise_exception_on_get
+ assert_equal "request method: POST", @response.body
+ get :raise_exception_on_post
+ assert_equal "request method: GET", @response.body
+ end
+
+ def test_string_constraint
+ with_routing do |set|
+ set.draw do
+ get "photos", to: "action_pack_assertions#nothing", constraints: { subdomain: "admin" }
+ end
+ end
+ end
+
+ def test_with_routing_works_with_api_only_controllers
+ @controller = ApiOnlyController.new
+
+ with_routing do |set|
+ set.draw do
+ get "new_route", to: "api_only#nothing"
+ get "redirect_to_new_route", to: "api_only#redirect_to_new_route"
+ end
+
+ process :redirect_to_new_route
+ assert_redirected_to "http://test.host/new_route"
+ end
+ end
+
+ def test_assert_redirect_to_named_route_failure
+ with_routing do |set|
+ set.draw do
+ get "route_one", to: "action_pack_assertions#nothing", as: :route_one
+ get "route_two", to: "action_pack_assertions#nothing", id: "two", as: :route_two
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
+ end
+ process :redirect_to_named_route
+ assert_raise(ActiveSupport::TestCase::Assertion) do
+ assert_redirected_to "http://test.host/route_two"
+ end
+ assert_raise(ActiveSupport::TestCase::Assertion) do
+ assert_redirected_to %r(^http://test.host/route_two)
+ end
+ assert_raise(ActiveSupport::TestCase::Assertion) do
+ assert_redirected_to controller: "action_pack_assertions", action: "nothing", id: "two"
+ end
+ assert_raise(ActiveSupport::TestCase::Assertion) do
+ assert_redirected_to route_two_url
+ end
+ end
+ end
+
+ def test_assert_redirect_to_nested_named_route
+ @controller = Admin::InnerModuleController.new
+
+ with_routing do |set|
+ set.draw do
+ get "admin/inner_module", to: "admin/inner_module#index", as: :admin_inner_module
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
+ end
+ process :redirect_to_index
+ # redirection is <{"action"=>"index", "controller"=>"admin/admin/inner_module"}>
+ assert_redirected_to admin_inner_module_path
+ end
+ end
+
+ def test_assert_redirected_to_top_level_named_route_from_nested_controller
+ @controller = Admin::InnerModuleController.new
+
+ with_routing do |set|
+ set.draw do
+ get "/action_pack_assertions/:id", to: "action_pack_assertions#index", as: :top_level
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
+ end
+ process :redirect_to_top_level_named_route
+ # assert_redirected_to "http://test.host/action_pack_assertions/foo" would pass because of exact match early return
+ assert_redirected_to "/action_pack_assertions/foo"
+ assert_redirected_to %r(/action_pack_assertions/foo)
+ end
+ end
+
+ def test_assert_redirected_to_top_level_named_route_with_same_controller_name_in_both_namespaces
+ @controller = Admin::InnerModuleController.new
+
+ with_routing do |set|
+ set.draw do
+ # this controller exists in the admin namespace as well which is the only difference from previous test
+ get "/user/:id", to: "user#index", as: :top_level
+
+ ActiveSupport::Deprecation.silence do
+ get ":controller/:action"
+ end
+ end
+ process :redirect_to_top_level_named_route
+ # assert_redirected_to top_level_url('foo') would pass because of exact match early return
+ assert_redirected_to top_level_path("foo")
+ end
+ end
+
+ def test_assert_redirect_failure_message_with_protocol_relative_url
+ process :redirect_external_protocol_relative
+ assert_redirected_to "/foo"
+ rescue ActiveSupport::TestCase::Assertion => ex
+ assert_no_match(
+ /#{request.protocol}#{request.host}\/\/www.rubyonrails.org/,
+ ex.message,
+ "protocol relative url was incorrectly normalized"
+ )
+ end
+
+ def test_template_objects_exist
+ process :assign_this
+ assert_not @controller.instance_variable_defined?(:"@hi")
+ assert @controller.instance_variable_get(:"@howdy")
+ end
+
+ def test_template_objects_missing
+ process :nothing
+ assert_not @controller.instance_variable_defined?(:@howdy)
+ end
+
+ def test_empty_flash
+ process :flash_me_naked
+ assert_empty flash
+ end
+
+ def test_flash_exist
+ process :flash_me
+ assert_predicate flash, :any?
+ assert_predicate flash["hello"], :present?
+ end
+
+ def test_flash_does_not_exist
+ process :nothing
+ assert_empty flash
+ end
+
+ def test_session_exist
+ process :session_stuffing
+ assert_equal "turkey", session["xmas"]
+ end
+
+ def session_does_not_exist
+ process :nothing
+ assert_empty session
+ end
+
+ def test_redirection_location
+ process :redirect_internal
+ assert_equal "http://test.host/nothing", @response.redirect_url
+
+ process :redirect_external
+ assert_equal "http://www.rubyonrails.org", @response.redirect_url
+
+ process :redirect_external_protocol_relative
+ assert_equal "//www.rubyonrails.org", @response.redirect_url
+ end
+
+ def test_no_redirect_url
+ process :nothing
+ assert_nil @response.redirect_url
+ end
+
+ def test_server_error_response_code
+ process :response500
+ assert_predicate @response, :server_error?
+
+ process :response599
+ assert_predicate @response, :server_error?
+
+ process :response404
+ assert_not_predicate @response, :server_error?
+ end
+
+ def test_missing_response_code
+ process :response404
+ assert_predicate @response, :not_found?
+ end
+
+ def test_client_error_response_code
+ process :response404
+ assert_predicate @response, :client_error?
+ end
+
+ def test_redirect_url_match
+ process :redirect_external
+ assert_predicate @response, :redirect?
+ assert_match(/rubyonrails/, @response.redirect_url)
+ assert_no_match(/perloffrails/, @response.redirect_url)
+ end
+
+ def test_redirection
+ process :redirect_internal
+ assert_predicate @response, :redirect?
+
+ process :redirect_external
+ assert_predicate @response, :redirect?
+
+ process :nothing
+ assert_not_predicate @response, :redirect?
+ end
+
+ def test_successful_response_code
+ process :nothing
+ assert_predicate @response, :successful?
+ end
+
+ def test_response_object
+ process :nothing
+ assert_kind_of ActionDispatch::TestResponse, @response
+ end
+
+ def test_render_based_on_parameters
+ process :render_based_on_parameters,
+ method: "GET",
+ params: { name: "David" }
+ assert_equal "Mr. David", @response.body
+ end
+
+ def test_assert_redirection_fails_with_incorrect_controller
+ process :redirect_to_controller
+ assert_raise(ActiveSupport::TestCase::Assertion) do
+ assert_redirected_to controller: "action_pack_assertions", action: "flash_me"
+ end
+ end
+
+ def test_assert_redirection_with_extra_controller_option
+ get :redirect_to_action
+ assert_redirected_to controller: "action_pack_assertions", action: "flash_me", id: 1, params: { panda: "fun" }
+ end
+
+ def test_redirected_to_url_leading_slash
+ process :redirect_to_path
+ assert_redirected_to "/some/path"
+ end
+
+ def test_redirected_to_url_no_leading_slash_fails
+ process :redirect_to_path
+ assert_raise ActiveSupport::TestCase::Assertion do
+ assert_redirected_to "some/path"
+ end
+ end
+
+ def test_redirect_invalid_external_route
+ process :redirect_invalid_external_route
+ assert_redirected_to "http://test.hostht_tp://www.rubyonrails.org"
+ end
+
+ def test_redirected_to_url_full_url
+ process :redirect_to_path
+ assert_redirected_to "http://test.host/some/path"
+ end
+
+ def test_assert_redirection_with_symbol
+ process :redirect_to_controller_with_symbol
+ assert_nothing_raised {
+ assert_redirected_to controller: "elsewhere", action: "flash_me"
+ }
+ process :redirect_to_controller_with_symbol
+ assert_nothing_raised {
+ assert_redirected_to controller: :elsewhere, action: :flash_me
+ }
+ end
+
+ def test_redirected_to_with_nested_controller
+ @controller = Admin::InnerModuleController.new
+ get :redirect_to_absolute_controller
+ assert_redirected_to controller: "/content"
+
+ get :redirect_to_fellow_controller
+ assert_redirected_to controller: "admin/user"
+ end
+
+ def test_assert_response_uses_exception_message
+ @controller = AssertResponseWithUnexpectedErrorController.new
+ e = assert_raise RuntimeError, "Expected non-success response" do
+ get :index
+ end
+ assert_response :success
+ assert_includes "FAIL", e.message
+ end
+
+ def test_assert_response_failure_response_with_no_exception
+ @controller = AssertResponseWithUnexpectedErrorController.new
+ get :show
+ assert_response 500
+ assert_equal "Boom", response.body
+ end
+end
+
+class ActionPackHeaderTest < ActionController::TestCase
+ tests ActionPackAssertionsController
+
+ def test_rendering_xml_sets_content_type
+ process :hello_xml_world
+ assert_equal("application/xml; charset=utf-8", @response.headers["Content-Type"])
+ end
+
+ def test_rendering_xml_respects_content_type
+ process :hello_xml_world_pdf
+ assert_equal("application/pdf; charset=utf-8", @response.headers["Content-Type"])
+ end
+
+ def test_rendering_xml_respects_content_type_when_set_in_the_header
+ process :hello_xml_world_pdf_header
+ assert_equal("application/pdf; charset=utf-8", @response.headers["Content-Type"])
+ end
+
+ def test_render_text_with_custom_content_type
+ get :render_text_with_custom_content_type
+ assert_equal "application/rss+xml; charset=utf-8", @response.headers["Content-Type"]
+ end
+end