Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
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...
commit 97a178bfa4d5101dca73ae931cc9c77385d8c97e 1 parent 1bcfce0
@jnewland jnewland authored dhh committed
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
Please sign in to comment.
Something went wrong with that request. Please try again.