diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/lib/abstract_controller/base.rb | 7 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/callbacks.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/rendering.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/strong_parameters.rb | 39 | ||||
-rw-r--r-- | actionpack/lib/action_controller/renderer.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 2 | ||||
-rw-r--r-- | actionpack/test/controller/integration_test.rb | 16 | ||||
-rw-r--r-- | actionpack/test/controller/parameters/parameters_permit_test.rb | 6 | ||||
-rw-r--r-- | actionpack/test/controller/render_test.rb | 7 | ||||
-rw-r--r-- | actionpack/test/controller/send_file_test.rb | 15 | ||||
-rw-r--r-- | actionpack/test/dispatch/cookies_test.rb | 4 | ||||
-rw-r--r-- | actionpack/test/dispatch/routing_test.rb | 30 |
12 files changed, 107 insertions, 25 deletions
diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index d4317399ed..aa06f70433 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -150,6 +150,13 @@ module AbstractController _find_action_name(action_name) end + # Tests if a response body is set. Used to determine if the + # +process_action+ callback needs to be terminated in + # +AbstractController::Callbacks+. + def performed? + response_body + end + # Returns true if the given controller is capable of rendering # a path. A subclass of +AbstractController::Base+ # may return false. An Email controller for example does not diff --git a/actionpack/lib/abstract_controller/callbacks.rb b/actionpack/lib/abstract_controller/callbacks.rb index d63ce9c1c3..3ef8da86fa 100644 --- a/actionpack/lib/abstract_controller/callbacks.rb +++ b/actionpack/lib/abstract_controller/callbacks.rb @@ -9,7 +9,7 @@ module AbstractController included do define_callbacks :process_action, - terminator: ->(controller, result_lambda) { result_lambda.call if result_lambda.is_a?(Proc); controller.response_body }, + terminator: ->(controller, result_lambda) { result_lambda.call if result_lambda.is_a?(Proc); controller.performed? }, skip_after_callbacks_if_terminated: true end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index a6fb0dbe1d..4ba2c26949 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -122,7 +122,7 @@ module AbstractController def _normalize_render(*args, &block) options = _normalize_args(*args, &block) #TODO: remove defined? when we restore AP <=> AV dependency - if defined?(request) && request.variant.present? + if defined?(request) && !request.nil? && request.variant.present? options[:variant] = request.variant end _normalize_options(options) diff --git a/actionpack/lib/action_controller/metal/strong_parameters.rb b/actionpack/lib/action_controller/metal/strong_parameters.rb index 46589901fd..b326695ce2 100644 --- a/actionpack/lib/action_controller/metal/strong_parameters.rb +++ b/actionpack/lib/action_controller/metal/strong_parameters.rb @@ -58,8 +58,7 @@ module ActionController # }) # # permitted = params.require(:person).permit(:name, :age) - # permitted # => {"name"=>"Francesco", "age"=>22} - # permitted.class # => ActionController::Parameters + # permitted # => <ActionController::Parameters {"name"=>"Francesco", "age"=>22} permitted: true> # permitted.permitted? # => true # # Person.first.update!(permitted) @@ -87,7 +86,7 @@ module ActionController # # params = ActionController::Parameters.new(a: "123", b: "456") # params.permit(:c) - # # => {} + # # => <ActionController::Parameters {} permitted: true> # # ActionController::Parameters.action_on_unpermitted_parameters = :raise # @@ -107,6 +106,8 @@ module ActionController # params["key"] # => "value" class Parameters cattr_accessor :permit_all_parameters, instance_accessor: false + self.permit_all_parameters = false + cattr_accessor :action_on_unpermitted_parameters, instance_accessor: false delegate :keys, :key?, :has_key?, :values, :has_value?, :value?, :empty?, :include?, @@ -255,7 +256,7 @@ module ActionController # either present or the singleton +false+, returns said value: # # ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person) - # # => {"name"=>"Francesco"} + # # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false> # # Otherwise raises <tt>ActionController::ParameterMissing</tt>: # @@ -276,12 +277,12 @@ module ActionController # returned: # # params = ActionController::Parameters.new(user: { ... }, profile: { ... }) - # user_params, profile_params = params.require(:user, :profile) + # user_params, profile_params = params.require([:user, :profile]) # # Otherwise, the method re-raises the first exception found: # # params = ActionController::Parameters.new(user: {}, profile: {}) - # user_params, profile_params = params.require(:user, :profile) + # user_params, profile_params = params.require([:user, :profile]) # # ActionController::ParameterMissing: param is missing or the value is empty: user # # Technically this method can be used to fetch terminal values: @@ -374,13 +375,13 @@ module ActionController # }) # # params.require(:person).permit(:contact) - # # => {} + # # => <ActionController::Parameters {} permitted: true> # # params.require(:person).permit(contact: :phone) - # # => {"contact"=>{"phone"=>"555-1234"}} + # # => <ActionController::Parameters {"contact"=><ActionController::Parameters {"phone"=>"555-1234"} permitted: true>} permitted: true> # # params.require(:person).permit(contact: [ :email, :phone ]) - # # => {"contact"=>{"email"=>"none@test.com", "phone"=>"555-1234"}} + # # => <ActionController::Parameters {"contact"=><ActionController::Parameters {"email"=>"none@test.com", "phone"=>"555-1234"} permitted: true>} permitted: true> def permit(*filters) params = self.class.new @@ -402,7 +403,7 @@ module ActionController # returns +nil+. # # params = ActionController::Parameters.new(person: { name: 'Francesco' }) - # params[:person] # => {"name"=>"Francesco"} + # params[:person] # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false> # params[:none] # => nil def [](key) convert_hashes_to_parameters(key, @parameters[key]) @@ -421,7 +422,7 @@ module ActionController # is given, then that will be run and its result returned. # # params = ActionController::Parameters.new(person: { name: 'Francesco' }) - # params.fetch(:person) # => {"name"=>"Francesco"} + # params.fetch(:person) # => <ActionController::Parameters {"name"=>"Francesco"} permitted: false> # params.fetch(:none) # => ActionController::ParameterMissing: param is missing or the value is empty: none # params.fetch(:none, 'Francesco') # => "Francesco" # params.fetch(:none) { 'Francesco' } # => "Francesco" @@ -457,8 +458,8 @@ module ActionController # don't exist, returns an empty hash. # # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) - # params.slice(:a, :b) # => {"a"=>1, "b"=>2} - # params.slice(:d) # => {} + # params.slice(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false> + # params.slice(:d) # => <ActionController::Parameters {} permitted: false> def slice(*keys) new_instance_with_inherited_permitted_status(@parameters.slice(*keys)) end @@ -474,8 +475,8 @@ module ActionController # filters out the given +keys+. # # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) - # params.except(:a, :b) # => {"c"=>3} - # params.except(:d) # => {"a"=>1,"b"=>2,"c"=>3} + # params.except(:a, :b) # => <ActionController::Parameters {"c"=>3} permitted: false> + # params.except(:d) # => <ActionController::Parameters {"a"=>1, "b"=>2, "c"=>3} permitted: false> def except(*keys) new_instance_with_inherited_permitted_status(@parameters.except(*keys)) end @@ -483,8 +484,8 @@ module ActionController # Removes and returns the key/value pairs matching the given keys. # # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) - # params.extract!(:a, :b) # => {"a"=>1, "b"=>2} - # params # => {"c"=>3} + # params.extract!(:a, :b) # => <ActionController::Parameters {"a"=>1, "b"=>2} permitted: false> + # params # => <ActionController::Parameters {"c"=>3} permitted: false> def extract!(*keys) new_instance_with_inherited_permitted_status(@parameters.extract!(*keys)) end @@ -494,7 +495,7 @@ module ActionController # # params = ActionController::Parameters.new(a: 1, b: 2, c: 3) # params.transform_values { |x| x * 2 } - # # => {"a"=>2, "b"=>4, "c"=>6} + # # => <ActionController::Parameters {"a"=>2, "b"=>4, "c"=>6} permitted: false> def transform_values(&block) if block new_instance_with_inherited_permitted_status( @@ -577,7 +578,7 @@ module ActionController # params = ActionController::Parameters.new(a: 1) # params.permit! # params.permitted? # => true - # copy_params = params.dup # => {"a"=>1} + # copy_params = params.dup # => <ActionController::Parameters {"a"=>1} permitted: true> # copy_params.permitted? # => true def dup super.tap do |duplicate| diff --git a/actionpack/lib/action_controller/renderer.rb b/actionpack/lib/action_controller/renderer.rb index 5ff4a658ad..a8c8d66682 100644 --- a/actionpack/lib/action_controller/renderer.rb +++ b/actionpack/lib/action_controller/renderer.rb @@ -1,7 +1,7 @@ require 'active_support/core_ext/hash/keys' module ActionController - # ActionController::Renderer allows to render arbitrary templates + # ActionController::Renderer allows you to render arbitrary templates # without requirement of being in controller actions. # # You get a concrete renderer class by invoking ActionController::Base#renderer. diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 8ff3b42a40..40b6500553 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -106,7 +106,7 @@ module ActionDispatch @ast = ast @anchor = anchor @via = via - @internal = options[:internal] + @internal = options.delete(:internal) path_params = ast.find_all(&:symbol?).map(&:to_sym) diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 97571c1308..34fb3b1003 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -1147,6 +1147,22 @@ class IntegrationRequestEncodersTest < ActionDispatch::IntegrationTest end end + def test_standard_json_encoding_works + with_routing do |routes| + routes.draw do + ActiveSupport::Deprecation.silence do + post ':action' => FooController + end + end + + post '/foos_json.json', params: { foo: 'fighters' }.to_json, + headers: { 'Content-Type' => 'application/json' } + + assert_response :success + assert_equal({ 'foo' => 'fighters' }, response.parsed_body) + end + end + def test_encoding_as_json post_to_foos as: :json do assert_response :success diff --git a/actionpack/test/controller/parameters/parameters_permit_test.rb b/actionpack/test/controller/parameters/parameters_permit_test.rb index b75eb0e3bf..2eed2996f6 100644 --- a/actionpack/test/controller/parameters/parameters_permit_test.rb +++ b/actionpack/test/controller/parameters/parameters_permit_test.rb @@ -369,4 +369,10 @@ class ParametersPermitTest < ActiveSupport::TestCase refute params.permit(foo: [:bar]).has_key?(:foo) refute params.permit(foo: :bar).has_key?(:foo) end + + test '#permitted? is false by default' do + params = ActionController::Parameters.new + + assert_equal false, params.permitted? + end end diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index f42efd35af..8d3134630d 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -564,6 +564,13 @@ class MetalRenderTest < ActionController::TestCase end end +class ActionControllerBaseRenderTest < ActionController::TestCase + def test_direct_render_to_string + ac = ActionController::Base.new() + assert_equal "Hello world!", ac.render_to_string(template: 'test/hello_world') + end +end + class ImplicitRenderTest < ActionController::TestCase tests ImplicitRenderTestController diff --git a/actionpack/test/controller/send_file_test.rb b/actionpack/test/controller/send_file_test.rb index 2820425c31..9df70dacbf 100644 --- a/actionpack/test/controller/send_file_test.rb +++ b/actionpack/test/controller/send_file_test.rb @@ -11,6 +11,8 @@ class SendFileController < ActionController::Base include ActionController::Testing layout "layouts/standard" # to make sure layouts don't interfere + before_action :file, only: :file_from_before_action + attr_writer :options def options @options ||= {} @@ -20,6 +22,10 @@ class SendFileController < ActionController::Base send_file(file_path, options) end + def file_from_before_action + raise 'No file sent from before action.' + end + def test_send_file_headers_bang options = { :type => Mime[:png], @@ -192,6 +198,15 @@ class SendFileTest < ActionController::TestCase assert_nil @controller.headers['Content-Disposition'] end + def test_send_file_from_before_action + response = nil + assert_nothing_raised { response = process('file_from_before_action') } + assert_not_nil response + + assert_kind_of String, response.body + assert_equal file_data, response.body + end + %w(file data).each do |method| define_method "test_send_#{method}_status" do @controller.options = { :stream => false, :status => 500 } diff --git a/actionpack/test/dispatch/cookies_test.rb b/actionpack/test/dispatch/cookies_test.rb index dfcef14344..c7194cde4a 100644 --- a/actionpack/test/dispatch/cookies_test.rb +++ b/actionpack/test/dispatch/cookies_test.rb @@ -520,7 +520,7 @@ class CookiesTest < ActionController::TestCase def test_accessing_nonexistent_signed_cookie_should_not_raise_an_invalid_signature get :set_signed_cookie - assert_nil @controller.send(:cookies).signed[:non_existant_attribute] + assert_nil @controller.send(:cookies).signed[:non_existent_attribute] end def test_encrypted_cookie_using_default_serializer @@ -638,7 +638,7 @@ class CookiesTest < ActionController::TestCase def test_accessing_nonexistent_encrypted_cookie_should_not_raise_invalid_message get :set_encrypted_cookie - assert_nil @controller.send(:cookies).encrypted[:non_existant_attribute] + assert_nil @controller.send(:cookies).encrypted[:non_existent_attribute] end def test_setting_invalid_encrypted_cookie_should_return_nil_when_accessing_it diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index ade4b0c381..75fdc9469f 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -4795,3 +4795,33 @@ class TestPathParameters < ActionDispatch::IntegrationTest assert_equal "/ar | /ar/about", @response.body end end + +class TestInternalRoutingParams < ActionDispatch::IntegrationTest + Routes = ActionDispatch::Routing::RouteSet.new.tap do |app| + app.draw do + get '/test_internal/:internal' => 'internal#internal' + end + end + + class ::InternalController < ActionController::Base + def internal + head :ok + end + end + + APP = build_app Routes + + def app + APP + end + + def test_paths_with_partial_dynamic_segments_are_recognised + get '/test_internal/123' + assert_equal 200, response.status + + assert_equal( + { controller: 'internal', action: 'internal', internal: '123' }, + request.path_parameters + ) + end +end |