Skip to content

Commit

Permalink
Add cookiejar to Rack::MockResponse
Browse files Browse the repository at this point in the history
  • Loading branch information
ericproulx committed Dec 30, 2023
1 parent 77f2cec commit fcd6364
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 30 deletions.
30 changes: 15 additions & 15 deletions spec/grape/endpoint_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,11 @@ def app

get('/get/cookies')

expect(last_response_cookies).to contain_exactly(
'cookie3=symbol',
'cookie4=secret+code+here',
'my-awesome-cookie1=is+cool',
'my-awesome-cookie2=is+cool+too; domain=my.example.com; path=/; secure'
expect(last_response.cookie_jar).to contain_exactly(
{ 'name' => 'cookie3', 'value' => 'symbol' },
{ 'name' => 'cookie4', 'value' => 'secret code here' },
{ 'name' => 'my-awesome-cookie1', 'value' => 'is cool' },
{ 'name' => 'my-awesome-cookie2', 'value' => 'is cool too', 'domain' => 'my.example.com', 'path' => '/', 'secure' => true }
)
end

Expand All @@ -191,7 +191,7 @@ def app

get '/username'
expect(last_response.body).to eq('mrplum')
expect(last_response.headers['Set-Cookie']).to be_nil
expect(last_response.cookie_jar).to be_empty
end

it 'sets and update browser cookies' do
Expand All @@ -203,9 +203,9 @@ def app

get '/username'
expect(last_response.body).to eq('user_test')
expect(last_response_cookies).to contain_exactly(
'sandbox=true',
'username=user_test'
expect(last_response.cookie_jar).to contain_exactly(
{ 'name' => 'sandbox', 'value' => 'true' },
{ 'name' => 'username', 'value' => 'user_test' }
)
end

Expand All @@ -221,9 +221,9 @@ def app
end
get '/test'
expect(last_response.body).to eq('3')
expect(last_response_cookies).to contain_exactly(
"and_this=; max-age=0; expires=#{cookie_expires_value}",
"delete_this_cookie=; max-age=0; expires=#{cookie_expires_value}"
expect(last_response.cookie_jar).to contain_exactly(
{ 'name' => 'and_this', 'value' => '', 'max-age' => 0, 'expires' => Time.at(0) },
{ 'name' => 'delete_this_cookie', 'value' => '', 'max-age' => 0, 'expires' => Time.at(0) }
)
end

Expand All @@ -239,9 +239,9 @@ def app
end
get '/test'
expect(last_response.body).to eq('3')
expect(last_response_cookies).to contain_exactly(
"and_this=; path=/test; max-age=0; expires=#{cookie_expires_value}",
"delete_this_cookie=; path=/test; max-age=0; expires=#{cookie_expires_value}"
expect(last_response.cookie_jar).to contain_exactly(
{ 'name' => 'and_this', 'path' => '/test', 'value' => '', 'max-age' => 0, 'expires' => Time.at(0) },
{ 'name' => 'delete_this_cookie', 'path' => '/test', 'value' => '', 'max-age' => 0, 'expires' => Time.at(0) }
)
end
end
Expand Down
15 changes: 0 additions & 15 deletions spec/support/cookie_helper.rb

This file was deleted.

54 changes: 54 additions & 0 deletions spec/support/cookie_jar.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# frozen_string_literal: true

require 'uri'

module Rack
class MockResponse
def cookie_jar
@cookie_jar ||= Array(headers['Set-Cookie']).flat_map { |h| h.split("\n") }.map { |c| Cookie.new(c).to_h }
end

# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie
class Cookie
attr_reader :attributes

def initialize(raw)
@attributes = raw.split(/;\s*/).flat_map.with_index do |attribute, i|
attribute, value = attribute.split('=', 2)
if i.zero?
[['name', attribute], ['value', unescape(value)]]
else
[[attribute.downcase, parse_value(attribute, value)]]
end
end.to_h.freeze
end

def to_h
@attributes.dup
end

def to_s
@attributes.to_s
end

private

def unescape(value)
URI.decode_www_form_component(value, Encoding::UTF_8)
end

def parse_value(attribute, value)
case attribute
when 'expires'
Time.parse(value)
when 'max-age'
value.to_i
when 'secure', 'httponly', 'partitioned'
true
else
unescape(value)
end
end
end
end
end

0 comments on commit fcd6364

Please sign in to comment.