title: Why does a cookie set in a test, not show up in a controller?
body: <p>This started out as a problem I could not get past in the rails tutorial, but at this point I would just like to understand whats going on, if I can I should be able to get past my problem in the tutorial.</p>
  
  <p>My problem boils down to this.  I am trying to set a cookie in a test, and then check it's value in the controller after doing a put, but I don't see the cookie in the controller.</p>
  
  <p>Here is the code in the test:</p>
  
  <pre><code>describe "as wrong user" do
    let(:user) { FactoryGirl.create(:user) }
    let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
    before do
        puts "setting up test - set remeber_token"
        cookies['remember_token'] = user.remember_token
        puts "cookies['remember_token'] = #{cookies['remember_token']}"
    end
    describe "submitting a PUT request to the Users#update action" do
      before do 
        puts "in test " 
        puts "cookies['remember_token'] = #{cookies['remember_token']}"
        put user_path(wrong_user) 
      end
      specify { response.should redirect_to(root_url) }
    end
  end
  </code></pre>
  
  <p>and here is the code in the controller (I think this is all that is relevant) </p>
  
  <pre><code>before_filter :signed_in_user, only: [:edit, :update]
  before_filter :correct_user,   only: [:edit, :update]
  
      def signed_in_user
        puts "in signed_in_user filter"
        puts "cookies['remember_token'] = #{cookies['remember_token']}"
        redirect_to signin_url, notice: "Please sign in." unless signed_in?
      end
  
      def correct_user
        @user = User.find(params[:id])
        redirect_to(root_url) unless current_user?(@user)
      end
  </code></pre>
  
  <p>When I run the tests the output seems to indicate that the cookie is set in the test but is gone in the before filter.  The test ultimately fails because because the <code>signed_in?</code> method is supposed to see if a user exists with the remember_token retrieved from the cookies object, which is nil.  Can someone explain what is going on here?</p>
  
  <p>Here is the console output:</p>
  
  <pre><code>&gt;bundle exec rspec spec/requests/authentication_pages_spec.rb -e "submitting a PUT request to the Users#update action"
  Run options: include {:full_description=&gt;/submitting\ a\ PUT\ request\ to\ the\ Users\#update\ action/}
  setting up test - set remeber_token
  cookies['remember_token'] = qpcZCCuhaoBirjWR9s5YMw
  in test
  cookies['remember_token'] = qpcZCCuhaoBirjWR9s5YMw
  in signed_in_user filter
  cookies['remember_token'] =
  F
  
  Failures:
  
    1) Authentication authorization as wrong user submitting a PUT request to the Users#update action
       Failure/Error: specify { response.should redirect_to(root_url) }
         Expected response to be a redirect to &lt;"http://www.example.com/"&gt; but was a redirect to &lt;"http://www.example.com/signin"&gt;
       # ./spec/requests/authentication_pages_spec.rb:84:in `block (5 levels) in &lt;top (required)&gt;'
  
  Finished in 0.34502 seconds
  1 example, 1 failure
  
  Failed examples:
  
  rspec ./spec/requests/authentication_pages_spec.rb:84 # Authentication authorization as wrong user submitting a PUT request to the Users#update action
  </code></pre>
  
  <p><strong>UPDATE:
  I tried using request.cookies['remember_token'] to set the cookie in the test and retrieve in the before filter,  and I am having the same issue.</strong></p>
  
  <p>so basically I have this:</p>
  
  <pre><code>describe "as wrong user" do
    describe "in the Users controller" do
      let(:user) { FactoryGirl.create(:user) }
      let(:wrong_user) { FactoryGirl.create(:user, email: "wrong@example.com") }
      before do 
        puts "setting up test - set remeber_token"
        get root_url
        request.cookies['remember_token'] = user.remember_token
        puts "cookies['remember_token'] = #{request.cookies['remember_token']}" 
      end  
  
      describe "visiting Users#edit page" do
        before { visit edit_user_path(wrong_user) }
        it { should_not have_selector('title', text: full_title('Edit user')) }
      end
  
      describe "submitting a PUT request to the Users#update action" do
        before do 
          puts "in test " 
          puts "cookies['remember_token'] = #{request.cookies['remember_token']}"
          put user_path(wrong_user) 
        end
        specify { response.should redirect_to(root_url) }
      end
    end
  </code></pre>
  
  <p>and in the before_filter :</p>
  
  <pre><code>  def signed_in_user
        puts "in signed_in_user filter"
        puts "cookies[:remember_token] = #{request.cookies[:remember_token]}"
        puts "request = #{request.cookies}"
        p request
        redirect_to signin_url, notice: "Please sign in." unless signed_in?
      end
  </code></pre>
  
  <p>and the  puts "request = #{request.cookies}"
  returns => <code>request = {}</code></p>
  
  <p><strong>Update:</strong></p>
  
  <p>I now understand what is going on here.  I have too look back through the tutorial to see if I missed something, or find the correct way around this.
  Here is what is happening.</p>
  
  <p>In the ApplicationController I have this (copied directly from the tutorial)</p>
  
  <pre><code>class ApplicationController &lt; ActionController::Base
    protect_from_forgery
    include SessionsHelper
  
    # Force signout to prevent CSRF attacks
    def handle_unverified_request
      sign_out
      super
    end   
  end
  </code></pre>
  
  <p>The sessions helper has this sign_out method:</p>
  
  <pre><code>  def sign_out
      puts "in sign out"
      cookies.delete :remember_token
      self.current_user = nil
    end
  </code></pre>
  
  <p>So what happens is that when I do the put in the test, the user gets signed out and as a result is redirected to the sign in page rather than the root_url.
  I have to look through the tutorial to see what I might have missed, or maybe it's an oversight? </p>
  
  <p><strong>SOLVED!</strong></p>
  
  <p>It turns out this was a very simple set up issue in my environment.
  I had set the environment variable RAILS_ENV="development".
  Removing that allows the first line in the spec_helper.rb to correctly set the RAILS_ENV to 'test' which turns protect_from_forgery off in the test env, which prevents the sign_out when I do the put, and allows the test to pass.</p>
  
  <p>I doubt many others will have this same issue, but if you are going through the rails tutorial and are failing the following test, make sure your tests are being run in the test environment.</p>
  
  <p>Failures:</p>
  
  <pre><code>  1) Authentication authorization as wrong user submitting a PUT request to the Users#update action
       Failure/Error: specify { response.should redirect_to(root_url) }
         Expected response to be a redirect to &lt;"http://www.example.com/"&gt; but was a redirect to &lt;"http://www.example.com/signin"&gt;
       # ./spec/requests/authentication_pages_spec.rb:84:in `block (5 levels) in &lt;top (required)&gt;'
  </code></pre>