rails--rails/actionview/test/actionpack/abstract/abstract_controller_test.rb

305 lines
8.4 KiB
Ruby

# frozen_string_literal: true
require "abstract_unit"
require "set"
module AbstractController
module Testing
# Test basic dispatching.
# ====
# * Call process
# * Test that the response_body is set correctly
class SimpleController < AbstractController::Base
end
class Me < SimpleController
def index
self.response_body = "Hello world"
"Something else"
end
end
class TestBasic < ActiveSupport::TestCase
test "dispatching works" do
controller = Me.new
controller.process(:index)
assert_equal "Hello world", controller.response_body
end
end
# Test Render mixin
# ====
class RenderingController < AbstractController::Base
include AbstractController::Rendering
include ActionView::Rendering
def _prefixes
[]
end
def render(options = {})
if options.is_a?(String)
options = { _template_name: options }
end
super
end
append_view_path File.expand_path("views", __dir__)
end
class Me2 < RenderingController
def index
render "index.erb"
end
def with_final_newline
render "with_final_newline.erb"
end
def index_to_string
self.response_body = render_to_string "index"
end
def action_with_ivars
@my_ivar = "Hello"
render "action_with_ivars.erb"
end
def naked_render
render
end
def rendering_to_body
self.response_body = render_to_body template: "naked_render"
end
def rendering_to_string
self.response_body = render_to_string template: "naked_render"
end
end
class TestRenderingController < ActiveSupport::TestCase
def setup
@controller = Me2.new
end
test "rendering templates works" do
@controller.process(:index)
assert_equal "Hello from index.erb", @controller.response_body
end
test "stripping final newline works" do
ActionView::Template::Handlers::ERB.strip_trailing_newlines = true
@controller.process(:with_final_newline)
assert_equal "Hello from with_final_newline.erb", @controller.response_body
ensure
ActionView::Template::Handlers::ERB.strip_trailing_newlines = false
end
test "render_to_string works with a String as an argument" do
@controller.process(:index_to_string)
assert_equal "Hello from index.erb", @controller.response_body
end
test "rendering passes ivars to the view" do
@controller.process(:action_with_ivars)
assert_equal "Hello from index_with_ivars.erb", @controller.response_body
end
test "rendering with no template name" do
@controller.process(:naked_render)
assert_equal "Hello from naked_render.erb", @controller.response_body
end
test "rendering to a rack body" do
@controller.process(:rendering_to_body)
assert_equal "Hello from naked_render.erb", @controller.response_body
end
test "rendering to a string" do
@controller.process(:rendering_to_string)
assert_equal "Hello from naked_render.erb", @controller.response_body
end
end
# Test rendering with prefixes
# ====
# * self._prefix is used when defined
class PrefixedViews < RenderingController
private
def self.prefix
name.underscore
end
def _prefixes
[self.class.prefix]
end
end
class Me3 < PrefixedViews
def index
render
end
def formatted
self.formats = [:html]
render
end
end
class TestPrefixedViews < ActiveSupport::TestCase
def setup
@controller = Me3.new
end
test "templates are located inside their 'prefix' folder" do
@controller.process(:index)
assert_equal "Hello from me3/index.erb", @controller.response_body
end
test "templates included their format" do
@controller.process(:formatted)
assert_equal "Hello from me3/formatted.html.erb", @controller.response_body
end
end
class OverridingLocalPrefixes < AbstractController::Base
include AbstractController::Rendering
include ActionView::Rendering
append_view_path File.expand_path("views", __dir__)
def index
render
end
def self.local_prefixes
# this would usually return "abstract_controller/testing/overriding_local_prefixes"
super + ["abstract_controller/testing/me3"]
end
class Inheriting < self
end
end
class OverridingLocalPrefixesTest < ActiveSupport::TestCase
test "overriding .local_prefixes adds prefix" do
@controller = OverridingLocalPrefixes.new
@controller.process(:index)
assert_equal "Hello from me3/index.erb", @controller.response_body
end
test ".local_prefixes is inherited" do
@controller = OverridingLocalPrefixes::Inheriting.new
@controller.process(:index)
assert_equal "Hello from me3/index.erb", @controller.response_body
end
end
# Test rendering with layouts
# ====
# self._layout is used when defined
class WithLayouts < PrefixedViews
include ActionView::Layouts
private
def self.layout(formats)
find_template(name.underscore, { formats: formats }, { _prefixes: ["layouts"] })
rescue ActionView::MissingTemplate
begin
find_template("application", { formats: formats }, { _prefixes: ["layouts"] })
rescue ActionView::MissingTemplate
end
end
def render_to_body(options = {})
options[:_layout] = options[:layout] || _default_layout({})
super
end
end
class Me4 < WithLayouts
def index
render
end
end
class TestLayouts < ActiveSupport::TestCase
test "layouts are included" do
controller = Me4.new
controller.process(:index)
assert_equal "Me4 Enter : Hello from me4/index.erb : Exit", controller.response_body
end
end
# respond_to_action?(action_name)
# ====
# * A method can be used as an action only if this method
# returns true when passed the method name as an argument
# * Defaults to true in AbstractController
class DefaultRespondToActionController < AbstractController::Base
def index() self.response_body = "success" end
end
class ActionMissingRespondToActionController < AbstractController::Base
# No actions
private
def action_missing(action_name)
self.response_body = "success"
end
end
class RespondToActionController < AbstractController::Base
def index() self.response_body = "success" end
def fail() self.response_body = "fail" end
private
def method_for_action(action_name)
action_name.to_s != "fail" && action_name
end
end
class TestRespondToAction < ActiveSupport::TestCase
def assert_dispatch(klass, body = "success", action = :index)
controller = klass.new
controller.process(action)
assert_equal body, controller.response_body
end
test "an arbitrary method is available as an action by default" do
assert_dispatch DefaultRespondToActionController, "success", :index
end
test "raises ActionNotFound when method does not exist and action_missing is not defined" do
assert_raise(ActionNotFound) { DefaultRespondToActionController.new.process(:fail) }
end
test "dispatches to action_missing when method does not exist and action_missing is defined" do
assert_dispatch ActionMissingRespondToActionController, "success", :ohai
end
test "a method is available as an action if method_for_action returns true" do
assert_dispatch RespondToActionController, "success", :index
end
test "raises ActionNotFound if method is defined but method_for_action returns false" do
assert_raise(ActionNotFound) { RespondToActionController.new.process(:fail) }
end
end
class Me6 < AbstractController::Base
action_methods
def index
end
end
class TestActionMethodsReloading < ActiveSupport::TestCase
test "action_methods should be reloaded after defining a new method" do
assert_equal Set.new(["index"]), Me6.action_methods
end
end
end
end