diff options
Diffstat (limited to 'actionpack')
25 files changed, 291 insertions, 76 deletions
diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index a90a7b37f7..25e2d27a01 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,52 @@ *Rails 3.1.0 (unreleased)* +* Implicit actions named not_implemented can be rendered [Santiago Pastorino] + +* 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] diff --git a/actionpack/README.rdoc b/actionpack/README.rdoc index 3661d27d51..b900962d32 100644 --- a/actionpack/README.rdoc +++ b/actionpack/README.rdoc @@ -19,7 +19,7 @@ It consists of several modules: * Action View, which handles view template lookup and rendering, and provides view helpers that assist when building HTML forms, Atom feeds and more. - Template formats that Action View handles are ERb (embedded Ruby, typically + Template formats that Action View handles are ERB (embedded Ruby, typically used to inline short Ruby snippets inside HTML), XML Builder and RJS (dynamically generated JavaScript from Ruby code). @@ -57,7 +57,7 @@ A short rundown of some of the major features: {Learn more}[link:classes/ActionController/Base.html] -* ERb templates (static content mixed with dynamic output from ruby) +* ERB templates (static content mixed with dynamic output from ruby) <% for post in @posts %> Title: <%= post.title %> diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index f6bc5e0d37..d3c66800d9 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -17,8 +17,6 @@ Gem::Specification.new do |s| s.require_path = 'lib' s.requirements << 'none' - s.has_rdoc = true - s.add_dependency('activesupport', version) s.add_dependency('activemodel', version) s.add_dependency('rack-cache', '~> 1.0.0') @@ -26,7 +24,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') + s.add_dependency('erubis', '~> 2.7.0') end diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index c384fd0978..0951267fea 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -1,3 +1,4 @@ +require 'erubis' require 'active_support/configurable' require 'active_support/descendants_tracker' require 'active_support/core_ext/module/anonymous' @@ -18,6 +19,7 @@ module AbstractController include ActiveSupport::Configurable extend ActiveSupport::DescendantsTracker + undef_method :not_implemented class << self attr_reader :abstract alias_method :abstract?, :abstract @@ -128,20 +130,23 @@ module AbstractController self.class.action_methods end - private + # Returns true if the name can be considered an action. This can + # be overridden in subclasses to modify the semantics of what + # can be considered an action. + # + # For instance, this is overriden by ActionController to add + # the implicit rendering feature. + # + # ==== Parameters + # * <tt>name</tt> - The name of an action to be tested + # + # ==== Returns + # * <tt>TrueClass</tt>, <tt>FalseClass</tt> + def action_method?(name) + self.class.action_methods.include?(name) + end - # Returns true if the name can be considered an action. This can - # be overridden in subclasses to modify the semantics of what - # can be considered an action. - # - # ==== Parameters - # * <tt>name</tt> - The name of an action to be tested - # - # ==== Returns - # * <tt>TrueClass</tt>, <tt>FalseClass</tt> - def action_method?(name) - self.class.action_methods.include?(name) - end + private # Call the action. Override this in a subclass to modify the # behavior around processing an action. This, and not #process, @@ -160,8 +165,8 @@ module AbstractController # If the action name was not found, but a method called "action_missing" # was found, #method_for_action will return "_handle_action_missing". # This method calls #action_missing with the current action name. - def _handle_action_missing - action_missing(@_action_name) + def _handle_action_missing(*args) + action_missing(@_action_name, *args) end # Takes an action name and returns the name of the method that will 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/base.rb b/actionpack/lib/action_controller/base.rb index e6523e56d2..5f9e082cd3 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -105,7 +105,7 @@ module ActionController # == Renders # # Action Controller sends content to the user by using one of five rendering methods. The most versatile and common is the rendering - # of a template. Included in the Action Pack is the Action View, which enables rendering of ERb templates. It's automatically configured. + # of a template. Included in the Action Pack is the Action View, which enables rendering of ERB templates. It's automatically configured. # The controller passes objects to the view by assigning instance variables: # # def show @@ -128,7 +128,7 @@ module ActionController # end # end # - # Read more about writing ERb and Builder templates in ActionView::Base. + # Read more about writing ERB and Builder templates in ActionView::Base. # # == Redirects # diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 39c804d707..1d6df89007 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 # @@ -77,7 +67,7 @@ module ActionController # class PostsController < ApplicationController # REALM = "SuperSecret" # USERS = {"dhh" => "secret", #plain text password - # "dap" => Digest:MD5::hexdigest(["dap",REALM,"secret"].join(":")) #ha1 digest password + # "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":")) #ha1 digest password # # before_filter :authenticate, :except => [:index] # @@ -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..3ec0c4c6a4 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -1,21 +1,21 @@ 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 - render + def default_render(*args) + render(*args) end - def method_for_action(action_name) - super || begin - if template_exists?(action_name.to_s, _prefixes) - "default_render" - end - end + def action_method?(action_name) + super || template_exists?(action_name.to_s, _prefixes) end end end diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index a2e06fe0a6..6469e24d36 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -189,7 +189,7 @@ module ActionController #:nodoc: raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given? if response = retrieve_response_from_mimes(mimes, &block) - response.call + response.call(nil) end end @@ -222,6 +222,9 @@ module ActionController #:nodoc: # is quite simple (it just needs to respond to call), you can even give # a proc to it. # + # In order to use respond_with, first you need to declare the formats your + # controller responds to in the class level with a call to <tt>respond_to</tt>. + # def respond_with(*resources, &block) raise "In order to use respond_with, first you need to declare the formats your " << "controller responds to in the class level" if self.class.mimes_for_respond_to.empty? @@ -259,7 +262,7 @@ module ActionController #:nodoc: # def retrieve_response_from_mimes(mimes=nil, &block) mimes ||= collect_mimes_from_class_level - collector = Collector.new(mimes) { default_render } + collector = Collector.new(mimes) { |options| default_render(options || {}) } block.call(collector) if block_given? if format = request.negotiate_mime(collector.order) diff --git a/actionpack/lib/action_controller/metal/responder.rb b/actionpack/lib/action_controller/metal/responder.rb index 4b45413cf8..59a3621f72 100644 --- a/actionpack/lib/action_controller/metal/responder.rb +++ b/actionpack/lib/action_controller/metal/responder.rb @@ -77,6 +77,37 @@ module ActionController #:nodoc: # # respond_with(@project, :manager, @task) # + # === Custom options + # + # <code>respond_with</code> also allow you to pass options that are forwarded + # to the underlying render call. Those options are only applied success + # scenarios. For instance, you can do the following in the create method above: + # + # def create + # @project = Project.find(params[:project_id]) + # @task = @project.comments.build(params[:task]) + # flash[:notice] = 'Task was successfully created.' if @task.save + # respond_with(@project, @task, :status => 201) + # end + # + # This will return status 201 if the task was saved with success. If not, + # it will simply ignore the given options and return status 422 and the + # resource errors. To customize the failure scenario, you can pass a + # a block to <code>respond_with</code>: + # + # def create + # @project = Project.find(params[:project_id]) + # @task = @project.comments.build(params[:task]) + # respond_with(@project, @task, :status => 201) do |format| + # if @task.save + # flash[:notice] = 'Task was successfully created.' + # else + # format.html { render "some_special_template" } + # end + # end + # end + # + # Using <code>respond_with</code> with a block follows the same syntax as <code>respond_to</code>. class Responder attr_reader :controller, :request, :format, :resource, :resources, :options @@ -131,7 +162,11 @@ module ActionController #:nodoc: # responds to :to_format and display it. # def to_format - default_render + if get? || !has_errors? + default_render + else + display_errors + end rescue ActionView::MissingTemplate => e api_behavior(e) end @@ -155,8 +190,6 @@ module ActionController #:nodoc: if get? display resource - elsif has_errors? - display resource.errors, :status => :unprocessable_entity elsif post? display resource, :status => :created, :location => api_location elsif has_empty_resource_definition? @@ -185,7 +218,7 @@ module ActionController #:nodoc: # controller. # def default_render - @default_response.call + @default_response.call(options) end # Display is just a shortcut to render a resource with the current format. @@ -209,6 +242,10 @@ module ActionController #:nodoc: controller.render given_options.merge!(options).merge!(format => resource) end + def display_errors + controller.render format => resource.errors, :status => :unprocessable_entity + end + # Check whether the resource has errors. # def has_errors? 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_dispatch/testing/assertions/routing.rb b/actionpack/lib/action_dispatch/testing/assertions/routing.rb index 11e8c63fa0..b760db42e2 100644 --- a/actionpack/lib/action_dispatch/testing/assertions/routing.rb +++ b/actionpack/lib/action_dispatch/testing/assertions/routing.rb @@ -46,7 +46,7 @@ module ActionDispatch expected_options.stringify_keys! msg = build_message(message, "The recognized options <?> did not match <?>, difference: <?>", request.path_parameters, expected_options, expected_options.diff(request.path_parameters)) - assert_block(msg) { request.path_parameters == expected_options } + assert_equal(expected_options, request.path_parameters, msg) end # Asserts that the provided options can be used to generate the provided path. This is the inverse of +assert_recognizes+. @@ -84,11 +84,11 @@ module ActionDispatch found_extras = options.reject {|k, v| ! extra_keys.include? k} msg = build_message(message, "found extras <?>, not <?>", found_extras, extras) - assert_block(msg) { found_extras == extras } + assert_equal(extras, found_extras, msg) msg = build_message(message, "The generated path <?> did not match <?>", generated_path, expected_path) - assert_block(msg) { expected_path == generated_path } + assert_equal(expected_path, generated_path, msg) end # Asserts that path and options match both ways; in other words, it verifies that <tt>path</tt> generates diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index ab8c6259c5..5519103627 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -8,13 +8,13 @@ require 'action_view/log_subscriber' module ActionView #:nodoc: # = Action View Base # - # Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb + # Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERB # (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used. # If the template file has a <tt>.rjs</tt> extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator. # - # == ERb + # == ERB # - # You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the + # You trigger ERB by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the # following loop for names: # # <b>Names of all the people</b> @@ -23,7 +23,7 @@ module ActionView #:nodoc: # <% end %> # # The loop is setup in regular embedding tags <% %> and the name is written using the output embedding tag <%= %>. Note that this - # is not just a usage suggestion. Regular output functions like print or puts won't work with ERb templates. So this would be wrong: + # is not just a usage suggestion. Regular output functions like print or puts won't work with ERB templates. So this would be wrong: # # <%# WRONG %> # Hi, Mr. <% puts "Frodo" %> @@ -81,7 +81,7 @@ module ActionView #:nodoc: # # == Builder # - # Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object + # Builder templates are a more programmatic alternative to ERB. They are especially useful for generating XML content. An XmlMarkup object # named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension. # # Here are some basic examples: diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index db9d7a08ff..96e5722252 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -4,7 +4,7 @@ module ActionView # = Action View Atom Feed Helpers module Helpers #:nodoc: module AtomFeedHelper - # Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERb or any other + # Adds easy defaults to writing Atom feeds with the Builder template engine (this does not work on ERB or any other # template languages). # # Full usage example: diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index c88bd1efd5..9ac7dff1ec 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -14,7 +14,7 @@ module ActionView # variable. You can then use this variable anywhere in your templates or layout. # # ==== Examples - # The capture method can be used in ERb templates... + # The capture method can be used in ERB templates... # # <% @greeting = capture do %> # Welcome to my shiny new web page! The date and time is diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 18e303778c..506db24dc2 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -584,7 +584,7 @@ module ActionView # Works like update_page but wraps the generated JavaScript in a # <tt>\<script></tt> tag. Use this to include generated JavaScript in an - # ERb template. See JavaScriptGenerator for more information. + # ERB template. See JavaScriptGenerator for more information. # # +html_options+ may be a hash of <tt>\<script></tt> attributes to be # passed to ActionView::Helpers::JavaScriptHelper#javascript_tag. diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index 6496397c31..de75488e72 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -186,7 +186,7 @@ module ActionView # link_to "Profiles", :controller => "profiles" # # => <a href="/profiles">Profiles</a> # - # You can use a block as well if your link target is hard to fit into the name parameter. ERb example: + # You can use a block as well if your link target is hard to fit into the name parameter. ERB example: # # <%= link_to(@profile) do %> # <strong><%= @profile.name %></strong> -- <span>Check it out!</span> diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index a36837afc8..0443b1b0f5 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -55,7 +55,7 @@ module ActionView class ERB # Specify trim mode for the ERB compiler. Defaults to '-'. - # See ERb documentation for suitable values. + # See ERB documentation for suitable values. class_attribute :erb_trim_mode self.erb_trim_mode = '-' 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/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 5debf96232..41f80d0784 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -558,6 +558,15 @@ class RespondWithController < ActionController::Base respond_with(resource, :location => "http://test.host/", :status => :created) end + def using_invalid_resource_with_template + respond_with(resource) + end + + def using_options_with_template + @customer = resource + respond_with(@customer, :status => 123, :location => "http://test.host/") + end + def using_resource_with_responder responder = proc { |c, r, o| c.render :text => "Resource name is #{r.first.name}" } respond_with(resource, :responder => responder) @@ -953,6 +962,54 @@ class RespondWithControllerTest < ActionController::TestCase assert_equal 201, @response.status end + def test_using_resource_with_status_and_location_with_invalid_resource + errors = { :name => :invalid } + Customer.any_instance.stubs(:errors).returns(errors) + + @request.accept = "text/xml" + + post :using_resource_with_status_and_location + assert_equal errors.to_xml, @response.body + assert_equal 422, @response.status + assert_equal nil, @response.location + + put :using_resource_with_status_and_location + assert_equal errors.to_xml, @response.body + assert_equal 422, @response.status + assert_equal nil, @response.location + end + + def test_using_invalid_resource_with_template + errors = { :name => :invalid } + Customer.any_instance.stubs(:errors).returns(errors) + + @request.accept = "text/xml" + + post :using_invalid_resource_with_template + assert_equal errors.to_xml, @response.body + assert_equal 422, @response.status + assert_equal nil, @response.location + + put :using_invalid_resource_with_template + assert_equal errors.to_xml, @response.body + assert_equal 422, @response.status + assert_equal nil, @response.location + end + + def test_using_options_with_template + @request.accept = "text/xml" + + post :using_options_with_template + assert_equal "<customer-name>david</customer-name>", @response.body + assert_equal 123, @response.status + assert_equal "http://test.host/", @response.location + + put :using_options_with_template + assert_equal "<customer-name>david</customer-name>", @response.body + assert_equal 123, @response.status + assert_equal "http://test.host/", @response.location + end + def test_using_resource_with_responder get :using_resource_with_responder assert_equal "Resource name is david", @response.body diff --git a/actionpack/test/controller/new_base/render_implicit_action_test.rb b/actionpack/test/controller/new_base/render_implicit_action_test.rb index 9f69d20329..3bb3016fdb 100644 --- a/actionpack/test/controller/new_base/render_implicit_action_test.rb +++ b/actionpack/test/controller/new_base/render_implicit_action_test.rb @@ -3,8 +3,9 @@ require 'abstract_unit' module RenderImplicitAction class SimpleController < ::ApplicationController self.view_paths = [ActionView::FixtureResolver.new( - "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", - "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!" + "render_implicit_action/simple/hello_world.html.erb" => "Hello world!", + "render_implicit_action/simple/hyphen-ated.html.erb" => "Hello hyphen-ated!", + "render_implicit_action/simple/not_implemented.html.erb" => "Not Implemented" )] def hello_world() end @@ -24,5 +25,18 @@ module RenderImplicitAction assert_body "Hello hyphen-ated!" assert_status 200 end + + test "render an action called not_implemented" do + get "/render_implicit_action/simple/not_implemented" + + assert_body "Not Implemented" + assert_status 200 + end + + test "action_method? returns true for implicit actions" do + assert SimpleController.new.action_method?(:hello_world) + assert SimpleController.new.action_method?(:"hyphen-ated") + assert SimpleController.new.action_method?(:not_implemented) + end end end 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/fixtures/respond_with/using_invalid_resource_with_template.xml.erb b/actionpack/test/fixtures/respond_with/using_invalid_resource_with_template.xml.erb new file mode 100644 index 0000000000..bf5869ed22 --- /dev/null +++ b/actionpack/test/fixtures/respond_with/using_invalid_resource_with_template.xml.erb @@ -0,0 +1 @@ +<content>I should not be displayed</content>
\ No newline at end of file diff --git a/actionpack/test/fixtures/respond_with/using_options_with_template.xml.erb b/actionpack/test/fixtures/respond_with/using_options_with_template.xml.erb new file mode 100644 index 0000000000..b313017913 --- /dev/null +++ b/actionpack/test/fixtures/respond_with/using_options_with_template.xml.erb @@ -0,0 +1 @@ +<customer-name><%= @customer.name %></customer-name>
\ No newline at end of file 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 |