diff options
Diffstat (limited to 'actionpack')
-rw-r--r-- | actionpack/CHANGELOG.md | 10 | ||||
-rw-r--r-- | actionpack/lib/action_controller/test_case.rb | 37 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/parameter_filter.rb | 24 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/cookies.rb | 14 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/testing/test_process.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/testing/test_request.rb | 17 | ||||
-rw-r--r-- | actionpack/test/controller/caching_test.rb | 1 | ||||
-rw-r--r-- | actionpack/test/controller/mime/respond_to_test.rb | 79 | ||||
-rw-r--r-- | actionpack/test/dispatch/request_test.rb | 1 | ||||
-rw-r--r-- | actionpack/test/dispatch/test_request_test.rb | 2 |
10 files changed, 88 insertions, 99 deletions
diff --git a/actionpack/CHANGELOG.md b/actionpack/CHANGELOG.md index cb5e7516fb..46856ffc5d 100644 --- a/actionpack/CHANGELOG.md +++ b/actionpack/CHANGELOG.md @@ -1,3 +1,13 @@ +* Add ability to filter parameters based on parent keys. + + # matches {credit_card: {code: "xxxx"}} + # doesn't match {file: { code: "xxxx"}} + config.filter_parameters += [ "credit_card.code" ] + + See #13897. + + *Guillaume Malette* + * Deprecate passing first parameter as `Hash` and default status code for `head` method. *Mehmet Emin İNAÇ* diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 96f161fb09..5489a0fde0 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -65,14 +65,6 @@ module ActionController @method = @request_method = nil @fullpath = @ip = @remote_ip = @protocol = nil @env['action_dispatch.request.query_parameters'] = {} - @set_cookies ||= {} - @set_cookies.update(Hash[cookie_jar.instance_variable_get("@set_cookies").map{ |k,o| [k,o[:value]] }]) - deleted_cookies = cookie_jar.instance_variable_get("@delete_cookies") - @set_cookies.reject!{ |k,v| deleted_cookies.include?(k) } - cookie_jar.update(rack_cookies) - cookie_jar.update(cookies) - cookie_jar.update(@set_cookies) - cookie_jar.recycle! end private @@ -83,17 +75,9 @@ module ActionController end class TestResponse < ActionDispatch::TestResponse - def recycle! - initialize - end end class LiveTestResponse < Live::Response - def recycle! - @body = nil - initialize - end - def body @body ||= super end @@ -317,7 +301,9 @@ module ActionController # Note that the request method is not verified. The different methods are # available to make the tests more expressive. def get(action, *args) - process_with_kwargs("GET", action, *args) + res = process_with_kwargs("GET", action, *args) + cookies.update res.cookies + res end # Simulate a POST request with the given parameters and set/volley the response. @@ -451,8 +437,13 @@ module ActionController @controller.extend(Testing::Functional) end + self.cookies.update @request.cookies + @request.env['HTTP_COOKIE'] = cookies.to_header + @request.env['action_dispatch.cookies'] = nil + @request.recycle! - @response.recycle! + @response = build_response @response_klass + @response.request = @request @controller.recycle! @request.env['REQUEST_METHOD'] = http_method @@ -479,9 +470,12 @@ module ActionController @controller.recycle! @controller.process(action) + @request.env.delete 'HTTP_COOKIE' + if cookies = @request.env['action_dispatch.cookies'] unless @response.committed? cookies.write(@response) + self.cookies.update(cookies.instance_variable_get(:@cookies)) end end @response.prepare! @@ -503,11 +497,11 @@ module ActionController def setup_controller_request_and_response @controller = nil unless defined? @controller - response_klass = TestResponse + @response_klass = TestResponse if klass = self.class.controller_class if klass < ActionController::Live - response_klass = LiveTestResponse + @response_klass = LiveTestResponse end unless @controller begin @@ -519,7 +513,8 @@ module ActionController end @request = build_request - @response = build_response response_klass + @request.env["rack.request.cookie_hash"] = {}.with_indifferent_access + @response = build_response @response_klass @response.request = @request if @controller diff --git a/actionpack/lib/action_dispatch/http/parameter_filter.rb b/actionpack/lib/action_dispatch/http/parameter_filter.rb index df4b073a17..6e058b829e 100644 --- a/actionpack/lib/action_dispatch/http/parameter_filter.rb +++ b/actionpack/lib/action_dispatch/http/parameter_filter.rb @@ -30,36 +30,46 @@ module ActionDispatch when Regexp regexps << item else - strings << item.to_s + strings << Regexp.escape(item.to_s) end end + deep_regexps, regexps = regexps.partition { |r| r.to_s.include?("\\.") } + deep_strings, strings = strings.partition { |s| s.include?("\\.") } + regexps << Regexp.new(strings.join('|'), true) unless strings.empty? - new regexps, blocks + deep_regexps << Regexp.new(deep_strings.join('|'), true) unless deep_strings.empty? + + new regexps, deep_regexps, blocks end - attr_reader :regexps, :blocks + attr_reader :regexps, :deep_regexps, :blocks - def initialize(regexps, blocks) + def initialize(regexps, deep_regexps, blocks) @regexps = regexps + @deep_regexps = deep_regexps.any? ? deep_regexps : nil @blocks = blocks end - def call(original_params) + def call(original_params, parents = []) filtered_params = {} original_params.each do |key, value| + parents.push(key) if deep_regexps if regexps.any? { |r| key =~ r } value = FILTERED + elsif deep_regexps && (joined = parents.join('.')) && deep_regexps.any? { |r| joined =~ r } + value = FILTERED elsif value.is_a?(Hash) - value = call(value) + value = call(value, parents) elsif value.is_a?(Array) - value = value.map { |v| v.is_a?(Hash) ? call(v) : v } + value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v } elsif blocks.any? key = key.dup if key.duplicable? value = value.dup if value.duplicable? blocks.each { |b| b.call(key, value) } end + parents.pop if deep_regexps filtered_params[key] = value end diff --git a/actionpack/lib/action_dispatch/middleware/cookies.rb b/actionpack/lib/action_dispatch/middleware/cookies.rb index dd1f140051..07d97bd6bd 100644 --- a/actionpack/lib/action_dispatch/middleware/cookies.rb +++ b/actionpack/lib/action_dispatch/middleware/cookies.rb @@ -8,7 +8,7 @@ require 'active_support/json' module ActionDispatch class Request < Rack::Request def cookie_jar - env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(self) + env['action_dispatch.cookies'] ||= Cookies::CookieJar.build(env, host, ssl?, cookies) end end @@ -228,16 +228,12 @@ module ActionDispatch } end - def self.build(request) - env = request.env + def self.build(env, host, secure, cookies) key_generator = env[GENERATOR_KEY] options = options_for_env env - host = request.host - secure = request.ssl? - new(key_generator, host, secure, options).tap do |hash| - hash.update(request.cookies) + hash.update(cookies) end end @@ -283,6 +279,10 @@ module ActionDispatch self end + def to_header + @cookies.map { |k,v| "#{k}=#{v}" }.join ';' + end + def handle_options(options) #:nodoc: options[:path] ||= "/" diff --git a/actionpack/lib/action_dispatch/testing/test_process.rb b/actionpack/lib/action_dispatch/testing/test_process.rb index 415ef80cd2..494644cd46 100644 --- a/actionpack/lib/action_dispatch/testing/test_process.rb +++ b/actionpack/lib/action_dispatch/testing/test_process.rb @@ -19,7 +19,7 @@ module ActionDispatch end def cookies - @request.cookie_jar + @cookie_jar ||= Cookies::CookieJar.build(@request.env, @request.host, @request.ssl?, @request.cookies) end def redirect_to_url diff --git a/actionpack/lib/action_dispatch/testing/test_request.rb b/actionpack/lib/action_dispatch/testing/test_request.rb index 4b9a088265..b40da46703 100644 --- a/actionpack/lib/action_dispatch/testing/test_request.rb +++ b/actionpack/lib/action_dispatch/testing/test_request.rb @@ -4,15 +4,12 @@ require 'rack/utils' module ActionDispatch class TestRequest < Request DEFAULT_ENV = Rack::MockRequest.env_for('/', - 'HTTP_HOST' => 'test.host', - 'REMOTE_ADDR' => '0.0.0.0', - 'HTTP_USER_AGENT' => 'Rails Testing' + 'HTTP_HOST' => 'test.host', + 'REMOTE_ADDR' => '0.0.0.0', + 'HTTP_USER_AGENT' => 'Rails Testing', + "rack.request.cookie_hash" => {}.with_indifferent_access ) - def self.new(env = {}) - super - end - def initialize(env = {}) env = Rails.application.env_config.merge(env) if defined?(Rails.application) && Rails.application super(default_env.merge(env)) @@ -63,12 +60,6 @@ module ActionDispatch @env['HTTP_ACCEPT'] = Array(mime_types).collect(&:to_s).join(",") end - alias :rack_cookies :cookies - - def cookies - @cookies ||= {}.with_indifferent_access - end - private def default_env diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index f21dd87400..4f5af85fea 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -381,6 +381,7 @@ class AutomaticCollectionCacheTest < ActionController::TestCase @controller.perform_caching = true @controller.partial_rendered_times = 0 @controller.cache_store = ActiveSupport::Cache::MemoryStore.new + ActionView::PartialRenderer.collection_cache = @controller.cache_store end def test_collection_fetches_cached_views diff --git a/actionpack/test/controller/mime/respond_to_test.rb b/actionpack/test/controller/mime/respond_to_test.rb index 8591bdb4d9..71660c87a2 100644 --- a/actionpack/test/controller/mime/respond_to_test.rb +++ b/actionpack/test/controller/mime/respond_to_test.rb @@ -4,6 +4,13 @@ require "active_support/log_subscriber/test_helper" class RespondToController < ActionController::Base layout :set_layout + before_action { + case params[:v] + when String then request.variant = params[:v].to_sym + when Array then request.variant = params[:v].map(&:to_sym) + end + } + def html_xml_or_rss respond_to do |type| type.html { render :text => "HTML" } @@ -612,8 +619,7 @@ class RespondToControllerTest < ActionController::TestCase logger = ActiveSupport::LogSubscriber::TestHelper::MockLogger.new old_logger, ActionController::Base.logger = ActionController::Base.logger, logger - @request.variant = :invalid - get :variant_with_implicit_rendering + get :variant_with_implicit_rendering, params: { v: :invalid } assert_response :no_content assert_equal 1, logger.logged(:info).select{ |s| s =~ /No template found/ }.size, "Implicit head :no_content not logged" ensure @@ -626,28 +632,24 @@ class RespondToControllerTest < ActionController::TestCase end def test_variant_with_implicit_rendering - @request.variant = :implicit - get :variant_with_implicit_rendering + get :variant_with_implicit_rendering, params: { v: :implicit } assert_response :no_content end def test_variant_with_implicit_template_rendering - @request.variant = :mobile - get :variant_with_implicit_rendering + get :variant_with_implicit_rendering, params: { v: :mobile } assert_equal "text/html", @response.content_type assert_equal "mobile", @response.body end def test_variant_with_format_and_custom_render - @request.variant = :phone - get :variant_with_format_and_custom_render + get :variant_with_format_and_custom_render, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "mobile", @response.body end def test_multiple_variants_for_format - @request.variant = :tablet - get :multiple_variants_for_format + get :multiple_variants_for_format, params: { v: :tablet } assert_equal "text/html", @response.content_type assert_equal "tablet", @response.body end @@ -667,32 +669,27 @@ class RespondToControllerTest < ActionController::TestCase assert_equal "text/html", @response.content_type assert_equal "none", @response.body - @request.variant = :phone - get :variant_inline_syntax + get :variant_inline_syntax, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body end def test_variant_inline_syntax_without_block - @request.variant = :phone - get :variant_inline_syntax_without_block + get :variant_inline_syntax_without_block, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body end def test_variant_any - @request.variant = :phone - get :variant_any + get :variant_any, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body - @request.variant = :tablet - get :variant_any + get :variant_any, params: { v: :tablet } assert_equal "text/html", @response.content_type assert_equal "any", @response.body - @request.variant = :phablet - get :variant_any + get :variant_any, params: { v: :phablet } assert_equal "text/html", @response.content_type assert_equal "any", @response.body end @@ -702,54 +699,45 @@ class RespondToControllerTest < ActionController::TestCase assert_equal "text/html", @response.content_type assert_equal "any", @response.body - @request.variant = :phone - get :variant_any_any + get :variant_any_any, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body - @request.variant = :yolo - get :variant_any_any + get :variant_any_any, params: { v: :yolo } assert_equal "text/html", @response.content_type assert_equal "any", @response.body end def test_variant_inline_any - @request.variant = :phone - get :variant_any + get :variant_any, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body - @request.variant = :tablet - get :variant_inline_any + get :variant_inline_any, params: { v: :tablet } assert_equal "text/html", @response.content_type assert_equal "any", @response.body - @request.variant = :phablet - get :variant_inline_any + get :variant_inline_any, params: { v: :phablet } assert_equal "text/html", @response.content_type assert_equal "any", @response.body end def test_variant_inline_any_any - @request.variant = :phone - get :variant_inline_any_any + get :variant_inline_any_any, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body - @request.variant = :yolo - get :variant_inline_any_any + get :variant_inline_any_any, params: { v: :yolo } assert_equal "text/html", @response.content_type assert_equal "any", @response.body end def test_variant_any_implicit_render - @request.variant = :tablet - get :variant_any_implicit_render + get :variant_any_implicit_render, params: { v: :tablet } assert_equal "text/html", @response.content_type assert_equal "tablet", @response.body - @request.variant = :phablet - get :variant_any_implicit_render + get :variant_any_implicit_render, params: { v: :phablet } assert_equal "text/html", @response.content_type assert_equal "phablet", @response.body end @@ -759,36 +747,31 @@ class RespondToControllerTest < ActionController::TestCase assert_equal "text/html", @response.content_type assert_equal "none or phone", @response.body - @request.variant = :phone - get :variant_any_with_none + get :variant_any_with_none, params: { v: :phone } assert_equal "text/html", @response.content_type assert_equal "none or phone", @response.body end def test_format_any_variant_any - @request.variant = :tablet - get :format_any_variant_any, format: :js + get :format_any_variant_any, format: :js, params: { v: :tablet } assert_equal "text/javascript", @response.content_type assert_equal "tablet", @response.body end def test_variant_negotiation_inline_syntax - @request.variant = [:tablet, :phone] - get :variant_inline_syntax_without_block + get :variant_inline_syntax_without_block, params: { v: [:tablet, :phone] } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body end def test_variant_negotiation_block_syntax - @request.variant = [:tablet, :phone] - get :variant_plus_none_for_format + get :variant_plus_none_for_format, params: { v: [:tablet, :phone] } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body end def test_variant_negotiation_without_block - @request.variant = [:tablet, :phone] - get :variant_inline_syntax_without_block + get :variant_inline_syntax_without_block, params: { v: [:tablet, :phone] } assert_equal "text/html", @response.content_type assert_equal "phone", @response.body end diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 27ee8603e4..ff63c10e8d 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -989,6 +989,7 @@ class RequestParameterFilter < BaseRequestTest [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'], [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'], [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana'], + [{'deep'=>{'cc'=>{'code'=>'bar','bar'=>'foo'},'ss'=>{'code'=>'bar'}}},{'deep'=>{'cc'=>{'code'=>'[FILTERED]','bar'=>'foo'},'ss'=>{'code'=>'bar'}}},%w'deep.cc.code'], [{'baz'=>[{'foo'=>'baz'}, "1"]}, {'baz'=>[{'foo'=>'[FILTERED]'}, "1"]}, [/foo/]]] test_hashes.each do |before_filter, after_filter, filter_words| diff --git a/actionpack/test/dispatch/test_request_test.rb b/actionpack/test/dispatch/test_request_test.rb index cc35d4594e..a4c124070a 100644 --- a/actionpack/test/dispatch/test_request_test.rb +++ b/actionpack/test/dispatch/test_request_test.rb @@ -24,8 +24,6 @@ class TestRequestTest < ActiveSupport::TestCase assert_equal true, env.delete("rack.multithread") assert_equal true, env.delete("rack.multiprocess") assert_equal false, env.delete("rack.run_once") - - assert env.empty?, env.inspect end test "cookie jar" do |