Closed raldred closed 5 years ago
Request spec doesn't support testing cookies, but controller spec does. What's the problem with you using controller spec?
No problem, like I said controller specs are fine, merely raising the gap in functionality.
Since controller specs are discouraged these days, I wouldn't expect to see their features moved to request specs. Instead, perhaps we should directly set the cookie header when calling get
.
agree @mikegee, in a similar fashion to passing params and headers. I suspect this is really down to a limitation of Rails' integration tests.
I wonder if you can do...
headers: {"HTTP_COOKIE" => "key=value; key2=value2;"}
Most of the behaviour for these sets of specs is direct from Rails, can you see if it works in the minitest equivalent for me?
I actually just tried to reproduce this and failed.
@raldred Thanks for the issue. We need a little more detail to be able to reproduce this.
Could you please provide us with a rails app that we can clone that demonstrates the issue. Specifically it'd be great if
1) you could rails new
an application and commit
2) make all the changes necessary to reproduce the issue and commit
then, provide us with a description of how to clone your application and reproduce the issue.
Thanks :)
@samphippen cc: @raldred I reproduce this issue. Please check if you have the time.
This is reproduced Rails application.
git@github.com:taki/rpsec-rails-does-not-set-cookie.git
Just pass cookies in the header as was mentioned before
get "/logout", nil, {'cookie' => '_cookiename=123'}
expect(response.cookies['_cookiename']).to_not be_present
Hello
TL;DR
Use response.cookies
when you don't change cookies inside your test
# in controller
def show
cookies["user_name"] = nil
head 200
end
# in test
RSpec.describe SignOutsController, type: :request do
describe 'GET /signout' do
it "clear cookie value" do
get "/sign_out"
expect(response.cookies["user_name"]).to eq(nil)
end
end
end
Use cookies
to set and expect when you set cookies inside your test
# in controller
def show
cookies.delete("user_name")
head 200
end
# in test
RSpec.describe SignOutsController, type: :request do
describe 'GET /signout' do
it "clear cookie value" do
cookies["user_name"] = "Sam"
get "/sign_out"
expect(cookies["user_name"]).to eq("")
end
end
end
I finaly took some times to look at this issue. I jumped to Rails source code on cookies test an especially one that look similar to the last reproduction case published by @taki?
https://github.com/rails/rails/blob/b9ca94caea2ca6a6cc09abaffaad67b447134079/actionpack/test/controller/integration_test.rb#L272-L280 or https://github.com/rails/rails/blob/43866b2ca338375b964b0b905ee20f74f9b21b22/actionpack/test/dispatch/cookies_test.rb#L1136-L1142
When setting cookies with cookies[]
you need to use cookies
for expectation.
For example:
# app/controllers/sign_outs_controller.rb
class SignOutsController < ApplicationController
def show
cookies["inside_controller"] = "FROM_CONTROLLER"
puts "cookies inside controller #{cookies.to_hash}"
head 200
end
end
# spec/requests/sign_outs_controller_spec.rb
require 'rails_helper'
RSpec.describe SignOutsController, type: :request do
describe 'GET /signout' do
specify do
cookies["inside_test"] = "FROM_TEST"
get "/sign_out"
puts ">> With response.cookies: #{response.cookies.inspect}"
puts ">> With cookies.to_hash: #{cookies.to_hash.inspect}"
puts ">> With headers[\"Set-Cookie\"]: #{headers["Set-Cookie"]}"
end
end
end
SignOutsController
GET /signout
cookies inside controller {"inside_test"=>"FROM_TEST", "inside_controller"=>"FROM_CONTROLLER"}
>> With response.cookies: {"inside_controller"=>"FROM_CONTROLLER"}
>> With cookies.to_hash: {"inside_controller"=>"FROM_CONTROLLER", "inside_test"=>"FROM_TEST"}
>> With headers["Set-Cookie"]: "inside_controller=FROM_CONTROLLER; path=/"
example at ./spec/requests/sign_outs_controller_spec.rb:5
When using response.cookies
it is only on cookies not modified inside the test.
This issue is for me not related to rspec-rails because we can see the same behavior tested into actionpack codebase. I am in favor of closing this issue but maybe we could add some documentation?
@benoittgt do you want to send a PR to update the cucumber features with whatever you think will work best?
Good idea @samphippen. I will try now.
There is also an old documentation on this https://relishapp.com/rspec/rspec-rails/docs/controller-specs/cookies I will send a PR to update this one too.
Sorry I had my daughter that wake-up after her nap was not able to make it this afternoon. 😃
Documentation will be simplified on next rspec-rails 4 documentation. See #2127
I am closing this issue because I don't think we can do more.
What Ruby, Rails and RSpec versions are you using?
Ruby version: 2.5.0 Rails version: 5.2.0 Rspec version: 3.7
Observed behaviour
Cookies are not available in the controller
Expected behaviour
Cookies should be available in the controller
spec
controller
Works fine in controller specs