aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
authorAaron Patterson <aaron.patterson@gmail.com>2011-03-29 17:38:43 -0700
committerAaron Patterson <aaron.patterson@gmail.com>2011-03-29 17:38:43 -0700
commit0471fc9f1cf95865a9810b46f1227783fee40ab5 (patch)
tree50c6a1990e7b97b7960a692c9441e686cbcb4902 /actionpack
parent28c73f012328c8386acfc608f0dfb1a459dbf170 (diff)
parent58becf116580c37c63b89f4a660ebe293f6e7c4e (diff)
downloadrails-0471fc9f1cf95865a9810b46f1227783fee40ab5.tar.gz
rails-0471fc9f1cf95865a9810b46f1227783fee40ab5.tar.bz2
rails-0471fc9f1cf95865a9810b46f1227783fee40ab5.zip
Merge branch 'master' into zomg
* master: (51 commits) order is not guaranteed by this select, so add an order and call first! oracle stores this with microseconds, so convert to seconds before comparing make sure that active connections are not cleared during test when an exception happens clearing active connections in the ConnectionManagement middleware if an exception happens proxy body responses so we close database connections after body is flushed Pass the proper method_name instead of hardcoding to action_name. Quote find_in_batches ORDER BY clause [#6620 state:resolved] Delegate first!, last!, any? and many? to scoped Dont call authenticate_or_request_with_http_basic twice Remove 'warning: ambiguous first argument' when running ActionPack tests Change exists? so that it doesn't instantiate records [#6127 state:resolved] Move mapper_test to the appropriate location Update the wildcard route to be non-greedy by default, therefore be able to match the (.:format) segment [#6605 state:resolved] Fix examples Added Base.http_basic_authenticate_with to do simple http basic authentication with a single class method call [DHH] make sure we have an active database connection before running each connection management test adding active_connections? to the connection pool for finding open connections adding active_connection? to the connection pool testing app delegation from the ConnectionManagement middleware namespacing connection management tests. :heart: ...
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/CHANGELOG53
-rw-r--r--actionpack/actionpack.gemspec2
-rw-r--r--actionpack/lib/abstract_controller/callbacks.rb2
-rw-r--r--actionpack/lib/action_controller.rb1
-rw-r--r--actionpack/lib/action_controller/base.rb1
-rw-r--r--actionpack/lib/action_controller/caching/actions.rb13
-rw-r--r--actionpack/lib/action_controller/metal/force_ssl.rb35
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb28
-rw-r--r--actionpack/lib/action_controller/metal/implicit_render.rb18
-rw-r--r--actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb2
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb8
-rw-r--r--actionpack/lib/action_view/helpers/form_helper.rb15
-rw-r--r--actionpack/lib/action_view/helpers/javascript_helper.rb5
-rw-r--r--actionpack/lib/action_view/template/resolver.rb4
-rw-r--r--actionpack/test/controller/force_ssl_test.rb83
-rw-r--r--actionpack/test/controller/http_basic_authentication_test.rb16
-rw-r--r--actionpack/test/dispatch/mapper_test.rb (renamed from actionpack/test/action_dispatch/routing/mapper_test.rb)32
-rw-r--r--actionpack/test/dispatch/show_exceptions_test.rb16
-rw-r--r--actionpack/test/template/date_helper_test.rb4
-rw-r--r--actionpack/test/template/form_helper_test.rb21
-rw-r--r--actionpack/test/template/javascript_helper_test.rb1
21 files changed, 318 insertions, 42 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG
index 5ab92c8cfc..3eba2281c4 100644
--- a/actionpack/CHANGELOG
+++ b/actionpack/CHANGELOG
@@ -1,5 +1,58 @@
*Rails 3.1.0 (unreleased)*
+* Wildcard route will always matching the optional format segment by default. For example if you have this route:
+
+ map '*pages' => 'pages#show'
+
+ by requesting '/foo/bar.json', your `params[:pages]` will be equals to "foo/bar" with the request format of JSON. If you want the old 3.0.x behavior back, you could supply `:format => false` like this:
+
+ map '*pages' => 'pages#show', :format => false
+
+* Added Base.http_basic_authenticate_with to do simple http basic authentication with a single class method call [DHH]
+
+ class PostsController < ApplicationController
+ USER_NAME, PASSWORD = "dhh", "secret"
+
+ before_filter :authenticate, :except => [ :index ]
+
+ def index
+ render :text => "Everyone can see me!"
+ end
+
+ def edit
+ render :text => "I'm only accessible if you know the password"
+ end
+
+ private
+ def authenticate
+ authenticate_or_request_with_http_basic do |user_name, password|
+ user_name == USER_NAME && password == PASSWORD
+ end
+ end
+ end
+
+ ..can now be written as
+
+ class PostsController < ApplicationController
+ http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index
+
+ def index
+ render :text => "Everyone can see me!"
+ end
+
+ def edit
+ render :text => "I'm only accessible if you know the password"
+ end
+ end
+
+* Allow you to add `force_ssl` into controller to force browser to transfer data via HTTPS protocol on that particular controller. You can also specify `:only` or `:except` to specific it to particular action. [DHH and Prem Sichanugrist]
+
+* Allow FormHelper#form_for to specify the :method as a direct option instead of through the :html hash [DHH]
+
+ form_for(@post, remote: true, method: :delete) instead of form_for(@post, remote: true, html: { method: :delete })
+
+* Make JavaScriptHelper#j() an alias for JavaScriptHelper#escape_javascript() -- note this then supersedes the Object#j() method that the JSON gem adds within templates using the JavaScriptHelper [DHH]
+
* Sensitive query string parameters (specified in config.filter_parameters) will now be filtered out from the request paths in the log file. [Prem Sichanugrist, fxn]
* URL parameters which return false for to_param now appear in the query string (previously they were removed) [Andrew White]
diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec
index f6bc5e0d37..651f3b164a 100644
--- a/actionpack/actionpack.gemspec
+++ b/actionpack/actionpack.gemspec
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
s.add_dependency('i18n', '~> 0.5.0')
s.add_dependency('rack', '~> 1.2.1')
s.add_dependency('rack-test', '~> 0.5.7')
- s.add_dependency('rack-mount', '~> 0.6.13')
+ s.add_dependency('rack-mount', '~> 0.7.1')
s.add_dependency('tzinfo', '~> 0.3.23')
s.add_dependency('erubis', '~> 2.6.6')
end
diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb
index 1943ca4436..95992c2698 100644
--- a/actionpack/lib/abstract_controller/callbacks.rb
+++ b/actionpack/lib/abstract_controller/callbacks.rb
@@ -14,7 +14,7 @@ module AbstractController
# Override AbstractController::Base's process_action to run the
# process_action callbacks around the normal behavior.
def process_action(method_name, *args)
- run_callbacks(:process_action, action_name) do
+ run_callbacks(:process_action, method_name) do
super
end
end
diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb
index 5b81cd39f4..62cc18b253 100644
--- a/actionpack/lib/action_controller.rb
+++ b/actionpack/lib/action_controller.rb
@@ -14,6 +14,7 @@ module ActionController
autoload :ConditionalGet
autoload :Cookies
autoload :Flash
+ autoload :ForceSSL
autoload :Head
autoload :Helpers
autoload :HideActions
diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb
index 81c0698fb8..e6523e56d2 100644
--- a/actionpack/lib/action_controller/base.rb
+++ b/actionpack/lib/action_controller/base.rb
@@ -198,6 +198,7 @@ module ActionController
Cookies,
Flash,
RequestForgeryProtection,
+ ForceSSL,
Streaming,
RecordIdentifier,
HttpAuthentication::Basic::ControllerMethods,
diff --git a/actionpack/lib/action_controller/caching/actions.rb b/actionpack/lib/action_controller/caching/actions.rb
index 2c8a6e4d4d..5fc6956266 100644
--- a/actionpack/lib/action_controller/caching/actions.rb
+++ b/actionpack/lib/action_controller/caching/actions.rb
@@ -56,19 +56,18 @@ module ActionController #:nodoc:
#
# caches_page :public
#
- # caches_action :index, :if => proc do |c|
- # !c.request.format.json? # cache if is not a JSON request
+ # caches_action :index, :if => proc do
+ # !request.format.json? # cache if is not a JSON request
# end
#
# caches_action :show, :cache_path => { :project => 1 },
# :expires_in => 1.hour
#
- # caches_action :feed, :cache_path => proc do |c|
- # if c.params[:user_id]
- # c.send(:user_list_url,
- # c.params[:user_id], c.params[:id])
+ # caches_action :feed, :cache_path => proc do
+ # if params[:user_id]
+ # user_list_url(params[:user_id, params[:id])
# else
- # c.send(:list_url, c.params[:id])
+ # list_url(params[:id])
# end
# end
# end
diff --git a/actionpack/lib/action_controller/metal/force_ssl.rb b/actionpack/lib/action_controller/metal/force_ssl.rb
new file mode 100644
index 0000000000..eb8ed7dfbd
--- /dev/null
+++ b/actionpack/lib/action_controller/metal/force_ssl.rb
@@ -0,0 +1,35 @@
+module ActionController
+ # This module provides a method which will redirects browser to use HTTPS
+ # protocol. This will ensure that user's sensitive information will be
+ # transferred safely over the internet. You _should_ always force browser
+ # to use HTTPS when you're transferring sensitive information such as
+ # user authentication, account information, or credit card information.
+ #
+ # Note that if you really concern about your application safety, you might
+ # consider using +config.force_ssl+ in your configuration config file instead.
+ # That will ensure all the data transferred via HTTPS protocol and prevent
+ # user from getting session hijacked when accessing the site under unsecured
+ # HTTP protocol.
+ module ForceSSL
+ extend ActiveSupport::Concern
+ include AbstractController::Callbacks
+
+ module ClassMethods
+ # Force the request to this particular controller or specified actions to be
+ # under HTTPS protocol.
+ #
+ # Note that this method will not be effective on development environment.
+ #
+ # ==== Options
+ # * <tt>only</tt> - The callback should be run only for this action
+ # * <tt>except<tt> - The callback should be run for all actions except this action
+ def force_ssl(options = {})
+ before_filter(options) do
+ if !request.ssl? && !Rails.env.development?
+ redirect_to :protocol => 'https://', :status => :moved_permanently
+ end
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index 39c804d707..b98429792d 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -8,9 +8,7 @@ module ActionController
# === Simple \Basic example
#
# class PostsController < ApplicationController
- # USER_NAME, PASSWORD = "dhh", "secret"
- #
- # before_filter :authenticate, :except => [ :index ]
+ # http_basic_authenticate_with :name => "dhh", :password => "secret", :except => :index
#
# def index
# render :text => "Everyone can see me!"
@@ -19,15 +17,7 @@ module ActionController
# def edit
# render :text => "I'm only accessible if you know the password"
# end
- #
- # private
- # def authenticate
- # authenticate_or_request_with_http_basic do |user_name, password|
- # user_name == USER_NAME && password == PASSWORD
- # end
- # end
- # end
- #
+ # end
#
# === Advanced \Basic example
#
@@ -115,6 +105,18 @@ module ActionController
extend self
module ControllerMethods
+ extend ActiveSupport::Concern
+
+ module ClassMethods
+ def http_basic_authenticate_with(options = {})
+ before_filter(options.except(:name, :password, :realm)) do
+ authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
+ name == options[:name] && password == options[:password]
+ end
+ end
+ end
+ end
+
def authenticate_or_request_with_http_basic(realm = "Application", &login_procedure)
authenticate_with_http_basic(&login_procedure) || request_http_basic_authentication(realm)
end
@@ -378,7 +380,6 @@ module ActionController
#
# RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
module Token
-
extend self
module ControllerMethods
@@ -458,6 +459,5 @@ module ActionController
controller.__send__ :render, :text => "HTTP Token: Access denied.\n", :status => :unauthorized
end
end
-
end
end
diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb
index cfa7004048..4b301c0d90 100644
--- a/actionpack/lib/action_controller/metal/implicit_render.rb
+++ b/actionpack/lib/action_controller/metal/implicit_render.rb
@@ -1,9 +1,13 @@
module ActionController
module ImplicitRender
- def send_action(*)
- ret = super
- default_render unless response_body
- ret
+ def send_action(method, *args)
+ if respond_to?(method, true)
+ ret = super
+ default_render unless response_body
+ ret
+ else
+ default_render
+ end
end
def default_render
@@ -11,10 +15,8 @@ module ActionController
end
def method_for_action(action_name)
- super || begin
- if template_exists?(action_name.to_s, _prefixes)
- "default_render"
- end
+ super || if template_exists?(action_name.to_s, _prefixes)
+ action_name.to_s
end
end
end
diff --git a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
index 50d8ca9484..2099fd069a 100644
--- a/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
+++ b/actionpack/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb
@@ -1,7 +1,7 @@
<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 %>
+ in <%=h @request.parameters['controller'].classify.pluralize %>Controller<% if @request.parameters['action'] %>#<%=h @request.parameters['action'] %><% end %>
<% end %>
</h1>
<pre><%=h @exception.message %></pre>
diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb
index 14c424f24b..35be0b3a27 100644
--- a/actionpack/lib/action_dispatch/routing/mapper.rb
+++ b/actionpack/lib/action_dispatch/routing/mapper.rb
@@ -104,10 +104,16 @@ module ActionDispatch
@options.reverse_merge!(:controller => /.+?/)
end
+ # Add a constraint for wildcard route to make it non-greedy and match the
+ # optional format part of the route by default
+ if path.match(/\*([^\/]+)$/) && @options[:format] != false
+ @options.reverse_merge!(:"#{$1}" => /.+?/)
+ end
+
if @options[:format] == false
@options.delete(:format)
path
- elsif path.include?(":format") || path.end_with?('/') || path.match(/^\/?\*/)
+ elsif path.include?(":format") || path.end_with?('/')
path
else
"#{path}(.:format)"
diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb
index 48abf119f1..9025d9e24c 100644
--- a/actionpack/lib/action_view/helpers/form_helper.rb
+++ b/actionpack/lib/action_view/helpers/form_helper.rb
@@ -185,7 +185,7 @@ module ActionView
#
# is equivalent to something like:
#
- # <%= form_for @post, :as => :post, :url => post_path(@post), :html => { :method => :put, :class => "edit_post", :id => "edit_post_45" } do |f| %>
+ # <%= form_for @post, :as => :post, :url => post_path(@post), :method => :put, :html => { :class => "edit_post", :id => "edit_post_45" } do |f| %>
# ...
# <% end %>
#
@@ -236,6 +236,16 @@ module ActionView
# Where <tt>@document = Document.find(params[:id])</tt> and
# <tt>@comment = Comment.new</tt>.
#
+ # === Setting the method
+ #
+ # You can force the form to use the full array of HTTP verbs by setting
+ #
+ # :method => (:get|:post|:put|:delete)
+ #
+ # in the options hash. If the verb is not GET or POST, which are natively supported by HTML forms, the
+ # form will be set to POST and a hidden input called _method will carry the intended verb for the server
+ # to interpret.
+ #
# === Unobtrusive JavaScript
#
# Specifying:
@@ -298,7 +308,7 @@ module ActionView
#
# In this case, if you use this:
#
- # <%= render :partial => f %>
+ # <%= render f %>
#
# The rendered template is <tt>people/_labelling_form</tt> and the local
# variable referencing the form builder is called
@@ -350,6 +360,7 @@ module ActionView
end
options[:html][:remote] = options.delete(:remote)
+ options[:html][:method] = options.delete(:method) if options.has_key?(:method)
options[:html][:authenticity_token] = options.delete(:authenticity_token)
builder = options[:parent_builder] = instantiate_builder(object_name, object, options, &proc)
diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb
index cd3a3eac80..a19ba7a968 100644
--- a/actionpack/lib/action_view/helpers/javascript_helper.rb
+++ b/actionpack/lib/action_view/helpers/javascript_helper.rb
@@ -47,6 +47,9 @@ module ActionView
"'" => "\\'" }
# Escape carrier returns and single and double quotes for JavaScript segments.
+ # Also available through the alias j(). This is particularly helpful in JavaScript responses, like:
+ #
+ # $('some_element').replaceWith('<%=j render 'some/element_template' %>');
def escape_javascript(javascript)
if javascript
javascript.gsub(/(\\|<\/|\r\n|[\n\r"'])/) { JS_ESCAPE_MAP[$1] }
@@ -55,6 +58,8 @@ module ActionView
end
end
+ alias_method :j, :escape_javascript
+
# Returns a JavaScript tag with the +content+ inside. Example:
# javascript_tag "alert('All is good')"
#
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 6c1063592f..41c6310ae2 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -157,8 +157,8 @@ module ActionView
query.gsub!(/\:#{ext}/, "{#{variants.compact.uniq.join(',')}}")
}
- query.gsub!(/\.{html,/, ".{html,text.html,")
- query.gsub!(/\.{text,/, ".{text,text.plain,")
+ query.gsub!('.{html,', '.{html,text.html,')
+ query.gsub!('.{text,', '.{text,text.plain,')
File.expand_path(query, @path)
end
diff --git a/actionpack/test/controller/force_ssl_test.rb b/actionpack/test/controller/force_ssl_test.rb
new file mode 100644
index 0000000000..3e723e20d9
--- /dev/null
+++ b/actionpack/test/controller/force_ssl_test.rb
@@ -0,0 +1,83 @@
+require 'abstract_unit'
+
+class ForceSSLController < ActionController::Base
+ def banana
+ render :text => "monkey"
+ end
+
+ def cheeseburger
+ render :text => "sikachu"
+ end
+end
+
+class ForceSSLControllerLevel < ForceSSLController
+ force_ssl
+end
+
+class ForceSSLOnlyAction < ForceSSLController
+ force_ssl :only => :cheeseburger
+end
+
+class ForceSSLExceptAction < ForceSSLController
+ force_ssl :except => :banana
+end
+
+class ForceSSLControllerLevelTest < ActionController::TestCase
+ tests ForceSSLControllerLevel
+
+ def test_banana_redirects_to_https
+ get :banana
+ assert_response 301
+ assert_equal "https://test.host/force_ssl_controller_level/banana", redirect_to_url
+ end
+
+ def test_cheeseburger_redirects_to_https
+ get :cheeseburger
+ assert_response 301
+ assert_equal "https://test.host/force_ssl_controller_level/cheeseburger", redirect_to_url
+ end
+end
+
+class ForceSSLOnlyActionTest < ActionController::TestCase
+ tests ForceSSLOnlyAction
+
+ def test_banana_not_redirects_to_https
+ get :banana
+ assert_response 200
+ end
+
+ def test_cheeseburger_redirects_to_https
+ get :cheeseburger
+ assert_response 301
+ assert_equal "https://test.host/force_ssl_only_action/cheeseburger", redirect_to_url
+ end
+end
+
+class ForceSSLExceptActionTest < ActionController::TestCase
+ tests ForceSSLExceptAction
+
+ def test_banana_not_redirects_to_https
+ get :banana
+ assert_response 200
+ end
+
+ def test_cheeseburger_redirects_to_https
+ get :cheeseburger
+ assert_response 301
+ assert_equal "https://test.host/force_ssl_except_action/cheeseburger", redirect_to_url
+ end
+end
+
+class ForceSSLExcludeDevelopmentTest < ActionController::TestCase
+ tests ForceSSLControllerLevel
+
+ def setup
+ Rails.env.stubs(:development?).returns(false)
+ end
+
+ def test_development_environment_not_redirects_to_https
+ Rails.env.stubs(:development?).returns(true)
+ get :banana
+ assert_response 200
+ end
+end \ No newline at end of file
diff --git a/actionpack/test/controller/http_basic_authentication_test.rb b/actionpack/test/controller/http_basic_authentication_test.rb
index 01c650a494..bd3e13e6fa 100644
--- a/actionpack/test/controller/http_basic_authentication_test.rb
+++ b/actionpack/test/controller/http_basic_authentication_test.rb
@@ -6,6 +6,8 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
before_filter :authenticate_with_request, :only => :display
before_filter :authenticate_long_credentials, :only => :show
+ http_basic_authenticate_with :name => "David", :password => "Goliath", :only => :search
+
def index
render :text => "Hello Secret"
end
@@ -17,6 +19,10 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
def show
render :text => 'Only for loooooong credentials'
end
+
+ def search
+ render :text => 'All inline'
+ end
private
@@ -104,6 +110,16 @@ class HttpBasicAuthenticationTest < ActionController::TestCase
assert assigns(:logged_in)
assert_equal 'Definitely Maybe', @response.body
end
+
+ test "authenticate with class method" do
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'Goliath')
+ get :search
+ assert_response :success
+
+ @request.env['HTTP_AUTHORIZATION'] = encode_credentials('David', 'WRONG!')
+ get :search
+ assert_response :unauthorized
+ end
private
diff --git a/actionpack/test/action_dispatch/routing/mapper_test.rb b/actionpack/test/dispatch/mapper_test.rb
index e21b271907..b6c08ffc33 100644
--- a/actionpack/test/action_dispatch/routing/mapper_test.rb
+++ b/actionpack/test/dispatch/mapper_test.rb
@@ -25,6 +25,10 @@ module ActionDispatch
def conditions
routes.map { |x| x[1] }
end
+
+ def requirements
+ routes.map { |x| x[2] }
+ end
end
def test_initialize
@@ -50,8 +54,34 @@ module ActionDispatch
def test_map_wildcard
fakeset = FakeSet.new
mapper = Mapper.new fakeset
- mapper.match '/*path', :to => 'pages#show', :as => :page
+ mapper.match '/*path', :to => 'pages#show'
+ assert_equal '/*path(.:format)', fakeset.conditions.first[:path_info]
+ assert_equal(/.+?/, fakeset.requirements.first[:path])
+ end
+
+ def test_map_wildcard_with_other_element
+ fakeset = FakeSet.new
+ mapper = Mapper.new fakeset
+ mapper.match '/*path/foo/:bar', :to => 'pages#show'
+ assert_equal '/*path/foo/:bar(.:format)', fakeset.conditions.first[:path_info]
+ assert_nil fakeset.requirements.first[:path]
+ end
+
+ def test_map_wildcard_with_multiple_wildcard
+ fakeset = FakeSet.new
+ mapper = Mapper.new fakeset
+ mapper.match '/*foo/*bar', :to => 'pages#show'
+ assert_equal '/*foo/*bar(.:format)', fakeset.conditions.first[:path_info]
+ assert_nil fakeset.requirements.first[:foo]
+ assert_equal(/.+?/, fakeset.requirements.first[:bar])
+ end
+
+ def test_map_wildcard_with_format_false
+ fakeset = FakeSet.new
+ mapper = Mapper.new fakeset
+ mapper.match '/*path', :to => 'pages#show', :format => false
assert_equal '/*path', fakeset.conditions.first[:path_info]
+ assert_nil fakeset.requirements.first[:path]
end
end
end
diff --git a/actionpack/test/dispatch/show_exceptions_test.rb b/actionpack/test/dispatch/show_exceptions_test.rb
index 2a478c214f..e453dd11ce 100644
--- a/actionpack/test/dispatch/show_exceptions_test.rb
+++ b/actionpack/test/dispatch/show_exceptions_test.rb
@@ -7,6 +7,8 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
case req.path
when "/not_found"
raise ActionController::UnknownAction
+ when "/runtime_error"
+ raise RuntimeError
when "/method_not_allowed"
raise ActionController::MethodNotAllowed
when "/not_implemented"
@@ -121,4 +123,18 @@ class ShowExceptionsTest < ActionDispatch::IntegrationTest
assert_response 404
assert_match(/AbstractController::ActionNotFound/, body)
end
+
+ test "show the controller name in the diagnostics template when controller name is present" do
+ @app = ProductionApp
+ get("/runtime_error", {}, {
+ 'action_dispatch.show_exceptions' => true,
+ 'action_dispatch.request.parameters' => {
+ 'action' => 'show',
+ 'id' => 'unknown',
+ 'controller' => 'featured_tiles'
+ }
+ })
+ assert_response 500
+ assert_match(/RuntimeError\n in FeaturedTilesController/, body)
+ end
end
diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb
index aca2fef170..fd1f824a39 100644
--- a/actionpack/test/template/date_helper_test.rb
+++ b/actionpack/test/template/date_helper_test.rb
@@ -2720,11 +2720,11 @@ class DateHelperTest < ActionView::TestCase
end
def test_time_tag_pubdate_option
- assert_match /<time.*pubdate="pubdate">.*<\/time>/, time_tag(Time.now, :pubdate => true)
+ assert_match(/<time.*pubdate="pubdate">.*<\/time>/, time_tag(Time.now, :pubdate => true))
end
def test_time_tag_with_given_text
- assert_match /<time.*>Right now<\/time>/, time_tag(Time.now, 'Right now')
+ assert_match(/<time.*>Right now<\/time>/, time_tag(Time.now, 'Right now'))
end
def test_time_tag_with_different_format
diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb
index 359b078466..ff183d097d 100644
--- a/actionpack/test/template/form_helper_test.rb
+++ b/actionpack/test/template/form_helper_test.rb
@@ -715,14 +715,31 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_for_with_method_as_part_of_html_options
+ form_for(@post, :url => '/', :html => { :id => 'create-post', :method => :delete }) do |f|
+ concat f.text_field(:title)
+ concat f.text_area(:body)
+ concat f.check_box(:secret)
+ end
+
+ expected = whole_form("/", "create-post", "edit_post", "delete") do
+ "<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
+ "<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
+ "<input name='post[secret]' type='hidden' value='0' />" +
+ "<input name='post[secret]' checked='checked' type='checkbox' id='post_secret' value='1' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_form_for_with_method
- form_for(@post, :url => '/', :html => { :id => 'create-post', :method => :put }) do |f|
+ form_for(@post, :url => '/', :method => :delete, :html => { :id => 'create-post' }) do |f|
concat f.text_field(:title)
concat f.text_area(:body)
concat f.check_box(:secret)
end
- expected = whole_form("/", "create-post", "edit_post", "put") do
+ expected = whole_form("/", "create-post", "edit_post", "delete") do
"<input name='post[title]' size='30' type='text' id='post_title' value='Hello World' />" +
"<textarea name='post[body]' id='post_body' rows='20' cols='40'>Back to the hill and over it again!</textarea>" +
"<input name='post[secret]' type='hidden' value='0' />" +
diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb
index 2e7484afaf..8aa2730da1 100644
--- a/actionpack/test/template/javascript_helper_test.rb
+++ b/actionpack/test/template/javascript_helper_test.rb
@@ -27,6 +27,7 @@ class JavaScriptHelperTest < ActionView::TestCase
assert_equal %(This \\"thing\\" is really\\n netos\\'), escape_javascript(%(This "thing" is really\n netos'))
assert_equal %(backslash\\\\test), escape_javascript( %(backslash\\test) )
assert_equal %(dont <\\/close> tags), escape_javascript(%(dont </close> tags))
+ assert_equal %(dont <\\/close> tags), j(%(dont </close> tags))
end
def test_button_to_function