[rspec-users] Cookies - how to set in controller specs?

David Chelimsky dchelimsky at gmail.com
Wed Jul 2 14:27:06 EDT 2008


On Jul 2, 2008, at 1:21 PM, Christopher Bailey wrote:

> On Wed, Jul 2, 2008 at 10:52 AM, David Chelimsky  
> <dchelimsky at gmail.com> wrote:
>> On Jul 2, 2008, at 12:42 PM, Christopher Bailey wrote:
>>
>>> First, nevermind!  Oy!  I finally figured it out.  The reason it
>>> wasn't working in my controller code was that I was checking for
>>> "cookies[:cookie_key]", not "request.cookies[:cookie_key]"!  It's a
>>> bit strange how that manifested, given the fact that referencing  
>>> just
>>> "cookies" was a hash with values, but alas, that's what was  
>>> happening.
>>
>> According to the rails API docs you shouldn't have to do that:
>>
>> http://api.rubyonrails.org/classes/ActionController/Cookies.html
>>
>> I figured out how to make this work. Here were the steps I took to  
>> get there
>> and the solution:
>>
>> def some_action
>>   puts cookies.inspect, cookies[:cookie_key], cookies.class
>> end
>>
>> => {:cookie_key=>"cookie value"}
>> => nil
>> => ActionController::CookieJar
>>
>> So the object is not a Hash, it's a CookieJar, which acts as a  
>> proxy to a
>> Hash. And guess what it does when it accesses the Hash?
>>
>> @cookies[name.to_s]
>>
>> :)
>>
>> So .........
>>
>> This will actually work! I've proven it with an example that I've  
>> added to
>> rspec-rails -
>> http://github.com/dchelimsky/rspec-rails/tree/master/spec/rails/example/controller_spec_spec.rb 
>>  (look
>> for "should support setting a cookie in the request"):
>>
>> request.cookies['cookie_key'] = CGI::Cookie.new('cookie_key','cookie
>> value')
>>
>> That will let you access the cookies as documented in the action.
>>
>> I'm going to add some sort of support to rspec to make this a bit  
>> more
>> user-friendly and less error prone. I'll follow up when I've done so.
>
> And really, from my interpretation and experiments, if you look at
> CookieJar, you can set the value by just passing a string, or a hash.
> Passing an actual CGI::Cookie object you're sort of getting lucky due
> to how CGI::Cookie.new happens to parse the "value" key/value pair in
> the Hash that it gets sent by CookieJar.[]= method.  Unless I'm not
> reading it right, what happens when you do:
>
>  request.cookies['cookie_key'] =  
> CGI::Cookie.new('cookie_key','cookie value')
>
> is that in CookieJar.[]=, it will wind up doing:
>
>  CGI::Cookie.new( { "name" => name.to_s, "value" =>
> the_cookie_object_you_passed } )
>
> If you try that in script/console for example, you'll find that
> CGI::Cookie.new happens to parse the value (your cookie object
> instance) properly and extract out the actual value.  But instead, you
> can just simplify that all by simply doing:
>
>  request.cookies['cookie_key'] = 'cookie value'
>
> This seems like one of those cases where people were trying to be too
> tricky with Ruby code, and mixing symbols and strings in unclear ways
> and so on.

I'm thinking of replacing the existing cookies() method (in the  
example) with one that returns a CookieJarProxy that will allow you to  
do any of the following:

cookies['cookie_key'] = 'cookie value'
cookies[:cookie_key] = 'cookie value'

cookies['cookie_key'].should == 'cookie value'
cookies[:cookie_key].should == 'cookie value'

WDYT about that?


