6

I'm using signed cookies in Rails 3 to enable a "remember-me" feature in an application. Everything works except I'm not able to functional test the cookies, since comparing cookies['remember_id'] gives me the encrypted cookie, and cookies.signed is not defined.

Any clues?

Ian
  • 4,195
  • 2
  • 25
  • 32

4 Answers4

8

The problem (at least on the surface) is that in the context of a functional test (ActionController::TestCase), the "cookies" object is a Hash, whereas when you work with the controllers, it's a ActionDispatch::Cookies::CookieJar object. So we need to convert it to a CookieJar object so that we can use the "signed" method on it to convert it to a SignedCookieJar.

You can put the following into your functional tests (after a get request) to convert cookies from a Hash to a CookieJar object

@request.cookies.merge!(cookies)
cookies = ActionDispatch::Cookies::CookieJar.build(@request)
Polemarch
  • 1,646
  • 14
  • 10
  • I came across this same problem, so thanks! I was wondering if it is necessary to include these two lines multiple times, if in the same test a new/second request is made thereby generating new cookies? Would it be possible to turn it into a test helper (with cookies as a parameter)? – Nick Jan 23 '16 at 17:00
  • The method `merge!` is deprecated in Rails 5. What would be the right code in Rails 5? (if I'm not mistaken `merge` is still available) – Marty Jul 06 '16 at 16:22
2

This is slightly off-topic, but I was having trouble getting the Rails 3 solution to work in Rails 5 because ActionDispatch::Cookies::CookieJar.build has changed. This did the trick:

jar = ActionDispatch::Cookies::CookieJar.build(@request, cookies.to_hash)
assert_equal jar.signed['remember_token'], ...
Bill
  • 31
  • 2
  • I appreciate your comment, but posting an answer that is "slightly off topic" might warrant making a comment on the question rather than posting an answer. :) – benhorgen Jul 21 '16 at 19:13
  • 1
    I wanted to, but you have to have a rep > 50 to comment on someone else's question or answer. Which I don't as it's my first post :) – Bill Jul 21 '16 at 19:34
  • Good call Bill. Thanks for that insight. – benhorgen Jul 21 '16 at 19:57
0

This will convert all encrypted and signed cookies to the regular ones for test environment. Just make sure you don't have cookies with secure attribute (won't work)

In config/initializers/signed_cookies_patch_test.rb:

if Rails.env.test?
  class ActionDispatch::Cookies::CookieJar
    def encrypted; self; end
    def signed; self; end
  end
end
-2

assert_equal @controller.send(:cookies).signed[:remember_id], matching_value

uberllama
  • 18,752
  • 2
  • 16
  • 8