title: Using Session, Cookies or Current_something in Rspec request tests
body: <p>I am trying to follow the new Rails testing convention with this new project I am working on. Therefore I setup unit tests, request tests and feature tests. The issue is that in the request tests, Capybara and the the session information are not supported. </p>
  
  <p>In addition to having the current_user method setup by Devise, my application has another similar method called current_client. For some of my controllers, I need to check whether the current_user is logged in. This works with Devise authenticate_user! called in a before_action. But for some controllers, I also need to check if a client was selected first (for example if you want to add transactions, they need to be tied with the current client being worked on). </p>
  
  <p>So I added another before_action method that checks if a client was also selected. This works well in feature tests with Capybara where I can mimic user loggin in and the user selecting a client to process. However in the request tests, It doesn`t work. </p>
  
  <p>I first test trying to access the endpoint without a user being logged in and the response is not successful (as it should) and it redirects to the sign in page. But then I need to run my tests with a user logged in AND a client selected. Devise helpers provide a sign_in(user) method. However I can't get my current_user method to work and I can't seem to be able to set it up properly. So those tests are failing and redirecting to another page asking the user to select a client.</p>
  
  <p>I have already tried many suggestions I saw. Like trying to stub the current_client method, trying to provide session info to the GET call. I even tried to check the Devise source code to find out how they can simulate the current_user method in Rspec and couldn't really find where the magic happens.</p>
  
  <p>Here is the code</p>
  
  <p>The current_client method looks like this</p>
  
  <pre><code>def current_client
    current_client ||= Client.find(session[:client_id]) if session[:client_id]
    rescue ActiveRecord::RecordNotFound
    current_client = nil
  end
  </code></pre>
  
  <p>This is how it is set once a user selects a client to process</p>
  
  <pre><code>def set_current_client(client)
    session[:client_id] = client.id
  end
  </code></pre>
  
  <p>This is the code in my test file
  I first create 2  users so that I can test that user 1 cannot access user 2 transactions down the line. (I'm using FactoryBot)
  I then create 2 clients (one for each user)</p>
  
  <pre><code>RSpec.describe "Rooms", :type =&gt; :request do 
    let!(:user) {create(:user)}
    let!(:user2) {create(:user2)}
  
    let!(:client) {create(:client, user: user)}
    let!(:client) {create(:client, user: user2)}
  </code></pre>
  
  <p>The following works</p>
  
  <pre><code>describe 'User Not Signed In' do 
    describe 'GET #index' do
      subject { get transact_path} 
      it "returns an unsuccessful response" do 
        subject
        expect(response).to_not be_successful
    end
  
    it "redirects to sign in page" do 
      subject
      expect(response).to redirect_to (new_user_session_path)
    end
  end
  </code></pre>
  
  <p>The following doesn't. The sign_in(user) method works in the before block and the redirect is not made to the sign in page. However, the response is not successful because the current_client is not set and I have tried to set it in so many ways in the before block without success.</p>
  
  <pre><code>describe 'User Signed In' do 
    before do 
      sign_in(user)
    end
  
  describe 'GET #index' do 
    it "returns a successful response" do 
      get transact_path
        expect(response).to be_successful
      end
    end
  end
  </code></pre>
  
  <p>I understand that the best practices moved away from controller tests because what view rendered or what instance variable assigned doesn't have anything to do with controllers in theory. But in my case, I'm simply trying to test my endpoints and right now I can't because I cannot setup my current_client.</p>