Rails 5.2 I have the following ApplicationCable::Connection ruby file:
module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user
    def connect
      self.current_user = find_verified_user
    end
    private
    def find_verified_user
      if verified_user = env['warden'].user
        verified_user
      else
        message = "The user is not found. Connection rejected."
        logger.add_tags 'ActionCable', message  
        self.transmit error: message 
        reject_unauthorized_connection
      end
    end
  end
end
I want to test this setup and and using the following RSpec test:
require 'rails_helper.rb'
RSpec.describe ApplicationCable::Connection, type: :channel do
  it "successfully connects" do
    connect "/cable", headers: { "X-USER-ID" => 325 }
    expect(connection.user_id).to eq 325
  end
end
Which fails with:
Failure/Error: if verified_user = env['warden'].user
NoMethodError: undefined method `[]' for nil:NilClass
So I want to stub out the env['warden'].user code and return an id of 325. I tried the following:
allow(env['warden']).to receive(:user).and_return(325)
But that produced the following error:
undefined local variable or methodenv' 
How can I test this class?
Try this:
require 'rails_helper.rb'
RSpec.describe ApplicationCable::Connection, type: :channel do
  let(:user)    { instance_double(User, id: 325) }
  let(:env)     { instance_double('env') }
  context 'with a verified user' do
    let(:warden)  { instance_double('warden', user: user) } 
    before do
      allow_any_instance_of(ApplicationCable::Connection).to receive(:env).and_return(env)
      allow(env).to receive(:[]).with('warden').and_return(warden)
    end
    it "successfully connects" do
      connect "/cable", headers: { "X-USER-ID" => 325 }
      expect(connect.current_user.id).to eq 325
    end
  end
  context 'without a verified user' do
    let(:warden)  { instance_double('warden', user: nil) }
    before do
      allow_any_instance_of(ApplicationCable::Connection).to receive(:env).and_return(env)
      allow(env).to receive(:[]).with('warden').and_return(warden)
    end
    it "rejects connection" do
      expect { connect "/cable" }.to have_rejected_connection
    end
  end
end
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With