diff options
-rw-r--r-- | actionpack/lib/action_dispatch/http/response.rb | 8 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/testing/integration.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/testing/test_response.rb | 13 | ||||
-rw-r--r-- | actionpack/test/controller/integration_test.rb | 34 | ||||
-rw-r--r-- | actionpack/test/controller/test_case_test.rb | 46 |
5 files changed, 69 insertions, 34 deletions
diff --git a/actionpack/lib/action_dispatch/http/response.rb b/actionpack/lib/action_dispatch/http/response.rb index 4061ea71a3..a895d1ab18 100644 --- a/actionpack/lib/action_dispatch/http/response.rb +++ b/actionpack/lib/action_dispatch/http/response.rb @@ -113,10 +113,10 @@ module ActionDispatch # :nodoc: # The underlying body, as a streamable object. attr_reader :stream - def initialize(status = 200, header = {}, body = []) + def initialize(status = 200, header = {}, body = [], default_headers: self.class.default_headers) super() - header = merge_default_headers(header, self.class.default_headers) + header = merge_default_headers(header, default_headers) self.body, self.header, self.status = body, header, status @@ -308,9 +308,7 @@ module ActionDispatch # :nodoc: end def merge_default_headers(original, default) - return original unless default.respond_to?(:merge) - - default.merge(original) + default.respond_to?(:merge) ? default.merge(original) : original end def build_buffer(response, body) diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index 9b00616968..2fe37c5bd4 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -369,7 +369,7 @@ module ActionDispatch @request_count += 1 @request = ActionDispatch::Request.new(session.last_request.env) response = _mock_session.last_response - @response = ActionDispatch::TestResponse.new(response.status, response.headers, response.body) + @response = ActionDispatch::TestResponse.from_response(response) @html_document = nil @url_options = nil diff --git a/actionpack/lib/action_dispatch/testing/test_response.rb b/actionpack/lib/action_dispatch/testing/test_response.rb index 369ea1467c..a9b88ac5fd 100644 --- a/actionpack/lib/action_dispatch/testing/test_response.rb +++ b/actionpack/lib/action_dispatch/testing/test_response.rb @@ -7,11 +7,7 @@ module ActionDispatch # See Response for more information on controller response objects. class TestResponse < Response def self.from_response(response) - new.tap do |resp| - resp.status = response.status - resp.headers = response.headers - resp.body = response.body - end + new response.status, response.headers, response.body, default_headers: nil end # Was the response successful? @@ -25,12 +21,5 @@ module ActionDispatch # Was there a server-side error? alias_method :error?, :server_error? - - def merge_default_headers(original, *args) - # Default headers are already applied, no need to merge them a second time. - # This makes sure that default headers, removed in controller actions, will - # not be reapplied to the test response. - original - end end end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 9ab1549e8e..438c044da2 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -397,9 +397,9 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest redirect_to action_url('get') end - def remove_default_header - response.headers.except! 'X-Frame-Options' - head :ok + def remove_header + response.headers.delete params[:header] + head :ok, 'c' => '3' end end @@ -640,25 +640,27 @@ class IntegrationProcessTest < ActionDispatch::IntegrationTest end end - def test_removed_default_headers_on_test_response_are_not_reapplied + def test_respect_removal_of_default_headers_by_a_controller_action with_test_route_set do - begin - header_to_remove = 'X-Frame-Options' - original_default_headers = ActionDispatch::Response.default_headers - ActionDispatch::Response.default_headers = { - 'X-Content-Type-Options' => 'nosniff', - header_to_remove => 'SAMEORIGIN', - } - get '/remove_default_header' - assert_includes headers, 'X-Content-Type-Options' - assert_not_includes headers, header_to_remove, "Should not contain removed default header" - ensure - ActionDispatch::Response.default_headers = original_default_headers + with_default_headers 'a' => '1', 'b' => '2' do + get '/remove_header', params: { header: 'a' } end end + + assert_not_includes @response.headers, 'a', 'Response should not include default header removed by the controller action' + assert_includes @response.headers, 'b' + assert_includes @response.headers, 'c' end private + def with_default_headers(headers) + original = ActionDispatch::Response.default_headers + ActionDispatch::Response.default_headers = headers + yield + ensure + ActionDispatch::Response.default_headers = original + end + def with_test_route_set with_routing do |set| controller = ::IntegrationProcessTest::IntegrationController.clone diff --git a/actionpack/test/controller/test_case_test.rb b/actionpack/test/controller/test_case_test.rb index ca854040b7..e348749f78 100644 --- a/actionpack/test/controller/test_case_test.rb +++ b/actionpack/test/controller/test_case_test.rb @@ -965,6 +965,52 @@ XML end end +class ResponseDefaultHeadersTest < ActionController::TestCase + class TestController < ActionController::Base + def remove_header + headers.delete params[:header] + head :ok, 'C' => '3' + end + end + + setup do + @original = ActionDispatch::Response.default_headers + @defaults = { 'A' => '1', 'B' => '2' } + ActionDispatch::Response.default_headers = @defaults + end + + teardown do + ActionDispatch::Response.default_headers = @original + end + + def setup + super + @controller = TestController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + @request.env['PATH_INFO'] = nil + @routes = ActionDispatch::Routing::RouteSet.new.tap do |r| + r.draw do + get ':controller(/:action(/:id))' + end + end + end + + test "response contains default headers" do + # Response headers start out with the defaults + assert_equal @defaults, response.headers + + get :remove_header, params: { header: 'A' } + assert_response :ok + + # After a request, the response in the test case doesn't have the + # defaults merged on top again. + assert_not_includes response.headers, 'A' + assert_includes response.headers, 'B' + assert_includes response.headers, 'C' + end +end + module EngineControllerTests class Engine < ::Rails::Engine isolate_namespace EngineControllerTests |