Browse files

Decorate responses from Rack Middleware and Rails Metal for the purpo…

…ses of integration testing. A test for the following Metal:

    class Poller < Rails::Rack::Metal
      def call(env)
        if env["PATH_INFO"] =~ /^\/poller/
          [200, {"Content-Type" => "text/plain"}, "Hello World!"]
        else
          super
        end
      end
    end

might be tested like so:

  class PollerTest < ActionController::IntegrationTest
    test "poller returns hello world" do
      get "/poller"
      assert_response 200
      assert_response :success
      assert_response :ok
      assert_equal "Hello World!", response.body
    end
  end

[#1588 state:committed]

Signed-off-by: David Heinemeier Hansson <david@loudthinking.com>
  • Loading branch information...
1 parent 1bcfce0 commit 97a178bfa4d5101dca73ae931cc9c77385d8c97e @jnewland jnewland committed with dhh Dec 17, 2008
Showing with 52 additions and 10 deletions.
  1. +17 −10 actionpack/lib/action_controller/integration.rb
  2. +35 −0 actionpack/test/controller/integration_test.rb
View
27 actionpack/lib/action_controller/integration.rb
@@ -276,6 +276,7 @@ def process(method, path, parameters = nil, headers = nil)
"SCRIPT_NAME" => "",
"REQUEST_URI" => path,
+ "PATH_INFO" => path,
"HTTP_HOST" => host,
"REMOTE_ADDR" => remote_addr,
"CONTENT_TYPE" => "application/x-www-form-urlencoded",
@@ -310,16 +311,6 @@ def process(method, path, parameters = nil, headers = nil)
status, headers, body = app.call(env)
@request_count += 1
- if @controller = ActionController::Base.last_instantiation
- @request = @controller.request
- @response = @controller.response
-
- # Decorate the response with the standard behavior of the
- # TestResponse so that things like assert_response can be
- # used in integration tests.
- @response.extend(TestResponseBehavior)
- end
-
@html_document = nil
@status = status.to_i
@@ -335,6 +326,22 @@ def process(method, path, parameters = nil, headers = nil)
@body = ""
body.each { |part| @body << part }
+ if @controller = ActionController::Base.last_instantiation
+ @request = @controller.request
+ @response = @controller.response
+ else
+ # Decorate responses from Rack Middleware and Rails Metal
+ # as an AbstractResponse for the purposes of integration testing
+ @response = AbstractResponse.new
+ @response.headers = @headers.merge('Status' => status.to_s)
+ @response.body = @body
+ end
+
+ # Decorate the response with the standard behavior of the
+ # TestResponse so that things like assert_response can be
+ # used in integration tests.
+ @response.extend(TestResponseBehavior)
+
return @status
rescue MultiPartNeededException
boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
View
35 actionpack/test/controller/integration_test.rb
@@ -373,4 +373,39 @@ def with_test_route_set
end
end
+class MetalTest < ActionController::IntegrationTest
+ require(File.dirname(__FILE__) + "/../../../railties/lib/rails/rack/metal.rb")
+
+ class Poller < ::Rails::Rack::Metal
+ def call(env)
+ if env["PATH_INFO"] =~ /^\/success/
+ [200, {"Content-Type" => "text/plain"}, "Hello World!"]
+ elsif env["PATH_INFO"] =~ /^\/failure/
+ [404, {"Content-Type" => "text/plain"}, '']
+ else
+ super
+ end
+ end
+ end
+
+ def setup
+ @integration_session = ActionController::Integration::Session.new(Poller)
+ end
+
+ def test_successful_get
+ get "/success"
+ assert_response 200
+ assert_response :success
+ assert_response :ok
+ assert_equal "Hello World!", response.body
+ end
+
+ def test_failed_get
+ get "/failure"
+ assert_response 404
+ assert_response :not_found
+ assert_equal '', response.body
+ end
+end
+
end

0 comments on commit 97a178b

Please sign in to comment.