Skip to content

Commit

Permalink
Make Rack::MockResponse handle non-hash headers
Browse files Browse the repository at this point in the history
Rack::MockResponse inherits from Rack::Response, which already
uses a HeaderHash for the headers.  The original_headers were
only used for cookie parsing, which for some reason was happening
before the call to super in initialize (so the headers weren't
available yet). There seems to be no reason why the cookie parsing
can't happen after the call to super, in which case we can use the
headers directly.

Fixes rack#1629
Fixes rack#1630

Co-authored-by: Matt Palmer <mpalmer@hezmatt.org>
  • Loading branch information
jeremyevans and mpalmer committed Jul 14, 2020
1 parent a12c4a8 commit 30ecc6c
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. For info on

### Fixed

- Make Rack::MockResponse handle non-hash headers. ([#1629](https://github.com/rack/rack/issues/1629), [@jeremyevans](https://github.com/jeremyevans))
- TempfileReaper now deletes temp files if application raises an exception. ([#1679](https://github.com/rack/rack/issues/1679), [@jeremyevans](https://github.com/jeremyevans))
- Fix using Rack::Session::Cookie with coder: Rack::Session::Cookie::Base64::{JSON,Zip}. ([#1666](https://github.com/rack/rack/issues/1666), [@jeremyevans](https://github.com/jeremyevans))
- Avoid NoMethodError when accessing Rack::Session::Cookie without requiring delegate first. ([#1610](https://github.com/rack/rack/issues/1610), [@onigra](https://github.com/onigra))
Expand Down
6 changes: 3 additions & 3 deletions lib/rack/mock.rb
Expand Up @@ -184,10 +184,10 @@ class << self
def initialize(status, headers, body, errors = StringIO.new(""))
@original_headers = headers
@errors = errors.string if errors.respond_to?(:string)
@cookies = parse_cookies_from_header

super(body, status, headers)

@cookies = parse_cookies_from_header
buffered_body!
end

Expand Down Expand Up @@ -231,8 +231,8 @@ def cookie(name)

def parse_cookies_from_header
cookies = Hash.new
if original_headers.has_key? 'Set-Cookie'
set_cookie_header = original_headers.fetch('Set-Cookie')
if headers.has_key? 'Set-Cookie'
set_cookie_header = headers.fetch('Set-Cookie')
set_cookie_header.split("\n").each do |cookie|
cookie_name, cookie_filling = cookie.split('=', 2)
cookie_attributes = identify_cookie_attributes cookie_filling
Expand Down
21 changes: 21 additions & 0 deletions test/spec_mock.rb
Expand Up @@ -330,6 +330,21 @@
res.cookie("i_dont_exist").must_be_nil
end

it "parses cookie headers provided as an array" do
res = Rack::MockRequest.new(->(env) { [200, [["set-cookie", "array=awesome"]], [""]] }).get("")
array_cookie = res.cookie("array")
array_cookie.value[0].must_equal "awesome"
end

it "parses multiple set-cookie headers provided as an array" do
cookie_headers = [["set-cookie", "array=awesome\nmultiple=times"]]
res = Rack::MockRequest.new(->(env) { [200, cookie_headers, [""]] }).get("")
array_cookie = res.cookie("array")
array_cookie.value[0].must_equal "awesome"
second_cookie = res.cookie("multiple")
second_cookie.value[0].must_equal "times"
end

it "provide access to the HTTP body" do
res = Rack::MockRequest.new(app).get("")
res.body.must_match(/rack/)
Expand All @@ -346,6 +361,12 @@
res.errors.must_include "foo"
end

it "handle enumerable headers that are not a hash" do
# this is exactly what rack-test does
res = Rack::MockResponse.new(200, [], [])
res.cookies.must_equal({})
end

it "allow calling body.close afterwards" do
# this is exactly what rack-test does
body = StringIO.new("hi")
Expand Down

0 comments on commit 30ecc6c

Please sign in to comment.