Setting and reading cookies when using Rack::Test

I used the following for testing a sinatra app using rspec and turnip. I needed to write a feature to test that a particular request was setting a cookie with an expiry date and that it would behave correctly when a cookie was already present in the browser.

For example, to set the expiry date 30 days in the future:

1
set_cookie "name=value; expires=#{Time.now + 30.days}"

Cookies are set by the response’s Set-Cookie header. To check the expires option, we need to parse the header and create Cookie objects:

1
2
3
4
5
6
def cookies_from_response(response=last_response)
Hash[response["Set-Cookie"].lines.map { |line|
cookie = Rack::Test::Cookie.new(line.chomp)
[cookie.name, cookie]
}]
end

So now we can do something like:

1
2
cookie = cookies_from_response["cookie_name"]
expect(cookie.expires).to be_within(5.minutes).of(30.days.from_now)

The be_within matcher is perfect here because we cannot check the exact expiry date.