>
>
>
>> Cheers,
>> David
>>
>>
>>>
>>>
>>> So, thank you very much for your time (that I essentially wasted :(
>>>
>>> On Wed, Jul 2, 2008 at 9:57 AM, Christopher Bailey <chris at cobaltedge.com 
>>> >
>>> wrote:
>>>>
>>>> On Wed, Jul 2, 2008 at 9:41 AM, David Chelimsky <dchelimsky at gmail.com 
>>>> >
>>>> wrote:
>>>>>
>>>>> On Jul 2, 2008, at 11:15 AM, Christopher Bailey wrote:
>>>>>
>>>>>> On Wed, Jul 2, 2008 at 4:06 AM, David Chelimsky <dchelimsky at gmail.com 
>>>>>> >
>>>>>> wrote:
>>>>>> <snip>
>>>>>>>
>>>>>>> This is just one of those goofy things in Rails testing. I'm  
>>>>>>> not sure
>>>>>>> the best way to make it easier in rspec without breaking  
>>>>>>> existing
>>>>>>> examples in the process. Regardless, here's how you interact  
>>>>>>> with
>>>>>>> cookies from an example:
>>>>>>>
>>>>>>> To set a cookie:
>>>>>>>
>>>>>>> request.cookies[:cookie_key] = CGI::Cookie.new('cookie_key',  
>>>>>>> 'cookie
>>>>>>> value')
>>>>>>
>>>>>> When I do this, in order to get to this cookie in my controller  
>>>>>> code,
>>>>>> I have to do
>>>>>>
>>>>>> cookies[:cookie_key][:cookie_key]
>>>>>
>>>>> Sorry Christopher - try this:
>>>>>
>>>>> request.cookies[:cookie_key] = 'cookie value'
>>>>
>>>> I tried that (see below in my email - I just mistakenly wrote it
>>>> without the "request." at the beginning).  When I do this, it  
>>>> appears
>>>> to set it, but then trying to retrieve it in my controller fails  
>>>> (even
>>>> though the key is there, and the value is there, when then  
>>>> requesting
>>>> cookies[:cookie_key] I get no value back).  Pretty weird.
>>>>
>>>>
>>>>> Cheers,
>>>>> David
>>>>>
>>>>>> Basically, it appears that what it does is assign that key a  
>>>>>> hash of
>>>>>> its own.  That makes sense of course, as I realize a cookie is  
>>>>>> really
>>>>>> a hash of name, value, path, expires, and so on.  However, it  
>>>>>> doesn't
>>>>>> jive with the retrieval, as you shouldn't have to double  
>>>>>> reference it
>>>>>> (which I believe is essentially the point of the [] method on
>>>>>> ActionController::CookieJar and is not how things are  
>>>>>> documented).
>>>>>>
>>>>>> However, what's really behaving weird, is if I do:
>>>>>>
>>>>>> cookies[:cookie_key] = "1234"
>>>>>>
>>>>>> Then, in my controller code, if I look at "cookies", it shows  
>>>>>> that
>>>>>> cookies is a hash, and if I call .keys on it, it spits out
>>>>>> ":cookie_key", and if I call .values on it, it says "1234", but  
>>>>>> if I
>>>>>> then go and do cookies[:cookie_key], it gives me nil.
>>>>>>
>>>>>> Again, I have to suspect something weird going on with Rails test
>>>>>> environment/RSpec, since all this works fine outside of tests.   
>>>>>> Any
>>>>>> suggestions on how to debug this further or what might be wrong?
>>>>>>
>>>>>> I should note I'm using Rails 2.1, and RSpec and rspec-rails from
>>>>>> about a week ago (from GitHub).
>>>>>>
>>>>>>> To read a cookie
>>>>>>>
>>>>>>> response.cookies[:cookie_key].should == ["expected value"]
>>>>>>>
>>>>>>> or
>>>>>>>
>>>>>>> cookies[:cookie_key].should == ["expected value"]
>>>>>>>
>>>>>>> Rails provides a cookies object that is actually  
>>>>>>> response.cookies, so
>>>>>>> you don't *have* to reference it through the response object.  
>>>>>>> I would,
>>>>>>> however, as I've been known to try to set a cookie in an  
>>>>>>> example using
>>>>>>> cookies when I should have been using request.cookies. So I  
>>>>>>> try to
>>>>>>> keep them explicit.
>>>>>>>
>>>>>>> HTH,
>>>>>>> David
>>>>>>> _______________________________________________
>>>>>>> rspec-users mailing list
>>>>>>> rspec-users at rubyforge.org
>>>>>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> --
>>>>>> Christopher Bailey
>>>>>> Cobalt Edge LLC
>>>>>> http://cobaltedge.com
>>>>>> _______________________________________________
>>>>>> rspec-users mailing list
>>>>>> rspec-users at rubyforge.org
>>>>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>>>>
>>>>> _______________________________________________
>>>>> rspec-users mailing list
>>>>> rspec-users at rubyforge.org
>>>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>>>>
>>>>
>>>>
>>>>
>>>> --
>>>> Christopher Bailey
>>>> Cobalt Edge LLC
>>>> http://cobaltedge.com
>>>>
>>>
>>>
>>>
>>> --
>>> Christopher Bailey
>>> Cobalt Edge LLC
>>> http://cobaltedge.com
>>> _______________________________________________
>>> rspec-users mailing list
>>> rspec-users at rubyforge.org
>>> http://rubyforge.org/mailman/listinfo/rspec-users
>>
>> _______________________________________________
>> rspec-users mailing list
>> rspec-users at rubyforge.org
>> http://rubyforge.org/mailman/listinfo/rspec-users
>>
>
>
>
> -- 
> Christopher Bailey
> Cobalt Edge LLC
> http://cobaltedge.com
> _______________________________________________
> rspec-users mailing list
> rspec-users at rubyforge.org
> http://rubyforge.org/mailman/listinfo/rspec-users



More information about the rspec-users mailing list