Requirement: Users must have cookies enabled to use the site. If they don't: give them some sort of graceful warning to let them know there's going to be trouble. Doesn't sound too bad… it ended up being much more of an adventure than I had expected.
Step 1. Add the cookie requirement
As you likely know, rails uses a cookie by default to track the session id (cookie id is :_session_id). So, it seems easy enough that I can verify that cookie is there to determine if cookies are enabled.
The catch, of course, is that on the first request: my code will check if the cookie is present… see that it isn't (the browser didn't _already_ have it) and conclude that cookies are disabled! That's not going to work: in all likelihood they are enabled… it's just a matter of me not getting a chance to set the thing yet.
So, I'm going to drop in a little workaround:
First check for the _session_id cookie. If it's there: great, we're good to go. Mission accomplished: proceed to the requested functionality with my blessings.
If not, what do we know? Not much. We know that the cookie hasn't _already_ been added, but we don't know if that's because it's actually been blocked… or have we just not even attempted it yet? What's the easiest way to determine if this is the first time the application has been accessed? Personally, I think it's to not even try to figure it out and just make another call: when that call is fielded you _know_ it's not the first!
So, we add a 'special' parameter and repeat the users request. The subsequent request will be able to check not only for the presence of our cookie but also for the presence of our special parameter – if both turn up negative: we can conclude that cookies are disabled.
Step 2. Add the unit tests
Alright, so all my functional tests are suddenly failing since they are all being blocked by the cookie requirement! I need to add my simple test for the code I just added – while also modifying the existing tests to have proper credentials to access the app. No prob, right? I already have my tests jumping through a little hoop to properly 'login', so now in addition to the "authenticate" stuff I already have: I just add a piece of code to add my cookie:
Run the tests… trouble. The cookie isn't being found. This does make some sense: what does "cookies" really mean to my test class? So, I change things so that instead of saying cookies[:_session_id], I say:
Now this works for the test… but now it isn't working in the actual web app!
Step 3. Making it WorkI suppose I could drop in another piece of code to have my filter check both cookies and @request.cookies but that's no good. I need to use @request.cookies for both test and 'application' code.
The final snags…
a. @request.cookies won't play nice with my symbol ( :_session_id ), so I need to actually use a string for the key ("_session_id").
b. @request.cookies["_session_id"] is returning a Hash and is also returning blank instead of null if not found
So… without further adu:
The test code:
The app code:
As with everyting Rails: the end solution is so simple it's painful.
And they lived happily ever after, The End.