Skip to content

Commit

Permalink
Decorate responses from Rack Middleware and Rails Metal for the purpo…
Browse files Browse the repository at this point in the history
…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
jnewland authored and dhh committed Dec 17, 2008
1 parent 1bcfce0 commit 97a178b
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 10 deletions.
27 changes: 17 additions & 10 deletions actionpack/lib/action_controller/integration.rb
Expand Up @@ -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",
Expand Down Expand Up @@ -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
Expand All @@ -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"
Expand Down
35 changes: 35 additions & 0 deletions actionpack/test/controller/integration_test.rb
Expand Up @@ -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.