mirror of
https://github.com/rails/rails.git
synced 2022-11-09 12:12:34 -05:00
Merge commit 'rails/master'
This commit is contained in:
commit
d3042ef80c
48 changed files with 580 additions and 713 deletions
|
@ -60,7 +60,7 @@ module ActionController
|
||||||
autoload :Redirector, 'action_controller/base/redirect'
|
autoload :Redirector, 'action_controller/base/redirect'
|
||||||
autoload :Renderer, 'action_controller/base/render'
|
autoload :Renderer, 'action_controller/base/render'
|
||||||
autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection'
|
autoload :RequestForgeryProtection, 'action_controller/base/request_forgery_protection'
|
||||||
autoload :Rescue, 'action_controller/dispatch/rescue'
|
autoload :Rescue, 'action_controller/base/rescue'
|
||||||
autoload :Resources, 'action_controller/routing/resources'
|
autoload :Resources, 'action_controller/routing/resources'
|
||||||
autoload :Responder, 'action_controller/base/responder'
|
autoload :Responder, 'action_controller/base/responder'
|
||||||
autoload :Routing, 'action_controller/routing'
|
autoload :Routing, 'action_controller/routing'
|
||||||
|
|
|
@ -30,10 +30,6 @@ module ActionController #:nodoc:
|
||||||
def allowed_methods_header
|
def allowed_methods_header
|
||||||
allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', '
|
allowed_methods.map { |method_symbol| method_symbol.to_s.upcase } * ', '
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_response!(response)
|
|
||||||
response.headers['Allow'] ||= allowed_methods_header
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class NotImplemented < MethodNotAllowed #:nodoc:
|
class NotImplemented < MethodNotAllowed #:nodoc:
|
||||||
|
@ -371,14 +367,12 @@ module ActionController #:nodoc:
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def call(env)
|
def call(env)
|
||||||
# HACK: For global rescue to have access to the original request and response
|
new.call(env)
|
||||||
request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
|
|
||||||
response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
|
|
||||||
process(request, response)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Factory for the standard create, process loop where the controller is discarded after processing.
|
# Factory for the standard create, process loop where the controller is discarded after processing.
|
||||||
def process(request, response) #:nodoc:
|
def process(request, response) #:nodoc:
|
||||||
|
ActiveSupport::Deprecation.warn("Controller.process has been deprecated. Use Controller.call instead", caller)
|
||||||
new.process(request, response)
|
new.process(request, response)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -511,6 +505,12 @@ module ActionController #:nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
public
|
public
|
||||||
|
def call(env)
|
||||||
|
request = ActionDispatch::Request.new(env)
|
||||||
|
response = ActionDispatch::Response.new
|
||||||
|
process(request, response).to_a
|
||||||
|
end
|
||||||
|
|
||||||
# Extracts the action_name from the request parameters and performs that action.
|
# Extracts the action_name from the request parameters and performs that action.
|
||||||
def process(request, response, method = :perform_action, *arguments) #:nodoc:
|
def process(request, response, method = :perform_action, *arguments) #:nodoc:
|
||||||
response.request = request
|
response.request = request
|
||||||
|
@ -820,7 +820,6 @@ module ActionController #:nodoc:
|
||||||
@template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
|
@template = ActionView::Base.new(self.class.view_paths, {}, self, formats)
|
||||||
response.template = @template if response.respond_to?(:template=)
|
response.template = @template if response.respond_to?(:template=)
|
||||||
@template.helpers.send :include, self.class.master_helper_module
|
@template.helpers.send :include, self.class.master_helper_module
|
||||||
response.redirected_to = nil
|
|
||||||
@performed_render = @performed_redirect = false
|
@performed_render = @performed_redirect = false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -48,8 +48,6 @@ module ActionController
|
||||||
status = 302
|
status = 302
|
||||||
end
|
end
|
||||||
|
|
||||||
response.redirected_to = options
|
|
||||||
|
|
||||||
case options
|
case options
|
||||||
# The scheme name consist of a letter followed by any combination of
|
# The scheme name consist of a letter followed by any combination of
|
||||||
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
||||||
|
@ -82,8 +80,6 @@ module ActionController
|
||||||
# The response body is not reset here, see +erase_render_results+
|
# The response body is not reset here, see +erase_render_results+
|
||||||
def erase_redirect_results #:nodoc:
|
def erase_redirect_results #:nodoc:
|
||||||
@performed_redirect = false
|
@performed_redirect = false
|
||||||
response.redirected_to = nil
|
|
||||||
response.redirected_to_method_params = nil
|
|
||||||
response.status = DEFAULT_RENDER_STATUS_CODE
|
response.status = DEFAULT_RENDER_STATUS_CODE
|
||||||
response.headers.delete('Location')
|
response.headers.delete('Location')
|
||||||
end
|
end
|
||||||
|
|
50
actionpack/lib/action_controller/base/rescue.rb
Normal file
50
actionpack/lib/action_controller/base/rescue.rb
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
module ActionController #:nodoc:
|
||||||
|
# Actions that fail to perform as expected throw exceptions. These
|
||||||
|
# exceptions can either be rescued for the public view (with a nice
|
||||||
|
# user-friendly explanation) or for the developers view (with tons of
|
||||||
|
# debugging information). The developers view is already implemented by
|
||||||
|
# the Action Controller, but the public view should be tailored to your
|
||||||
|
# specific application.
|
||||||
|
#
|
||||||
|
# The default behavior for public exceptions is to render a static html
|
||||||
|
# file with the name of the error code thrown. If no such file exists, an
|
||||||
|
# empty response is sent with the correct status code.
|
||||||
|
#
|
||||||
|
# You can override what constitutes a local request by overriding the
|
||||||
|
# <tt>local_request?</tt> method in your own controller. Custom rescue
|
||||||
|
# behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
|
||||||
|
# and <tt>rescue_action_locally</tt> methods.
|
||||||
|
module Rescue
|
||||||
|
def self.included(base) #:nodoc:
|
||||||
|
base.send :include, ActiveSupport::Rescuable
|
||||||
|
base.extend(ClassMethods)
|
||||||
|
|
||||||
|
base.class_eval do
|
||||||
|
alias_method_chain :perform_action, :rescue
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ClassMethods
|
||||||
|
def rescue_action(env)
|
||||||
|
exception = env.delete('action_dispatch.rescue.exception')
|
||||||
|
request = ActionDispatch::Request.new(env)
|
||||||
|
response = ActionDispatch::Response.new
|
||||||
|
new.process(request, response, :rescue_action, exception).to_a
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
# Exception handler called when the performance of an action raises
|
||||||
|
# an exception.
|
||||||
|
def rescue_action(exception)
|
||||||
|
rescue_with_handler(exception) || raise(exception)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
def perform_action_with_rescue
|
||||||
|
perform_action_without_rescue
|
||||||
|
rescue Exception => exception
|
||||||
|
rescue_action(exception)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,9 +5,9 @@ module ActionController
|
||||||
class << self
|
class << self
|
||||||
def define_dispatcher_callbacks(cache_classes)
|
def define_dispatcher_callbacks(cache_classes)
|
||||||
unless cache_classes
|
unless cache_classes
|
||||||
unless self.middleware.include?(ActionDispatch::Reloader)
|
# Development mode callbacks
|
||||||
self.middleware.insert_after(ActionDispatch::Failsafe, ActionDispatch::Reloader)
|
before_dispatch :reload_application
|
||||||
end
|
after_dispatch :cleanup_application
|
||||||
|
|
||||||
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
|
ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false
|
||||||
end
|
end
|
||||||
|
@ -40,22 +40,11 @@ module ActionController
|
||||||
def run_prepare_callbacks
|
def run_prepare_callbacks
|
||||||
new.send :run_callbacks, :prepare_dispatch
|
new.send :run_callbacks, :prepare_dispatch
|
||||||
end
|
end
|
||||||
|
|
||||||
def reload_application
|
|
||||||
# Run prepare callbacks before every request in development mode
|
|
||||||
run_prepare_callbacks
|
|
||||||
|
|
||||||
Routing::Routes.reload
|
|
||||||
end
|
|
||||||
|
|
||||||
def cleanup_application
|
|
||||||
# Cleanup the application before processing the current request.
|
|
||||||
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
|
|
||||||
ActiveSupport::Dependencies.clear
|
|
||||||
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
cattr_accessor :router
|
||||||
|
self.router = Routing::Routes
|
||||||
|
|
||||||
cattr_accessor :middleware
|
cattr_accessor :middleware
|
||||||
self.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
|
self.middleware = ActionDispatch::MiddlewareStack.new do |middleware|
|
||||||
middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
|
middlewares = File.join(File.dirname(__FILE__), "middlewares.rb")
|
||||||
|
@ -66,27 +55,29 @@ module ActionController
|
||||||
define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
|
define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
@app = @@middleware.build(lambda { |env| self._call(env) })
|
@app = @@middleware.build(@@router)
|
||||||
freeze
|
freeze
|
||||||
end
|
end
|
||||||
|
|
||||||
def call(env)
|
def call(env)
|
||||||
|
run_callbacks :before_dispatch
|
||||||
@app.call(env)
|
@app.call(env)
|
||||||
|
ensure
|
||||||
|
run_callbacks :after_dispatch, :enumerator => :reverse_each
|
||||||
end
|
end
|
||||||
|
|
||||||
def _call(env)
|
def reload_application
|
||||||
begin
|
# Run prepare callbacks before every request in development mode
|
||||||
run_callbacks :before_dispatch
|
run_callbacks :prepare_dispatch
|
||||||
Routing::Routes.call(env)
|
|
||||||
rescue Exception => exception
|
@@router.reload
|
||||||
if controller ||= (::ApplicationController rescue Base)
|
end
|
||||||
controller.call_with_exception(env, exception).to_a
|
|
||||||
else
|
def cleanup_application
|
||||||
raise exception
|
# Cleanup the application before processing the current request.
|
||||||
end
|
ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord)
|
||||||
ensure
|
ActiveSupport::Dependencies.clear
|
||||||
run_callbacks :after_dispatch, :enumerator => :reverse_each
|
ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def flush_logger
|
def flush_logger
|
||||||
|
|
|
@ -3,6 +3,11 @@ use "Rack::Lock", :if => lambda {
|
||||||
}
|
}
|
||||||
|
|
||||||
use "ActionDispatch::Failsafe"
|
use "ActionDispatch::Failsafe"
|
||||||
|
use "ActionDispatch::ShowExceptions", lambda { ActionController::Base.consider_all_requests_local }
|
||||||
|
use "ActionDispatch::Rescue", lambda {
|
||||||
|
controller = (::ApplicationController rescue ActionController::Base)
|
||||||
|
controller.method(:rescue_action)
|
||||||
|
}
|
||||||
|
|
||||||
use lambda { ActionController::Base.session_store },
|
use lambda { ActionController::Base.session_store },
|
||||||
lambda { ActionController::Base.session_options }
|
lambda { ActionController::Base.session_options }
|
||||||
|
|
|
@ -1,185 +0,0 @@
|
||||||
module ActionController #:nodoc:
|
|
||||||
# Actions that fail to perform as expected throw exceptions. These
|
|
||||||
# exceptions can either be rescued for the public view (with a nice
|
|
||||||
# user-friendly explanation) or for the developers view (with tons of
|
|
||||||
# debugging information). The developers view is already implemented by
|
|
||||||
# the Action Controller, but the public view should be tailored to your
|
|
||||||
# specific application.
|
|
||||||
#
|
|
||||||
# The default behavior for public exceptions is to render a static html
|
|
||||||
# file with the name of the error code thrown. If no such file exists, an
|
|
||||||
# empty response is sent with the correct status code.
|
|
||||||
#
|
|
||||||
# You can override what constitutes a local request by overriding the
|
|
||||||
# <tt>local_request?</tt> method in your own controller. Custom rescue
|
|
||||||
# behavior is achieved by overriding the <tt>rescue_action_in_public</tt>
|
|
||||||
# and <tt>rescue_action_locally</tt> methods.
|
|
||||||
module Rescue
|
|
||||||
LOCALHOST = '127.0.0.1'.freeze
|
|
||||||
|
|
||||||
DEFAULT_RESCUE_RESPONSE = :internal_server_error
|
|
||||||
DEFAULT_RESCUE_RESPONSES = {
|
|
||||||
'ActionController::RoutingError' => :not_found,
|
|
||||||
'ActionController::UnknownAction' => :not_found,
|
|
||||||
'ActiveRecord::RecordNotFound' => :not_found,
|
|
||||||
'ActiveRecord::StaleObjectError' => :conflict,
|
|
||||||
'ActiveRecord::RecordInvalid' => :unprocessable_entity,
|
|
||||||
'ActiveRecord::RecordNotSaved' => :unprocessable_entity,
|
|
||||||
'ActionController::MethodNotAllowed' => :method_not_allowed,
|
|
||||||
'ActionController::NotImplemented' => :not_implemented,
|
|
||||||
'ActionController::InvalidAuthenticityToken' => :unprocessable_entity
|
|
||||||
}
|
|
||||||
|
|
||||||
DEFAULT_RESCUE_TEMPLATE = 'diagnostics'
|
|
||||||
DEFAULT_RESCUE_TEMPLATES = {
|
|
||||||
'ActionView::MissingTemplate' => 'missing_template',
|
|
||||||
'ActionController::RoutingError' => 'routing_error',
|
|
||||||
'ActionController::UnknownAction' => 'unknown_action',
|
|
||||||
'ActionView::TemplateError' => 'template_error'
|
|
||||||
}
|
|
||||||
|
|
||||||
RESCUES_TEMPLATE_PATH = ActionView::Template::FileSystemPath.new(
|
|
||||||
File.join(File.dirname(__FILE__), "templates"))
|
|
||||||
|
|
||||||
def self.included(base) #:nodoc:
|
|
||||||
base.cattr_accessor :rescue_responses
|
|
||||||
base.rescue_responses = Hash.new(DEFAULT_RESCUE_RESPONSE)
|
|
||||||
base.rescue_responses.update DEFAULT_RESCUE_RESPONSES
|
|
||||||
|
|
||||||
base.cattr_accessor :rescue_templates
|
|
||||||
base.rescue_templates = Hash.new(DEFAULT_RESCUE_TEMPLATE)
|
|
||||||
base.rescue_templates.update DEFAULT_RESCUE_TEMPLATES
|
|
||||||
|
|
||||||
base.extend(ClassMethods)
|
|
||||||
base.send :include, ActiveSupport::Rescuable
|
|
||||||
|
|
||||||
base.class_eval do
|
|
||||||
alias_method_chain :perform_action, :rescue
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
module ClassMethods
|
|
||||||
def call_with_exception(env, exception) #:nodoc:
|
|
||||||
request = env["action_controller.rescue.request"] ||= ActionDispatch::Request.new(env)
|
|
||||||
response = env["action_controller.rescue.response"] ||= ActionDispatch::Response.new
|
|
||||||
new.process(request, response, :rescue_action, exception)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
# Exception handler called when the performance of an action raises
|
|
||||||
# an exception.
|
|
||||||
def rescue_action(exception)
|
|
||||||
rescue_with_handler(exception) ||
|
|
||||||
rescue_action_without_handler(exception)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Overwrite to implement custom logging of errors. By default
|
|
||||||
# logs as fatal.
|
|
||||||
def log_error(exception) #:doc:
|
|
||||||
ActiveSupport::Deprecation.silence do
|
|
||||||
if ActionView::TemplateError === exception
|
|
||||||
logger.fatal(exception.to_s)
|
|
||||||
else
|
|
||||||
logger.fatal(
|
|
||||||
"\n#{exception.class} (#{exception.message}):\n " +
|
|
||||||
clean_backtrace(exception).join("\n ") + "\n\n"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Overwrite to implement public exception handling (for requests
|
|
||||||
# answering false to <tt>local_request?</tt>). By default will call
|
|
||||||
# render_optional_error_file. Override this method to provide more
|
|
||||||
# user friendly error messages.
|
|
||||||
def rescue_action_in_public(exception) #:doc:
|
|
||||||
render_optional_error_file response_code_for_rescue(exception)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Attempts to render a static error page based on the
|
|
||||||
# <tt>status_code</tt> thrown, or just return headers if no such file
|
|
||||||
# exists. At first, it will try to render a localized static page.
|
|
||||||
# For example, if a 500 error is being handled Rails and locale is :da,
|
|
||||||
# it will first attempt to render the file at <tt>public/500.da.html</tt>
|
|
||||||
# then attempt to render <tt>public/500.html</tt>. If none of them exist,
|
|
||||||
# the body of the response will be left empty.
|
|
||||||
def render_optional_error_file(status_code)
|
|
||||||
status = interpret_status(status_code)
|
|
||||||
locale_path = "#{Rails.public_path}/#{status[0,3]}.#{I18n.locale}.html" if I18n.locale
|
|
||||||
path = "#{Rails.public_path}/#{status[0,3]}.html"
|
|
||||||
|
|
||||||
if locale_path && File.exist?(locale_path)
|
|
||||||
render :file => locale_path, :status => status, :content_type => Mime::HTML
|
|
||||||
elsif File.exist?(path)
|
|
||||||
render :file => path, :status => status, :content_type => Mime::HTML
|
|
||||||
else
|
|
||||||
head status
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# True if the request came from localhost, 127.0.0.1. Override this
|
|
||||||
# method if you wish to redefine the meaning of a local request to
|
|
||||||
# include remote IP addresses or other criteria.
|
|
||||||
def local_request? #:doc:
|
|
||||||
request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
|
|
||||||
end
|
|
||||||
|
|
||||||
# Render detailed diagnostics for unhandled exceptions rescued from
|
|
||||||
# a controller action.
|
|
||||||
def rescue_action_locally(exception)
|
|
||||||
@template.instance_variable_set("@exception", exception)
|
|
||||||
@template.instance_variable_set("@rescues_path", RESCUES_TEMPLATE_PATH)
|
|
||||||
@template.instance_variable_set("@contents",
|
|
||||||
@template._render_template(template_path_for_local_rescue(exception)))
|
|
||||||
|
|
||||||
response.content_type = Mime::HTML
|
|
||||||
response.status = interpret_status(response_code_for_rescue(exception))
|
|
||||||
|
|
||||||
content = @template._render_template(rescues_path("layout"))
|
|
||||||
render_for_text(content)
|
|
||||||
end
|
|
||||||
|
|
||||||
def rescue_action_without_handler(exception)
|
|
||||||
log_error(exception) if logger
|
|
||||||
erase_results if performed?
|
|
||||||
|
|
||||||
# Let the exception alter the response if it wants.
|
|
||||||
# For example, MethodNotAllowed sets the Allow header.
|
|
||||||
if exception.respond_to?(:handle_response!)
|
|
||||||
exception.handle_response!(response)
|
|
||||||
end
|
|
||||||
|
|
||||||
if consider_all_requests_local || local_request?
|
|
||||||
rescue_action_locally(exception)
|
|
||||||
else
|
|
||||||
rescue_action_in_public(exception)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
def perform_action_with_rescue #:nodoc:
|
|
||||||
perform_action_without_rescue
|
|
||||||
rescue Exception => exception
|
|
||||||
rescue_action(exception)
|
|
||||||
end
|
|
||||||
|
|
||||||
def rescues_path(template_name)
|
|
||||||
RESCUES_TEMPLATE_PATH.find_by_parts("rescues/#{template_name}.erb")
|
|
||||||
end
|
|
||||||
|
|
||||||
def template_path_for_local_rescue(exception)
|
|
||||||
rescues_path(rescue_templates[exception.class.name])
|
|
||||||
end
|
|
||||||
|
|
||||||
def response_code_for_rescue(exception)
|
|
||||||
rescue_responses[exception.class.name]
|
|
||||||
end
|
|
||||||
|
|
||||||
def clean_backtrace(exception)
|
|
||||||
defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) ?
|
|
||||||
Rails.backtrace_cleaner.clean(exception.backtrace) :
|
|
||||||
exception.backtrace
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,10 +0,0 @@
|
||||||
<h1>
|
|
||||||
<%=h @exception.class.to_s %>
|
|
||||||
<% if request.parameters['controller'] %>
|
|
||||||
in <%=h request.parameters['controller'].humanize %>Controller<% if request.parameters['action'] %>#<%=h request.parameters['action'] %><% end %>
|
|
||||||
<% end %>
|
|
||||||
</h1>
|
|
||||||
<pre><%=h @exception.clean_message %></pre>
|
|
||||||
|
|
||||||
<%= @template._render_template(@rescues_path.find_by_parts("rescues/_trace.erb")) %>
|
|
||||||
<%= @template._render_template(@rescues_path.find_by_parts("rescues/_request_and_response.erb")) %>
|
|
|
@ -430,7 +430,7 @@ module ActionController
|
||||||
def call(env)
|
def call(env)
|
||||||
request = ActionDispatch::Request.new(env)
|
request = ActionDispatch::Request.new(env)
|
||||||
app = Routing::Routes.recognize(request)
|
app = Routing::Routes.recognize(request)
|
||||||
app.call(env).to_a
|
app.call(env)
|
||||||
end
|
end
|
||||||
|
|
||||||
def recognize(request)
|
def recognize(request)
|
||||||
|
|
|
@ -35,27 +35,27 @@ module ActionController #:nodoc:
|
||||||
end
|
end
|
||||||
|
|
||||||
data = params.to_query
|
data = params.to_query
|
||||||
@env['CONTENT_LENGTH'] = data.length
|
@env['CONTENT_LENGTH'] = data.length.to_s
|
||||||
@env['rack.input'] = StringIO.new(data)
|
@env['rack.input'] = StringIO.new(data)
|
||||||
end
|
end
|
||||||
|
|
||||||
def recycle!
|
def recycle!
|
||||||
@env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
|
@env.delete_if { |k, v| k =~ /^(action_dispatch|rack)\.request/ }
|
||||||
|
@env.delete_if { |k, v| k =~ /^action_dispatch\.rescue/ }
|
||||||
@env['action_dispatch.request.query_parameters'] = {}
|
@env['action_dispatch.request.query_parameters'] = {}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Integration test methods such as ActionController::Integration::Session#get
|
|
||||||
# and ActionController::Integration::Session#post return objects of class
|
|
||||||
# TestResponse, which represent the HTTP response results of the requested
|
|
||||||
# controller actions.
|
|
||||||
#
|
|
||||||
# See Response for more information on controller response objects.
|
|
||||||
class TestResponse < ActionDispatch::TestResponse
|
class TestResponse < ActionDispatch::TestResponse
|
||||||
def recycle!
|
def recycle!
|
||||||
body_parts.clear
|
@status = 200
|
||||||
headers.delete('ETag')
|
@header = Rack::Utils::HeaderHash.new(DEFAULT_HEADERS)
|
||||||
headers.delete('Last-Modified')
|
@writer = lambda { |x| @body << x }
|
||||||
|
@block = nil
|
||||||
|
@length = 0
|
||||||
|
@body = []
|
||||||
|
|
||||||
|
@request = @template = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -132,7 +132,19 @@ module ActionController #:nodoc:
|
||||||
build_request_uri(action, parameters)
|
build_request_uri(action, parameters)
|
||||||
|
|
||||||
Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
|
Base.class_eval { include ProcessWithTest } unless Base < ProcessWithTest
|
||||||
@controller.process(@request, @response)
|
|
||||||
|
env = @request.env
|
||||||
|
app = @controller
|
||||||
|
|
||||||
|
# TODO: Enable Lint
|
||||||
|
# app = Rack::Lint.new(app)
|
||||||
|
|
||||||
|
status, headers, body = app.call(env)
|
||||||
|
response = Rack::MockResponse.new(status, headers, body)
|
||||||
|
|
||||||
|
@response.request, @response.template = @request, @controller.template
|
||||||
|
@response.status, @response.headers, @response.body = response.status, response.headers, response.body
|
||||||
|
@response
|
||||||
end
|
end
|
||||||
|
|
||||||
def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
|
def xml_http_request(request_method, action, parameters = nil, session = nil, flash = nil)
|
||||||
|
|
|
@ -47,7 +47,8 @@ module ActionDispatch
|
||||||
|
|
||||||
autoload :Failsafe, 'action_dispatch/middleware/failsafe'
|
autoload :Failsafe, 'action_dispatch/middleware/failsafe'
|
||||||
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
|
autoload :ParamsParser, 'action_dispatch/middleware/params_parser'
|
||||||
autoload :Reloader, 'action_dispatch/middleware/reloader'
|
autoload :Rescue, 'action_dispatch/middleware/rescue'
|
||||||
|
autoload :ShowExceptions, 'action_dispatch/middleware/show_exceptions'
|
||||||
autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
|
autoload :MiddlewareStack, 'action_dispatch/middleware/stack'
|
||||||
|
|
||||||
autoload :Assertions, 'action_dispatch/testing/assertions'
|
autoload :Assertions, 'action_dispatch/testing/assertions'
|
||||||
|
|
|
@ -34,8 +34,6 @@ module ActionDispatch # :nodoc:
|
||||||
DEFAULT_HEADERS = { "Cache-Control" => "no-cache" }
|
DEFAULT_HEADERS = { "Cache-Control" => "no-cache" }
|
||||||
attr_accessor :request
|
attr_accessor :request
|
||||||
|
|
||||||
attr_accessor :redirected_to, :redirected_to_method_params
|
|
||||||
|
|
||||||
attr_writer :header
|
attr_writer :header
|
||||||
alias_method :headers=, :header=
|
alias_method :headers=, :header=
|
||||||
|
|
||||||
|
@ -187,7 +185,7 @@ module ActionDispatch # :nodoc:
|
||||||
@writer = lambda { |x| callback.call(x) }
|
@writer = lambda { |x| callback.call(x) }
|
||||||
@body.call(self, self)
|
@body.call(self, self)
|
||||||
else
|
else
|
||||||
@body.each(&callback)
|
@body.each { |part| callback.call(part.to_s) }
|
||||||
end
|
end
|
||||||
|
|
||||||
@writer = callback
|
@writer = callback
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
module ActionDispatch
|
|
||||||
class Reloader
|
|
||||||
def initialize(app)
|
|
||||||
@app = app
|
|
||||||
end
|
|
||||||
|
|
||||||
def call(env)
|
|
||||||
ActionController::Dispatcher.reload_application
|
|
||||||
@app.call(env)
|
|
||||||
ensure
|
|
||||||
ActionController::Dispatcher.cleanup_application
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
14
actionpack/lib/action_dispatch/middleware/rescue.rb
Normal file
14
actionpack/lib/action_dispatch/middleware/rescue.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
module ActionDispatch
|
||||||
|
class Rescue
|
||||||
|
def initialize(app, rescuer)
|
||||||
|
@app, @rescuer = app, rescuer
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
@app.call(env)
|
||||||
|
rescue Exception => exception
|
||||||
|
env['action_dispatch.rescue.exception'] = exception
|
||||||
|
@rescuer.call(env)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
142
actionpack/lib/action_dispatch/middleware/show_exceptions.rb
Normal file
142
actionpack/lib/action_dispatch/middleware/show_exceptions.rb
Normal file
|
@ -0,0 +1,142 @@
|
||||||
|
module ActionDispatch
|
||||||
|
class ShowExceptions
|
||||||
|
include StatusCodes
|
||||||
|
|
||||||
|
LOCALHOST = '127.0.0.1'.freeze
|
||||||
|
|
||||||
|
DEFAULT_RESCUE_RESPONSE = :internal_server_error
|
||||||
|
DEFAULT_RESCUE_RESPONSES = {
|
||||||
|
'ActionController::RoutingError' => :not_found,
|
||||||
|
'ActionController::UnknownAction' => :not_found,
|
||||||
|
'ActiveRecord::RecordNotFound' => :not_found,
|
||||||
|
'ActiveRecord::StaleObjectError' => :conflict,
|
||||||
|
'ActiveRecord::RecordInvalid' => :unprocessable_entity,
|
||||||
|
'ActiveRecord::RecordNotSaved' => :unprocessable_entity,
|
||||||
|
'ActionController::MethodNotAllowed' => :method_not_allowed,
|
||||||
|
'ActionController::NotImplemented' => :not_implemented,
|
||||||
|
'ActionController::InvalidAuthenticityToken' => :unprocessable_entity
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_RESCUE_TEMPLATE = 'diagnostics'
|
||||||
|
DEFAULT_RESCUE_TEMPLATES = {
|
||||||
|
'ActionView::MissingTemplate' => 'missing_template',
|
||||||
|
'ActionController::RoutingError' => 'routing_error',
|
||||||
|
'ActionController::UnknownAction' => 'unknown_action',
|
||||||
|
'ActionView::TemplateError' => 'template_error'
|
||||||
|
}
|
||||||
|
|
||||||
|
RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
|
||||||
|
|
||||||
|
cattr_accessor :rescue_responses
|
||||||
|
@@rescue_responses = Hash.new(DEFAULT_RESCUE_RESPONSE)
|
||||||
|
@@rescue_responses.update DEFAULT_RESCUE_RESPONSES
|
||||||
|
|
||||||
|
cattr_accessor :rescue_templates
|
||||||
|
@@rescue_templates = Hash.new(DEFAULT_RESCUE_TEMPLATE)
|
||||||
|
@@rescue_templates.update DEFAULT_RESCUE_TEMPLATES
|
||||||
|
|
||||||
|
def initialize(app, consider_all_requests_local = false)
|
||||||
|
@app = app
|
||||||
|
@consider_all_requests_local = consider_all_requests_local
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(env)
|
||||||
|
@app.call(env)
|
||||||
|
rescue Exception => exception
|
||||||
|
log_error(exception) if logger
|
||||||
|
|
||||||
|
request = Request.new(env)
|
||||||
|
if @consider_all_requests_local || local_request?(request)
|
||||||
|
rescue_action_locally(request, exception)
|
||||||
|
else
|
||||||
|
rescue_action_in_public(exception)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
# Render detailed diagnostics for unhandled exceptions rescued from
|
||||||
|
# a controller action.
|
||||||
|
def rescue_action_locally(request, exception)
|
||||||
|
template = ActionView::Base.new([RESCUES_TEMPLATE_PATH],
|
||||||
|
:template => template,
|
||||||
|
:request => request,
|
||||||
|
:exception => exception
|
||||||
|
)
|
||||||
|
file = "rescues/#{@@rescue_templates[exception.class.name]}.erb"
|
||||||
|
body = template.render(:file => file, :layout => 'rescues/layout.erb')
|
||||||
|
|
||||||
|
headers = {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}
|
||||||
|
status = status_code(exception)
|
||||||
|
|
||||||
|
[status, headers, body]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Attempts to render a static error page based on the
|
||||||
|
# <tt>status_code</tt> thrown, or just return headers if no such file
|
||||||
|
# exists. At first, it will try to render a localized static page.
|
||||||
|
# For example, if a 500 error is being handled Rails and locale is :da,
|
||||||
|
# it will first attempt to render the file at <tt>public/500.da.html</tt>
|
||||||
|
# then attempt to render <tt>public/500.html</tt>. If none of them exist,
|
||||||
|
# the body of the response will be left empty.
|
||||||
|
def rescue_action_in_public(exception)
|
||||||
|
status = status_code(exception)
|
||||||
|
locale_path = "#{public_path}/#{status}.#{I18n.locale}.html" if I18n.locale
|
||||||
|
path = "#{public_path}/#{status}.html"
|
||||||
|
|
||||||
|
if locale_path && File.exist?(locale_path)
|
||||||
|
render_public_file(status, locale_path)
|
||||||
|
elsif File.exist?(path)
|
||||||
|
render_public_file(status, path)
|
||||||
|
else
|
||||||
|
[status, {'Content-Type' => 'text/html', 'Content-Length' => '0'}, []]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# True if the request came from localhost, 127.0.0.1.
|
||||||
|
def local_request?(request)
|
||||||
|
request.remote_addr == LOCALHOST && request.remote_ip == LOCALHOST
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_public_file(status, path)
|
||||||
|
body = File.read(path)
|
||||||
|
[status, {'Content-Type' => 'text/html', 'Content-Length' => body.length.to_s}, body]
|
||||||
|
end
|
||||||
|
|
||||||
|
def status_code(exception)
|
||||||
|
interpret_status(@@rescue_responses[exception.class.name]).to_i
|
||||||
|
end
|
||||||
|
|
||||||
|
def public_path
|
||||||
|
if defined?(Rails)
|
||||||
|
Rails.public_path
|
||||||
|
else
|
||||||
|
"public"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def log_error(exception) #:doc:
|
||||||
|
ActiveSupport::Deprecation.silence do
|
||||||
|
if ActionView::TemplateError === exception
|
||||||
|
logger.fatal(exception.to_s)
|
||||||
|
else
|
||||||
|
logger.fatal(
|
||||||
|
"\n#{exception.class} (#{exception.message}):\n " +
|
||||||
|
clean_backtrace(exception).join("\n ") + "\n\n"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def clean_backtrace(exception)
|
||||||
|
defined?(Rails) && Rails.respond_to?(:backtrace_cleaner) ?
|
||||||
|
Rails.backtrace_cleaner.clean(exception.backtrace) :
|
||||||
|
exception.backtrace
|
||||||
|
end
|
||||||
|
|
||||||
|
def logger
|
||||||
|
if defined?(Rails.logger)
|
||||||
|
Rails.logger
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -61,7 +61,7 @@ module ActionDispatch
|
||||||
|
|
||||||
def inspect
|
def inspect
|
||||||
str = klass.to_s
|
str = klass.to_s
|
||||||
args.each { |arg| str += ", #{arg.inspect}" }
|
args.each { |arg| str += ", #{build_args.inspect}" }
|
||||||
str
|
str
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,7 +74,6 @@ module ActionDispatch
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def build_args
|
def build_args
|
||||||
Array(args).map { |arg| arg.respond_to?(:call) ? arg.call : arg }
|
Array(args).map { |arg| arg.respond_to?(:call) ? arg.call : arg }
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%
|
<%
|
||||||
clean_params = request.parameters.clone
|
clean_params = @request.parameters.clone
|
||||||
clean_params.delete("action")
|
clean_params.delete("action")
|
||||||
clean_params.delete("controller")
|
clean_params.delete("controller")
|
||||||
|
|
||||||
|
@ -17,8 +17,8 @@
|
||||||
<p><b>Parameters</b>: <pre><%=h request_dump %></pre></p>
|
<p><b>Parameters</b>: <pre><%=h request_dump %></pre></p>
|
||||||
|
|
||||||
<p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p>
|
<p><a href="#" onclick="document.getElementById('session_dump').style.display='block'; return false;">Show session dump</a></p>
|
||||||
<div id="session_dump" style="display:none"><%= debug(request.session.instance_variable_get("@data")) %></div>
|
<div id="session_dump" style="display:none"><%= debug(@request.session.instance_variable_get("@data")) %></div>
|
||||||
|
|
||||||
|
|
||||||
<h2 style="margin-top: 30px">Response</h2>
|
<h2 style="margin-top: 30px">Response</h2>
|
||||||
<p><b>Headers</b>: <pre><%=h response ? response.headers.inspect.gsub(',', ",\n") : 'None' %></pre></p>
|
<p><b>Headers</b>: <pre><%=h @response ? @response.headers.inspect.gsub(',', ",\n") : 'None' %></pre></p>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<h1>
|
||||||
|
<%=h @exception.class.to_s %>
|
||||||
|
<% if @request.parameters['controller'] %>
|
||||||
|
in <%=h @request.parameters['controller'].humanize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %>
|
||||||
|
<% end %>
|
||||||
|
</h1>
|
||||||
|
<pre><%=h @exception.clean_message %></pre>
|
||||||
|
|
||||||
|
<%= render :file => "rescues/_trace.erb" %>
|
||||||
|
<%= render :file => "rescues/_request_and_response.erb" %>
|
|
@ -23,7 +23,7 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<%= @contents %>
|
<%= yield %>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
|
@ -1,6 +1,6 @@
|
||||||
<h1>
|
<h1>
|
||||||
<%=h @exception.original_exception.class.to_s %> in
|
<%=h @exception.original_exception.class.to_s %> in
|
||||||
<%=h request.parameters["controller"].capitalize if request.parameters["controller"]%>#<%=h request.parameters["action"] %>
|
<%=h @request.parameters["controller"].capitalize if @request.parameters["controller"]%>#<%=h @request.parameters["action"] %>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
<% @real_exception = @exception
|
<% @real_exception = @exception
|
||||||
@exception = @exception.original_exception || @exception %>
|
@exception = @exception.original_exception || @exception %>
|
||||||
<%= render :file => @rescues_path["rescues/_trace.erb"] %>
|
<%= render :file => "rescues/_trace.erb" %>
|
||||||
<% @exception = @real_exception %>
|
<% @exception = @real_exception %>
|
||||||
|
|
||||||
<%= render :file => @rescues_path["rescues/_request_and_response.erb"] %>
|
<%= render :file => "rescues/_request_and_response.erb" %>
|
|
@ -31,13 +31,7 @@ module ActionDispatch
|
||||||
elsif type.is_a?(Symbol) && @response.response_code == ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[type]
|
elsif type.is_a?(Symbol) && @response.response_code == ActionDispatch::StatusCodes::SYMBOL_TO_STATUS_CODE[type]
|
||||||
assert_block("") { true } # to count the assertion
|
assert_block("") { true } # to count the assertion
|
||||||
else
|
else
|
||||||
if @controller && @response.error?
|
assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false }
|
||||||
exception = @controller.template.instance_variable_get(:@exception)
|
|
||||||
exception_message = exception && exception.message
|
|
||||||
assert_block(build_message(message, "Expected response to be a <?>, but was <?>\n<?>", type, @response.response_code, exception_message.to_s)) { false }
|
|
||||||
else
|
|
||||||
assert_block(build_message(message, "Expected response to be a <?>, but was <?>", type, @response.response_code)) { false }
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -60,14 +54,9 @@ module ActionDispatch
|
||||||
validate_request!
|
validate_request!
|
||||||
|
|
||||||
assert_response(:redirect, message)
|
assert_response(:redirect, message)
|
||||||
return true if options == @response.redirected_to
|
return true if options == @response.location
|
||||||
|
|
||||||
# Support partial arguments for hash redirections
|
redirected_to_after_normalisation = normalize_argument_to_redirection(@response.location)
|
||||||
if options.is_a?(Hash) && @response.redirected_to.is_a?(Hash)
|
|
||||||
return true if options.all? {|(key, value)| @response.redirected_to[key] == value}
|
|
||||||
end
|
|
||||||
|
|
||||||
redirected_to_after_normalisation = normalize_argument_to_redirection(@response.redirected_to)
|
|
||||||
options_after_normalisation = normalize_argument_to_redirection(options)
|
options_after_normalisation = normalize_argument_to_redirection(options)
|
||||||
|
|
||||||
if redirected_to_after_normalisation != options_after_normalisation
|
if redirected_to_after_normalisation != options_after_normalisation
|
||||||
|
|
|
@ -16,6 +16,7 @@ module ActionDispatch
|
||||||
|
|
||||||
def env
|
def env
|
||||||
write_cookies!
|
write_cookies!
|
||||||
|
delete_nil_values!
|
||||||
super
|
super
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -74,5 +75,9 @@ module ActionDispatch
|
||||||
@env['HTTP_COOKIE'] = @cookies.map { |name, value| "#{name}=#{value};" }.join(' ')
|
@env['HTTP_COOKIE'] = @cookies.map { |name, value| "#{name}=#{value};" }.join(' ')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete_nil_values!
|
||||||
|
@env.delete_if { |k, v| v.nil? }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
module ActionDispatch
|
module ActionDispatch
|
||||||
|
# Integration test methods such as ActionController::Integration::Session#get
|
||||||
|
# and ActionController::Integration::Session#post return objects of class
|
||||||
|
# TestResponse, which represent the HTTP response results of the requested
|
||||||
|
# controller actions.
|
||||||
|
#
|
||||||
|
# See Response for more information on controller response objects.
|
||||||
class TestResponse < Response
|
class TestResponse < Response
|
||||||
def self.from_response(response)
|
def self.from_response(response)
|
||||||
new.tap do |resp|
|
new.tap do |resp|
|
||||||
|
@ -87,6 +93,12 @@ module ActionDispatch
|
||||||
ActiveSupport::Deprecation.warn("response.has_template_object? has been deprecated. Use tempate.assigns[name].nil? instead", caller)
|
ActiveSupport::Deprecation.warn("response.has_template_object? has been deprecated. Use tempate.assigns[name].nil? instead", caller)
|
||||||
!template_objects[name].nil?
|
!template_objects[name].nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns binary content (downloadable file), converted to a String
|
||||||
|
def binary_content
|
||||||
|
ActiveSupport::Deprecation.warn("response.binary_content has been deprecated. Use response.body instead", caller)
|
||||||
|
body
|
||||||
|
end
|
||||||
end
|
end
|
||||||
include DeprecatedHelpers
|
include DeprecatedHelpers
|
||||||
|
|
||||||
|
@ -115,17 +127,5 @@ module ActionDispatch
|
||||||
def client_error?
|
def client_error?
|
||||||
(400..499).include?(response_code)
|
(400..499).include?(response_code)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns binary content (downloadable file), converted to a String
|
|
||||||
def binary_content
|
|
||||||
raise "Response body is not a Proc: #{body_parts.inspect}" unless body_parts.kind_of?(Proc)
|
|
||||||
require 'stringio'
|
|
||||||
|
|
||||||
sio = StringIO.new
|
|
||||||
body_parts.call(self, sio)
|
|
||||||
|
|
||||||
sio.rewind
|
|
||||||
sio.read
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -489,7 +489,7 @@ class ActionPackAssertionsControllerTest < ActionController::TestCase
|
||||||
get :index
|
get :index
|
||||||
assert_response :success
|
assert_response :success
|
||||||
flunk 'Expected non-success response'
|
flunk 'Expected non-success response'
|
||||||
rescue ActiveSupport::TestCase::Assertion => e
|
rescue RuntimeError => e
|
||||||
assert e.message.include?('FAIL')
|
assert e.message.include?('FAIL')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -514,9 +514,11 @@ class ActionPackHeaderTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_rendering_xml_respects_content_type
|
def test_rendering_xml_respects_content_type
|
||||||
@response.headers['type'] = 'application/pdf'
|
pending do
|
||||||
process :hello_xml_world
|
@response.headers['type'] = 'application/pdf'
|
||||||
assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
|
process :hello_xml_world
|
||||||
|
assert_equal('application/pdf; charset=utf-8', @response.headers['Content-Type'])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_text_with_custom_content_type
|
def test_render_text_with_custom_content_type
|
||||||
|
|
|
@ -27,6 +27,7 @@ class EmptyController < ActionController::Base
|
||||||
end
|
end
|
||||||
class NonEmptyController < ActionController::Base
|
class NonEmptyController < ActionController::Base
|
||||||
def public_action
|
def public_action
|
||||||
|
render :nothing => true
|
||||||
end
|
end
|
||||||
|
|
||||||
hide_action :hidden_action
|
hide_action :hidden_action
|
||||||
|
@ -51,6 +52,7 @@ end
|
||||||
|
|
||||||
class DefaultUrlOptionsController < ActionController::Base
|
class DefaultUrlOptionsController < ActionController::Base
|
||||||
def default_url_options_action
|
def default_url_options_action
|
||||||
|
render :nothing => true
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_url_options(options = nil)
|
def default_url_options(options = nil)
|
||||||
|
@ -151,11 +153,8 @@ class PerformActionTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_get_on_hidden_should_fail
|
def test_get_on_hidden_should_fail
|
||||||
use_controller NonEmptyController
|
use_controller NonEmptyController
|
||||||
get :hidden_action
|
assert_raise(ActionController::UnknownAction) { get :hidden_action }
|
||||||
assert_response 404
|
assert_raise(ActionController::UnknownAction) { get :another_hidden_action }
|
||||||
|
|
||||||
get :another_hidden_action
|
|
||||||
assert_response 404
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_namespaced_action_should_log_module_name
|
def test_namespaced_action_should_log_module_name
|
||||||
|
|
|
@ -111,7 +111,7 @@ class PageCachingTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_should_cache_ok_at_custom_path
|
def test_should_cache_ok_at_custom_path
|
||||||
@request.stubs(:path).returns("/index.html")
|
@request.request_uri = "/index.html"
|
||||||
get :ok
|
get :ok
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
assert File.exist?("#{FILE_STORE_PATH}/index.html")
|
assert File.exist?("#{FILE_STORE_PATH}/index.html")
|
||||||
|
@ -149,6 +149,9 @@ class PageCachingTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
class ActionCachingTestController < ActionController::Base
|
class ActionCachingTestController < ActionController::Base
|
||||||
|
rescue_from(Exception) { head 500 }
|
||||||
|
rescue_from(ActiveRecord::RecordNotFound) { head :not_found }
|
||||||
|
|
||||||
caches_action :index, :redirected, :forbidden, :if => Proc.new { |c| !c.request.format.json? }, :expires_in => 1.hour
|
caches_action :index, :redirected, :forbidden, :if => Proc.new { |c| !c.request.format.json? }, :expires_in => 1.hour
|
||||||
caches_action :show, :cache_path => 'http://test.host/custom/show'
|
caches_action :show, :cache_path => 'http://test.host/custom/show'
|
||||||
caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
|
caches_action :edit, :cache_path => Proc.new { |c| c.params[:id] ? "http://test.host/#{c.params[:id]};edit" : "http://test.host/edit" }
|
||||||
|
|
|
@ -54,39 +54,38 @@ class CookieTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_setting_cookie
|
def test_setting_cookie
|
||||||
get :authenticate
|
get :authenticate
|
||||||
assert_equal ["user_name=david; path=/"], @response.headers["Set-Cookie"]
|
assert_equal "user_name=david; path=/", @response.headers["Set-Cookie"]
|
||||||
assert_equal({"user_name" => "david"}, @response.cookies)
|
assert_equal({"user_name" => "david"}, @response.cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_setting_with_escapable_characters
|
def test_setting_with_escapable_characters
|
||||||
get :set_with_with_escapable_characters
|
get :set_with_with_escapable_characters
|
||||||
assert_equal ["that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/"], @response.headers["Set-Cookie"]
|
assert_equal "that+%26+guy=foo+%26+bar+%3D%3E+baz; path=/", @response.headers["Set-Cookie"]
|
||||||
assert_equal({"that & guy" => "foo & bar => baz"}, @response.cookies)
|
assert_equal({"that & guy" => "foo & bar => baz"}, @response.cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_setting_cookie_for_fourteen_days
|
def test_setting_cookie_for_fourteen_days
|
||||||
get :authenticate_for_fourteen_days
|
get :authenticate_for_fourteen_days
|
||||||
assert_equal ["user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"], @response.headers["Set-Cookie"]
|
assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT", @response.headers["Set-Cookie"]
|
||||||
assert_equal({"user_name" => "david"}, @response.cookies)
|
assert_equal({"user_name" => "david"}, @response.cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_setting_cookie_for_fourteen_days_with_symbols
|
def test_setting_cookie_for_fourteen_days_with_symbols
|
||||||
get :authenticate_for_fourteen_days_with_symbols
|
get :authenticate_for_fourteen_days_with_symbols
|
||||||
assert_equal ["user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT"], @response.headers["Set-Cookie"]
|
assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT", @response.headers["Set-Cookie"]
|
||||||
assert_equal({"user_name" => "david"}, @response.cookies)
|
assert_equal({"user_name" => "david"}, @response.cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_setting_cookie_with_http_only
|
def test_setting_cookie_with_http_only
|
||||||
get :authenticate_with_http_only
|
get :authenticate_with_http_only
|
||||||
assert_equal ["user_name=david; path=/; HttpOnly"], @response.headers["Set-Cookie"]
|
assert_equal "user_name=david; path=/; HttpOnly", @response.headers["Set-Cookie"]
|
||||||
assert_equal({"user_name" => "david"}, @response.cookies)
|
assert_equal({"user_name" => "david"}, @response.cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_multiple_cookies
|
def test_multiple_cookies
|
||||||
get :set_multiple_cookies
|
get :set_multiple_cookies
|
||||||
assert_equal 2, @response.cookies.size
|
assert_equal 2, @response.cookies.size
|
||||||
assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT", @response.headers["Set-Cookie"][0]
|
assert_equal "user_name=david; path=/; expires=Mon, 10-Oct-2005 05:00:00 GMT\nlogin=XJ-122; path=/", @response.headers["Set-Cookie"]
|
||||||
assert_equal "login=XJ-122; path=/", @response.headers["Set-Cookie"][1]
|
|
||||||
assert_equal({"login" => "XJ-122", "user_name" => "david"}, @response.cookies)
|
assert_equal({"login" => "XJ-122", "user_name" => "david"}, @response.cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -96,7 +95,7 @@ class CookieTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_expiring_cookie
|
def test_expiring_cookie
|
||||||
get :logout
|
get :logout
|
||||||
assert_equal ["user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT"], @response.headers["Set-Cookie"]
|
assert_equal "user_name=; path=/; expires=Thu, 01-Jan-1970 00:00:00 GMT", @response.headers["Set-Cookie"]
|
||||||
assert_equal({"user_name" => nil}, @response.cookies)
|
assert_equal({"user_name" => nil}, @response.cookies)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -117,6 +116,6 @@ class CookieTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_delete_cookie_with_path
|
def test_delete_cookie_with_path
|
||||||
get :delete_cookie_with_path
|
get :delete_cookie_with_path
|
||||||
assert_equal ["user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT"], @response.headers["Set-Cookie"]
|
assert_equal "user_name=; path=/beaten; expires=Thu, 01-Jan-1970 00:00:00 GMT", @response.headers["Set-Cookie"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,12 +15,6 @@ class DeprecatedBaseMethodsTest < ActionController::TestCase
|
||||||
|
|
||||||
tests Target
|
tests Target
|
||||||
|
|
||||||
def test_log_error_silences_deprecation_warnings
|
|
||||||
get :raises_name_error
|
|
||||||
rescue => e
|
|
||||||
assert_not_deprecated { @controller.send :log_error, e }
|
|
||||||
end
|
|
||||||
|
|
||||||
if defined? Test::Unit::Error
|
if defined? Test::Unit::Error
|
||||||
def test_assertion_failed_error_silences_deprecation_warnings
|
def test_assertion_failed_error_silences_deprecation_warnings
|
||||||
get :raises_name_error
|
get :raises_name_error
|
||||||
|
|
|
@ -45,19 +45,6 @@ class DispatcherTest < Test::Unit::TestCase
|
||||||
def log_failsafe_exception(status, exception); end
|
def log_failsafe_exception(status, exception); end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_failsafe_response
|
|
||||||
Dispatcher.any_instance.expects(:_call).raises('b00m')
|
|
||||||
ActionDispatch::Failsafe.any_instance.expects(:log_failsafe_exception)
|
|
||||||
|
|
||||||
assert_nothing_raised do
|
|
||||||
assert_equal [
|
|
||||||
500,
|
|
||||||
{"Content-Type" => "text/html"},
|
|
||||||
["<html><body><h1>500 Internal Server Error</h1></body></html>"]
|
|
||||||
], dispatch
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_prepare_callbacks
|
def test_prepare_callbacks
|
||||||
a = b = c = nil
|
a = b = c = nil
|
||||||
Dispatcher.to_prepare { |*args| a = b = c = 1 }
|
Dispatcher.to_prepare { |*args| a = b = c = 1 }
|
||||||
|
|
|
@ -169,6 +169,7 @@ class FilterTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def public
|
def public
|
||||||
|
render :text => 'ok'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -177,6 +178,10 @@ class FilterTest < Test::Unit::TestCase
|
||||||
before_filter :find_record
|
before_filter :find_record
|
||||||
before_filter :ensure_login
|
before_filter :ensure_login
|
||||||
|
|
||||||
|
def index
|
||||||
|
render :text => 'ok'
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
def find_record
|
def find_record
|
||||||
@ran_filter ||= []
|
@ran_filter ||= []
|
||||||
|
@ -603,7 +608,7 @@ class FilterTest < Test::Unit::TestCase
|
||||||
%w(foo bar baz).each do |action|
|
%w(foo bar baz).each do |action|
|
||||||
request = ActionController::TestRequest.new
|
request = ActionController::TestRequest.new
|
||||||
request.query_parameters[:choose] = action
|
request.query_parameters[:choose] = action
|
||||||
response = DynamicDispatchController.process(request, ActionController::TestResponse.new)
|
response = Rack::MockResponse.new(*DynamicDispatchController.call(request.env))
|
||||||
assert_equal action, response.body
|
assert_equal action, response.body
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -102,19 +102,19 @@ class HelperTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_helper_for_nested_controller
|
def test_helper_for_nested_controller
|
||||||
request = ActionController::TestRequest.new
|
request = ActionController::TestRequest.new
|
||||||
response = ActionController::TestResponse.new
|
|
||||||
request.action = 'render_hello_world'
|
request.action = 'render_hello_world'
|
||||||
|
|
||||||
assert_equal 'hello: Iz guuut!', Fun::GamesController.process(request, response).body
|
response = Rack::MockResponse.new(*Fun::GamesController.call(request.env))
|
||||||
|
assert_equal 'hello: Iz guuut!', response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_helper_for_acronym_controller
|
def test_helper_for_acronym_controller
|
||||||
request = ActionController::TestRequest.new
|
request = ActionController::TestRequest.new
|
||||||
response = ActionController::TestResponse.new
|
|
||||||
request.action = 'test'
|
request.action = 'test'
|
||||||
|
|
||||||
assert_equal 'test: baz', Fun::PdfController.process(request, response).body
|
response = Rack::MockResponse.new(*Fun::PdfController.call(request.env))
|
||||||
|
assert_equal 'test: baz', response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_all_helpers
|
def test_all_helpers
|
||||||
|
@ -211,14 +211,16 @@ class IsolatedHelpersTest < Test::Unit::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_helper_in_a
|
def test_helper_in_a
|
||||||
assert_raise(ActionView::TemplateError) { A.process(@request, @response) }
|
assert_raise(ActionView::TemplateError) { A.call(@request.env) }
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_helper_in_b
|
def test_helper_in_b
|
||||||
assert_equal 'B', B.process(@request, @response).body
|
response = Rack::MockResponse.new(*B.call(@request.env))
|
||||||
|
assert_equal 'B', response.body
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_helper_in_c
|
def test_helper_in_c
|
||||||
assert_equal 'C', C.process(@request, @response).body
|
response = Rack::MockResponse.new(*C.call(@request.env))
|
||||||
|
assert_equal 'C', response.body
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -205,8 +205,7 @@ end
|
||||||
class LayoutExceptionRaised < ActionController::TestCase
|
class LayoutExceptionRaised < ActionController::TestCase
|
||||||
def test_exception_raised_when_layout_file_not_found
|
def test_exception_raised_when_layout_file_not_found
|
||||||
@controller = SetsNonExistentLayoutFile.new
|
@controller = SetsNonExistentLayoutFile.new
|
||||||
get :hello
|
assert_raise(ActionView::MissingTemplate) { get :hello }
|
||||||
assert_kind_of ActionView::MissingTemplate, @controller.template.instance_eval { @exception }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -234,8 +234,10 @@ class RedirectTest < ActionController::TestCase
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_redirect_with_partial_params
|
def test_redirect_with_partial_params
|
||||||
get :module_redirect
|
pending do
|
||||||
assert_redirected_to :action => 'hello_world'
|
get :module_redirect
|
||||||
|
assert_redirected_to :action => 'hello_world'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_redirect_to_nil
|
def test_redirect_to_nil
|
||||||
|
|
|
@ -1293,15 +1293,15 @@ class RenderTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_head_with_symbolic_status
|
def test_head_with_symbolic_status
|
||||||
get :head_with_symbolic_status, :status => "ok"
|
get :head_with_symbolic_status, :status => "ok"
|
||||||
assert_equal "200 OK", @response.status
|
assert_equal 200, @response.status
|
||||||
assert_response :ok
|
assert_response :ok
|
||||||
|
|
||||||
get :head_with_symbolic_status, :status => "not_found"
|
get :head_with_symbolic_status, :status => "not_found"
|
||||||
assert_equal "404 Not Found", @response.status
|
assert_equal 404, @response.status
|
||||||
assert_response :not_found
|
assert_response :not_found
|
||||||
|
|
||||||
get :head_with_symbolic_status, :status => "no_content"
|
get :head_with_symbolic_status, :status => "no_content"
|
||||||
assert_equal "204 No Content", @response.status
|
assert_equal 204, @response.status
|
||||||
assert !@response.headers.include?('Content-Length')
|
assert !@response.headers.include?('Content-Length')
|
||||||
assert_response :no_content
|
assert_response :no_content
|
||||||
|
|
||||||
|
@ -1322,7 +1322,7 @@ class RenderTest < ActionController::TestCase
|
||||||
def test_head_with_string_status
|
def test_head_with_string_status
|
||||||
get :head_with_string_status, :status => "404 Eat Dirt"
|
get :head_with_string_status, :status => "404 Eat Dirt"
|
||||||
assert_equal 404, @response.response_code
|
assert_equal 404, @response.response_code
|
||||||
assert_equal "Eat Dirt", @response.message
|
assert_equal "Not Found", @response.message
|
||||||
assert_response :not_found
|
assert_response :not_found
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1590,7 +1590,7 @@ class EtagRenderTest < ActionController::TestCase
|
||||||
def test_render_against_etag_request_should_304_when_match
|
def test_render_against_etag_request_should_304_when_match
|
||||||
@request.if_none_match = etag_for("hello david")
|
@request.if_none_match = etag_for("hello david")
|
||||||
get :render_hello_world_from_variable
|
get :render_hello_world_from_variable
|
||||||
assert_equal "304 Not Modified", @response.status
|
assert_equal 304, @response.status
|
||||||
assert @response.body.empty?
|
assert @response.body.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1603,13 +1603,13 @@ class EtagRenderTest < ActionController::TestCase
|
||||||
def test_render_against_etag_request_should_200_when_no_match
|
def test_render_against_etag_request_should_200_when_no_match
|
||||||
@request.if_none_match = etag_for("hello somewhere else")
|
@request.if_none_match = etag_for("hello somewhere else")
|
||||||
get :render_hello_world_from_variable
|
get :render_hello_world_from_variable
|
||||||
assert_equal "200 OK", @response.status
|
assert_equal 200, @response.status
|
||||||
assert !@response.body.empty?
|
assert !@response.body.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_render_should_not_set_etag_when_last_modified_has_been_specified
|
def test_render_should_not_set_etag_when_last_modified_has_been_specified
|
||||||
get :render_hello_world_with_last_modified_set
|
get :render_hello_world_with_last_modified_set
|
||||||
assert_equal "200 OK", @response.status
|
assert_equal 200, @response.status
|
||||||
assert_not_nil @response.last_modified
|
assert_not_nil @response.last_modified
|
||||||
assert_nil @response.etag
|
assert_nil @response.etag
|
||||||
assert @response.body.present?
|
assert @response.body.present?
|
||||||
|
@ -1623,11 +1623,11 @@ class EtagRenderTest < ActionController::TestCase
|
||||||
|
|
||||||
@request.if_none_match = expected_etag
|
@request.if_none_match = expected_etag
|
||||||
get :render_hello_world_from_variable
|
get :render_hello_world_from_variable
|
||||||
assert_equal "304 Not Modified", @response.status
|
assert_equal 304, @response.status
|
||||||
|
|
||||||
@request.if_none_match = "\"diftag\""
|
@request.if_none_match = "\"diftag\""
|
||||||
get :render_hello_world_from_variable
|
get :render_hello_world_from_variable
|
||||||
assert_equal "200 OK", @response.status
|
assert_equal 200, @response.status
|
||||||
end
|
end
|
||||||
|
|
||||||
def render_with_404_shouldnt_have_etag
|
def render_with_404_shouldnt_have_etag
|
||||||
|
@ -1695,7 +1695,7 @@ class LastModifiedRenderTest < ActionController::TestCase
|
||||||
def test_request_not_modified
|
def test_request_not_modified
|
||||||
@request.if_modified_since = @last_modified
|
@request.if_modified_since = @last_modified
|
||||||
get :conditional_hello
|
get :conditional_hello
|
||||||
assert_equal "304 Not Modified", @response.status
|
assert_equal 304, @response.status
|
||||||
assert @response.body.blank?, @response.body
|
assert @response.body.blank?, @response.body
|
||||||
assert_equal @last_modified, @response.headers['Last-Modified']
|
assert_equal @last_modified, @response.headers['Last-Modified']
|
||||||
end
|
end
|
||||||
|
@ -1710,7 +1710,7 @@ class LastModifiedRenderTest < ActionController::TestCase
|
||||||
def test_request_modified
|
def test_request_modified
|
||||||
@request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
|
@request.if_modified_since = 'Thu, 16 Jul 2008 00:00:00 GMT'
|
||||||
get :conditional_hello
|
get :conditional_hello
|
||||||
assert_equal "200 OK", @response.status
|
assert_equal 200, @response.status
|
||||||
assert !@response.body.blank?
|
assert !@response.body.blank?
|
||||||
assert_equal @last_modified, @response.headers['Last-Modified']
|
assert_equal @last_modified, @response.headers['Last-Modified']
|
||||||
end
|
end
|
||||||
|
|
|
@ -138,315 +138,6 @@ class RescueController < ActionController::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class RescueControllerTest < ActionController::TestCase
|
|
||||||
FIXTURE_PUBLIC = "#{File.dirname(__FILE__)}/../fixtures".freeze
|
|
||||||
|
|
||||||
def setup
|
|
||||||
super
|
|
||||||
set_all_requests_local
|
|
||||||
populate_exception_object
|
|
||||||
end
|
|
||||||
|
|
||||||
def set_all_requests_local
|
|
||||||
RescueController.consider_all_requests_local = true
|
|
||||||
@request.remote_addr = '1.2.3.4'
|
|
||||||
@request.host = 'example.com'
|
|
||||||
end
|
|
||||||
|
|
||||||
def populate_exception_object
|
|
||||||
begin
|
|
||||||
raise 'foo'
|
|
||||||
rescue => @exception
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_exceptions_raised_by_filters
|
|
||||||
with_rails_root FIXTURE_PUBLIC do
|
|
||||||
with_all_requests_local false do
|
|
||||||
get :before_filter_raises
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :internal_server_error
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_action_locally_if_all_requests_local
|
|
||||||
@controller.expects(:local_request?).never
|
|
||||||
@controller.expects(:rescue_action_locally).with(@exception)
|
|
||||||
@controller.expects(:rescue_action_in_public).never
|
|
||||||
|
|
||||||
with_all_requests_local do
|
|
||||||
@controller.send :rescue_action, @exception
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_action_locally_if_remote_addr_is_localhost
|
|
||||||
@controller.expects(:local_request?).returns(true)
|
|
||||||
@controller.expects(:rescue_action_locally).with(@exception)
|
|
||||||
@controller.expects(:rescue_action_in_public).never
|
|
||||||
|
|
||||||
with_all_requests_local false do
|
|
||||||
@controller.send :rescue_action, @exception
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_action_in_public_otherwise
|
|
||||||
@controller.expects(:local_request?).returns(false)
|
|
||||||
@controller.expects(:rescue_action_locally).never
|
|
||||||
@controller.expects(:rescue_action_in_public).with(@exception)
|
|
||||||
|
|
||||||
with_all_requests_local false do
|
|
||||||
@controller.send :rescue_action, @exception
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_action_in_public_with_localized_error_file
|
|
||||||
# Change locale
|
|
||||||
old_locale = I18n.locale
|
|
||||||
I18n.locale = :da
|
|
||||||
|
|
||||||
with_rails_root FIXTURE_PUBLIC do
|
|
||||||
with_all_requests_local false do
|
|
||||||
get :raises
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :internal_server_error
|
|
||||||
body = File.read("#{FIXTURE_PUBLIC}/public/500.da.html")
|
|
||||||
assert_equal body, @response.body
|
|
||||||
ensure
|
|
||||||
I18n.locale = old_locale
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_action_in_public_with_error_file
|
|
||||||
with_rails_root FIXTURE_PUBLIC do
|
|
||||||
with_all_requests_local false do
|
|
||||||
get :raises
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :internal_server_error
|
|
||||||
body = File.read("#{FIXTURE_PUBLIC}/public/500.html")
|
|
||||||
assert_equal body, @response.body
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_action_in_public_without_error_file
|
|
||||||
with_rails_root '/tmp' do
|
|
||||||
with_all_requests_local false do
|
|
||||||
get :raises
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :internal_server_error
|
|
||||||
assert_equal ' ', @response.body
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_unknown_action_in_public_with_error_file
|
|
||||||
with_rails_root FIXTURE_PUBLIC do
|
|
||||||
with_all_requests_local false do
|
|
||||||
get :foobar_doesnt_exist
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :not_found
|
|
||||||
body = File.read("#{FIXTURE_PUBLIC}/public/404.html")
|
|
||||||
assert_equal body, @response.body
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_unknown_action_in_public_without_error_file
|
|
||||||
with_rails_root '/tmp' do
|
|
||||||
with_all_requests_local false do
|
|
||||||
get :foobar_doesnt_exist
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :not_found
|
|
||||||
assert_equal ' ', @response.body
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_missing_template_in_public
|
|
||||||
with_rails_root FIXTURE_PUBLIC do
|
|
||||||
with_all_requests_local true do
|
|
||||||
get :missing_template
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
assert_response :internal_server_error
|
|
||||||
assert @response.body.include?('missing_template'), "Response should include the template name."
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_action_locally
|
|
||||||
get :raises
|
|
||||||
assert_response :internal_server_error
|
|
||||||
assert_template 'diagnostics.erb'
|
|
||||||
assert @response.body.include?('RescueController#raises'), "Response should include controller and action."
|
|
||||||
assert @response.body.include?("don't panic"), "Response should include exception message."
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_local_request_when_remote_addr_is_localhost
|
|
||||||
@controller.expects(:request).returns(@request).at_least_once
|
|
||||||
with_remote_addr '127.0.0.1' do
|
|
||||||
assert @controller.send(:local_request?)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_local_request_when_remote_addr_isnt_locahost
|
|
||||||
@controller.expects(:request).returns(@request)
|
|
||||||
with_remote_addr '1.2.3.4' do
|
|
||||||
assert !@controller.send(:local_request?)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_responses
|
|
||||||
responses = ActionController::Base.rescue_responses
|
|
||||||
|
|
||||||
assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses.default
|
|
||||||
assert_equal ActionController::Rescue::DEFAULT_RESCUE_RESPONSE, responses[Exception.new]
|
|
||||||
|
|
||||||
assert_equal :not_found, responses[ActionController::RoutingError.name]
|
|
||||||
assert_equal :not_found, responses[ActionController::UnknownAction.name]
|
|
||||||
assert_equal :not_found, responses['ActiveRecord::RecordNotFound']
|
|
||||||
assert_equal :conflict, responses['ActiveRecord::StaleObjectError']
|
|
||||||
assert_equal :unprocessable_entity, responses['ActiveRecord::RecordInvalid']
|
|
||||||
assert_equal :unprocessable_entity, responses['ActiveRecord::RecordNotSaved']
|
|
||||||
assert_equal :method_not_allowed, responses['ActionController::MethodNotAllowed']
|
|
||||||
assert_equal :not_implemented, responses['ActionController::NotImplemented']
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_templates
|
|
||||||
templates = ActionController::Base.rescue_templates
|
|
||||||
|
|
||||||
assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates.default
|
|
||||||
assert_equal ActionController::Rescue::DEFAULT_RESCUE_TEMPLATE, templates[Exception.new]
|
|
||||||
|
|
||||||
assert_equal 'missing_template', templates[ActionView::MissingTemplate.name]
|
|
||||||
assert_equal 'routing_error', templates[ActionController::RoutingError.name]
|
|
||||||
assert_equal 'unknown_action', templates[ActionController::UnknownAction.name]
|
|
||||||
assert_equal 'template_error', templates[ActionView::TemplateError.name]
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_not_implemented
|
|
||||||
with_all_requests_local false do
|
|
||||||
with_rails_public_path(".") do
|
|
||||||
head :not_implemented
|
|
||||||
end
|
|
||||||
end
|
|
||||||
assert_response :not_implemented
|
|
||||||
assert_equal "GET, PUT", @response.headers['Allow']
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_method_not_allowed
|
|
||||||
with_all_requests_local false do
|
|
||||||
with_rails_public_path(".") do
|
|
||||||
get :method_not_allowed
|
|
||||||
end
|
|
||||||
end
|
|
||||||
assert_response :method_not_allowed
|
|
||||||
assert_equal "GET, HEAD, PUT", @response.headers['Allow']
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_handler
|
|
||||||
get :not_authorized
|
|
||||||
assert_response :forbidden
|
|
||||||
end
|
|
||||||
def test_rescue_handler_string
|
|
||||||
get :not_authorized_raise_as_string
|
|
||||||
assert_response :forbidden
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_rescue_handler_with_argument
|
|
||||||
@controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
|
|
||||||
get :record_invalid
|
|
||||||
end
|
|
||||||
def test_rescue_handler_with_argument_as_string
|
|
||||||
@controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
|
|
||||||
get :record_invalid_raise_as_string
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_proc_rescue_handler
|
|
||||||
get :not_allowed
|
|
||||||
assert_response :forbidden
|
|
||||||
end
|
|
||||||
def test_proc_rescue_handler_as_string
|
|
||||||
get :not_allowed_raise_as_string
|
|
||||||
assert_response :forbidden
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_proc_rescue_handle_with_argument
|
|
||||||
get :invalid_request
|
|
||||||
assert_equal "RescueController::InvalidRequest", @response.body
|
|
||||||
end
|
|
||||||
def test_proc_rescue_handle_with_argument_as_string
|
|
||||||
get :invalid_request_raise_as_string
|
|
||||||
assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_block_rescue_handler
|
|
||||||
get :bad_gateway
|
|
||||||
assert_response 502
|
|
||||||
end
|
|
||||||
def test_block_rescue_handler_as_string
|
|
||||||
get :bad_gateway_raise_as_string
|
|
||||||
assert_response 502
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_block_rescue_handler_with_argument
|
|
||||||
get :resource_unavailable
|
|
||||||
assert_equal "RescueController::ResourceUnavailable", @response.body
|
|
||||||
end
|
|
||||||
|
|
||||||
def test_block_rescue_handler_with_argument_as_string
|
|
||||||
get :resource_unavailable_raise_as_string
|
|
||||||
assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
|
|
||||||
end
|
|
||||||
|
|
||||||
protected
|
|
||||||
def with_all_requests_local(local = true)
|
|
||||||
old_local, ActionController::Base.consider_all_requests_local =
|
|
||||||
ActionController::Base.consider_all_requests_local, local
|
|
||||||
yield
|
|
||||||
ensure
|
|
||||||
ActionController::Base.consider_all_requests_local = old_local
|
|
||||||
end
|
|
||||||
|
|
||||||
def with_remote_addr(addr)
|
|
||||||
old_remote_addr, @request.remote_addr = @request.remote_addr, addr
|
|
||||||
yield
|
|
||||||
ensure
|
|
||||||
@request.remote_addr = old_remote_addr
|
|
||||||
end
|
|
||||||
|
|
||||||
def with_rails_public_path(rails_root)
|
|
||||||
old_rails = Object.const_get(:Rails) rescue nil
|
|
||||||
mod = Object.const_set(:Rails, Module.new)
|
|
||||||
(class << mod; self; end).instance_eval do
|
|
||||||
define_method(:public_path) { "#{rails_root}/public" }
|
|
||||||
end
|
|
||||||
yield
|
|
||||||
ensure
|
|
||||||
Object.module_eval { remove_const(:Rails) } if defined?(Rails)
|
|
||||||
Object.const_set(:Rails, old_rails) if old_rails
|
|
||||||
end
|
|
||||||
|
|
||||||
def with_rails_root(path = nil,&block)
|
|
||||||
old_rails_root = RAILS_ROOT if defined?(RAILS_ROOT)
|
|
||||||
if path
|
|
||||||
silence_warnings { Object.const_set(:RAILS_ROOT, path) }
|
|
||||||
else
|
|
||||||
Object.remove_const(:RAILS_ROOT) rescue nil
|
|
||||||
end
|
|
||||||
|
|
||||||
with_rails_public_path(path, &block)
|
|
||||||
|
|
||||||
ensure
|
|
||||||
if old_rails_root
|
|
||||||
silence_warnings { Object.const_set(:RAILS_ROOT, old_rails_root) }
|
|
||||||
else
|
|
||||||
Object.remove_const(:RAILS_ROOT) rescue nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class ExceptionInheritanceRescueController < ActionController::Base
|
class ExceptionInheritanceRescueController < ActionController::Base
|
||||||
|
|
||||||
class ParentException < StandardError
|
class ParentException < StandardError
|
||||||
|
@ -528,6 +219,63 @@ class ApplicationController < ActionController::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class RescueControllerTest < ActionController::TestCase
|
||||||
|
def test_rescue_handler
|
||||||
|
get :not_authorized
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
def test_rescue_handler_string
|
||||||
|
get :not_authorized_raise_as_string
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_rescue_handler_with_argument
|
||||||
|
@controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
|
||||||
|
get :record_invalid
|
||||||
|
end
|
||||||
|
def test_rescue_handler_with_argument_as_string
|
||||||
|
@controller.expects(:show_errors).once.with { |e| e.is_a?(Exception) }
|
||||||
|
get :record_invalid_raise_as_string
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_proc_rescue_handler
|
||||||
|
get :not_allowed
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
def test_proc_rescue_handler_as_string
|
||||||
|
get :not_allowed_raise_as_string
|
||||||
|
assert_response :forbidden
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_proc_rescue_handle_with_argument
|
||||||
|
get :invalid_request
|
||||||
|
assert_equal "RescueController::InvalidRequest", @response.body
|
||||||
|
end
|
||||||
|
def test_proc_rescue_handle_with_argument_as_string
|
||||||
|
get :invalid_request_raise_as_string
|
||||||
|
assert_equal "RescueController::InvalidRequestToRescueAsString", @response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_block_rescue_handler
|
||||||
|
get :bad_gateway
|
||||||
|
assert_response 502
|
||||||
|
end
|
||||||
|
def test_block_rescue_handler_as_string
|
||||||
|
get :bad_gateway_raise_as_string
|
||||||
|
assert_response 502
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_block_rescue_handler_with_argument
|
||||||
|
get :resource_unavailable
|
||||||
|
assert_equal "RescueController::ResourceUnavailable", @response.body
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_block_rescue_handler_with_argument_as_string
|
||||||
|
get :resource_unavailable_raise_as_string
|
||||||
|
assert_equal "RescueController::ResourceUnavailableToRescueAsString", @response.body
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class RescueTest < ActionController::IntegrationTest
|
class RescueTest < ActionController::IntegrationTest
|
||||||
class TestController < ActionController::Base
|
class TestController < ActionController::Base
|
||||||
class RecordInvalid < StandardError
|
class RecordInvalid < StandardError
|
||||||
|
|
|
@ -44,12 +44,12 @@ class SendFileTest < ActionController::TestCase
|
||||||
response = nil
|
response = nil
|
||||||
assert_nothing_raised { response = process('file') }
|
assert_nothing_raised { response = process('file') }
|
||||||
assert_not_nil response
|
assert_not_nil response
|
||||||
assert_kind_of Proc, response.body_parts
|
assert_kind_of Array, response.body_parts
|
||||||
|
|
||||||
require 'stringio'
|
require 'stringio'
|
||||||
output = StringIO.new
|
output = StringIO.new
|
||||||
output.binmode
|
output.binmode
|
||||||
assert_nothing_raised { response.body_parts.call(response, output) }
|
assert_nothing_raised { response.body_parts.each { |part| output << part.to_s } }
|
||||||
assert_equal file_data, output.string
|
assert_equal file_data, output.string
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -149,13 +149,13 @@ class SendFileTest < ActionController::TestCase
|
||||||
define_method "test_send_#{method}_status" do
|
define_method "test_send_#{method}_status" do
|
||||||
@controller.options = { :stream => false, :status => 500 }
|
@controller.options = { :stream => false, :status => 500 }
|
||||||
assert_nothing_raised { assert_not_nil process(method) }
|
assert_nothing_raised { assert_not_nil process(method) }
|
||||||
assert_equal '500 Internal Server Error', @response.status
|
assert_equal 500, @response.status
|
||||||
end
|
end
|
||||||
|
|
||||||
define_method "test_default_send_#{method}_status" do
|
define_method "test_default_send_#{method}_status" do
|
||||||
@controller.options = { :stream => false }
|
@controller.options = { :stream => false }
|
||||||
assert_nothing_raised { assert_not_nil process(method) }
|
assert_nothing_raised { assert_not_nil process(method) }
|
||||||
assert_equal ActionController::DEFAULT_RENDER_STATUS_CODE, @response.status
|
assert_equal 200, @response.status
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -614,7 +614,9 @@ XML
|
||||||
|
|
||||||
def test_binary_content_works_with_send_file
|
def test_binary_content_works_with_send_file
|
||||||
get :test_send_file
|
get :test_send_file
|
||||||
assert_nothing_raised(NoMethodError) { @response.binary_content }
|
assert_deprecated do
|
||||||
|
assert_nothing_raised(NoMethodError) { @response.binary_content }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
103
actionpack/test/dispatch/show_exceptions_test.rb
Normal file
103
actionpack/test/dispatch/show_exceptions_test.rb
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
require 'abstract_unit'
|
||||||
|
|
||||||
|
module ActionDispatch
|
||||||
|
class ShowExceptions
|
||||||
|
private
|
||||||
|
def public_path
|
||||||
|
"#{FIXTURE_LOAD_PATH}/public"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class ShowExceptionsTest < ActionController::IntegrationTest
|
||||||
|
Boomer = lambda do |env|
|
||||||
|
req = ActionDispatch::Request.new(env)
|
||||||
|
case req.path
|
||||||
|
when "/not_found"
|
||||||
|
raise ActionController::UnknownAction
|
||||||
|
when "/method_not_allowed"
|
||||||
|
raise ActionController::MethodNotAllowed
|
||||||
|
when "/not_implemented"
|
||||||
|
raise ActionController::NotImplemented
|
||||||
|
when "/unprocessable_entity"
|
||||||
|
raise ActionController::InvalidAuthenticityToken
|
||||||
|
else
|
||||||
|
raise "puke!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
ProductionApp = ActionDispatch::ShowExceptions.new(Boomer, false)
|
||||||
|
DevelopmentApp = ActionDispatch::ShowExceptions.new(Boomer, true)
|
||||||
|
|
||||||
|
test "rescue in public from a remote ip" do
|
||||||
|
@integration_session = open_session(ProductionApp)
|
||||||
|
self.remote_addr = '208.77.188.166'
|
||||||
|
|
||||||
|
get "/"
|
||||||
|
assert_response 500
|
||||||
|
assert_equal "500 error fixture\n", body
|
||||||
|
|
||||||
|
get "/not_found"
|
||||||
|
assert_response 404
|
||||||
|
assert_equal "404 error fixture\n", body
|
||||||
|
|
||||||
|
get "/method_not_allowed"
|
||||||
|
assert_response 405
|
||||||
|
assert_equal "", body
|
||||||
|
end
|
||||||
|
|
||||||
|
test "rescue locally from a local request" do
|
||||||
|
@integration_session = open_session(ProductionApp)
|
||||||
|
self.remote_addr = '127.0.0.1'
|
||||||
|
|
||||||
|
get "/"
|
||||||
|
assert_response 500
|
||||||
|
assert_match /puke/, body
|
||||||
|
|
||||||
|
get "/not_found"
|
||||||
|
assert_response 404
|
||||||
|
assert_match /ActionController::UnknownAction/, body
|
||||||
|
|
||||||
|
get "/method_not_allowed"
|
||||||
|
assert_response 405
|
||||||
|
assert_match /ActionController::MethodNotAllowed/, body
|
||||||
|
end
|
||||||
|
|
||||||
|
test "localize public rescue message" do
|
||||||
|
# Change locale
|
||||||
|
old_locale = I18n.locale
|
||||||
|
I18n.locale = :da
|
||||||
|
|
||||||
|
begin
|
||||||
|
@integration_session = open_session(ProductionApp)
|
||||||
|
self.remote_addr = '208.77.188.166'
|
||||||
|
|
||||||
|
get "/"
|
||||||
|
assert_response 500
|
||||||
|
assert_equal "500 localized error fixture\n", body
|
||||||
|
|
||||||
|
get "/not_found"
|
||||||
|
assert_response 404
|
||||||
|
assert_equal "404 error fixture\n", body
|
||||||
|
ensure
|
||||||
|
I18n.locale = old_locale
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
test "always rescue locally in development mode" do
|
||||||
|
@integration_session = open_session(DevelopmentApp)
|
||||||
|
self.remote_addr = '208.77.188.166'
|
||||||
|
|
||||||
|
get "/"
|
||||||
|
assert_response 500
|
||||||
|
assert_match /puke/, body
|
||||||
|
|
||||||
|
get "/not_found"
|
||||||
|
assert_response 404
|
||||||
|
assert_match /ActionController::UnknownAction/, body
|
||||||
|
|
||||||
|
get "/method_not_allowed"
|
||||||
|
assert_response 405
|
||||||
|
assert_match /ActionController::MethodNotAllowed/, body
|
||||||
|
end
|
||||||
|
end
|
|
@ -40,6 +40,6 @@ class TestRequestTest < ActiveSupport::TestCase
|
||||||
|
|
||||||
req.cookies["login"] = "XJ-122"
|
req.cookies["login"] = "XJ-122"
|
||||||
assert_equal({"user_name" => "david", "login" => "XJ-122"}, req.cookies)
|
assert_equal({"user_name" => "david", "login" => "XJ-122"}, req.cookies)
|
||||||
assert_equal "login=XJ-122; user_name=david;", req.env["HTTP_COOKIE"]
|
assert_equal %w(login=XJ-122 user_name=david), req.env["HTTP_COOKIE"].split(/; ?/).sort
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,11 @@ class BodyPartsTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_body_parts
|
def test_body_parts
|
||||||
get :index
|
get :index
|
||||||
assert_equal RENDERINGS, @response.body_parts
|
pending do
|
||||||
|
# TestProcess buffers body_parts into body
|
||||||
|
# TODO: Rewrite test w/o going through process
|
||||||
|
assert_equal RENDERINGS, @response.body_parts
|
||||||
|
end
|
||||||
assert_equal RENDERINGS.join, @response.body
|
assert_equal RENDERINGS.join, @response.body
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,26 +10,32 @@ class OutputBufferTest < ActionController::TestCase
|
||||||
tests TestController
|
tests TestController
|
||||||
|
|
||||||
def test_flush_output_buffer
|
def test_flush_output_buffer
|
||||||
# Start with the default body parts
|
pending do
|
||||||
get :index
|
# TODO: This tests needs to be rewritten due
|
||||||
assert_equal ['foo'], @response.body_parts
|
# The @response is not the same response object assigned
|
||||||
assert_nil @controller.template.output_buffer
|
# to the @controller.template
|
||||||
|
|
||||||
# Nil output buffer is skipped
|
# Start with the default body parts
|
||||||
@controller.template.flush_output_buffer
|
get :index
|
||||||
assert_nil @controller.template.output_buffer
|
assert_equal ['foo'], @response.body_parts
|
||||||
assert_equal ['foo'], @response.body_parts
|
assert_nil @controller.template.output_buffer
|
||||||
|
|
||||||
# Empty output buffer is skipped
|
# Nil output buffer is skipped
|
||||||
@controller.template.output_buffer = ''
|
@controller.template.flush_output_buffer
|
||||||
@controller.template.flush_output_buffer
|
assert_nil @controller.template.output_buffer
|
||||||
assert_equal '', @controller.template.output_buffer
|
assert_equal ['foo'], @response.body_parts
|
||||||
assert_equal ['foo'], @response.body_parts
|
|
||||||
|
|
||||||
# Flushing appends the output buffer to the body parts
|
# Empty output buffer is skipped
|
||||||
@controller.template.output_buffer = 'bar'
|
@controller.template.output_buffer = ''
|
||||||
@controller.template.flush_output_buffer
|
@controller.template.flush_output_buffer
|
||||||
assert_equal '', @controller.template.output_buffer
|
assert_equal '', @controller.template.output_buffer
|
||||||
assert_equal ['foo', 'bar'], @response.body_parts
|
assert_equal ['foo'], @response.body_parts
|
||||||
|
|
||||||
|
# Flushing appends the output buffer to the body parts
|
||||||
|
@controller.template.output_buffer = 'bar'
|
||||||
|
@controller.template.flush_output_buffer
|
||||||
|
assert_equal '', @controller.template.output_buffer
|
||||||
|
assert_equal ['foo', 'bar'], @response.body_parts
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -21,15 +21,9 @@
|
||||||
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
#++
|
#++
|
||||||
|
|
||||||
begin
|
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
||||||
require 'active_support'
|
$:.unshift(activesupport_path) if File.directory?(activesupport_path)
|
||||||
rescue LoadError
|
require 'active_support'
|
||||||
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
|
||||||
if File.directory?(activesupport_path)
|
|
||||||
$:.unshift activesupport_path
|
|
||||||
require 'active_support'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
require 'active_support/core/all'
|
require 'active_support/core/all'
|
||||||
|
|
||||||
$:.unshift(File.dirname(__FILE__) + '/../../arel/lib')
|
$:.unshift(File.dirname(__FILE__) + '/../../arel/lib')
|
||||||
|
|
|
@ -217,7 +217,7 @@ class Hash
|
||||||
case params.class.to_s
|
case params.class.to_s
|
||||||
when "Hash"
|
when "Hash"
|
||||||
params.inject({}) do |h,(k,v)|
|
params.inject({}) do |h,(k,v)|
|
||||||
h[k.to_s.underscore.tr("-", "_")] = unrename_keys(v)
|
h[k.to_s.tr("-", "_")] = unrename_keys(v)
|
||||||
h
|
h
|
||||||
end
|
end
|
||||||
when "Array"
|
when "Array"
|
||||||
|
|
|
@ -646,6 +646,22 @@ class HashToXmlTest < Test::Unit::TestCase
|
||||||
assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"]
|
assert_equal expected_topic_hash, Hash.from_xml(topic_xml)["rsp"]["photos"]["photo"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def test_all_caps_key_from_xml
|
||||||
|
test_xml = <<-EOT
|
||||||
|
<ABC3XYZ>
|
||||||
|
<TEST>Lorem Ipsum</TEST>
|
||||||
|
</ABC3XYZ>
|
||||||
|
EOT
|
||||||
|
|
||||||
|
expected_hash = {
|
||||||
|
"ABC3XYZ" => {
|
||||||
|
"TEST" => "Lorem Ipsum"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_equal expected_hash, Hash.from_xml(test_xml)
|
||||||
|
end
|
||||||
|
|
||||||
def test_empty_array_from_xml
|
def test_empty_array_from_xml
|
||||||
blog_xml = <<-XML
|
blog_xml = <<-XML
|
||||||
<blog>
|
<blog>
|
||||||
|
|
Loading…
Reference in a new issue