1

我想测试我的 Rails 控制器是否path为 cookie 设置了有效的选项(在本例中)。我怎么能用 RSpec 做到这一点?

我的代码:

#Controller
def action
  #(...)
  cookies[:name] = { value:cookie_data,
                     path: cookie_path }
  #(...)
end

#spec 
it "sets cookie path" do
  get 'action'
  #I'd like do to something like that
  response.cookies['name'].path.should == '/some/path' 
end
4

3 回答 3

3

在尝试让 CGI::Cookie.parse 做正确的事情失败后,我最终滚动了自己的解析器。这很简单:

def parse_set_cookie_header(header)
  kv_pairs = header.split(/\s*;\s*/).map do |attr|
    k, v = attr.split '='

    [ k, v || nil ]
  end

  Hash[ kv_pairs ]
end

这是它产生的结果的示例:

饼干制作:

IN: "signup=VALUE_HERE; path=/subscriptions; secure; HttpOnly"
OUT: {"signup"=>"VALUE_HERE", "path"=>"/subscriptions", "secure"=>nil, "HttpOnly"=>nil}

Cookie 删除:

IN: "signup=; path=/subscriptions; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000; secure; HttpOnly"
OUT: {"signup"=>nil, "path"=>"/subscriptions", "max-age"=>"0", "expires"=>"Thu, 01 Jan 1970 00:00:00 -0000", "secure"=>nil, "HttpOnly"=>nil}

这是一个与之配套的示例规范:

describe 'the Set-Cookie header' do
  let(:value) { 'hello world' }

  let(:signup_cookie) do
    parse_set_cookie_header response.header['Set-Cookie']
  end

  before do
    get :index, :spec => 'set_signup_cookie'
  end

  it 'has a payload set for :signup' do
    expect(signup_cookie['signup']).to be_present
  end

  it 'has the right path' do
    expect(signup_cookie['path']).to eq '/subscriptions'
  end

  it 'has the secure flag set' do
    expect(signup_cookie).to have_key 'secure'
  end

  it 'has the HttpOnly flag set' do
    expect(signup_cookie).to have_key 'HttpOnly'
  end

  it 'is a session cookie (i.e. it has no :expires)' do
    expect(signup_cookie).not_to have_key 'expires'
  end

  it 'has no max-age' do
    expect(signup_cookie).not_to have_key 'max-age'
  end
end
于 2015-08-08T02:17:36.320 回答
0

我找到了解决方案,但这似乎是一种黑客行为。我想知道是否有更清洁的方法来做到这一点。

it "sets cookie path" do
  get 'action'
  match = response.header["Set-Cookie"].match(/path=(.*);?/)
  match.should_not be_nil
  match[1].should == '/some/path'
end
于 2012-10-29T15:39:17.317 回答
0

我已经尝试了这里提供的几种解决方案以及类似的线程。唯一对我有用的是检查 Set-Cookie 标头,如下所示:

it 'expires cookie in 15 minutes' do
  travel_to(Date.new(2016, 10, 25))
  post 'favorites', params: { flavor: 'chocolate' }
  travel_back

  details = 'favorite=chocolate; path=/; expires=Tue, 25 Oct 2016 07:15:00 GMT; HttpOnly'
  expect(response.header['Set-Cookie']).to eq details
end

这有点脆弱,因为 cookie 的其他非关键属性可能会破坏该字符串。但它确实使您远离 Rails 内部,并允许您一次检查多个属性。(注意这是一个反模式 rspec!)

如果你只关心一个属性,你可以像这样匹配它:

  expect(response.header['Set-Cookie']).to match(
    /favorite=chocolate.*; expires=Tue, 25 Oct 2016 07:15:00 GMT/
  )
于 2022-02-24T21:03:20.133 回答