BEEK
BEEK

Reputation: 220

RSpec: login_as not working after switching to shallow nesting

I'm switching to shallow nesting of Assets (belonging to Entity), and I'm rewriting request specs. For the new shallow routes (e.g. '/assets/1', which was '/entities/1/assets/1'), login_as fails. It works for the still-nested routes, such as the #index or #new actions. Manual testing with a browser works for all routes. I have shallow-ized another set of routes (Vendors, also belonging to Entity), without issue.

I can trace the issue to the Warden.on_next_request callback inside the login_as method. During the failing tests, this callback is set, but never triggered by the next request. Here the code from Warden's helper.rb, with some diagnostics of mine:

      def login_as(user, opts = {})
        puts "    #### login_as: queing on_next_request"
        Warden.on_next_request do |proxy|
          puts "    ####      ... executing callback"
          opts[:event] ||= :authentication
          proxy.set_user(user, opts)
        end
      end

My tests and output:

require 'rails_helper'

RSpec.configure do |c|
  c.include SystemHelpers
end

RSpec.describe '/assets', type: :request do
  let(:user) { create(:user, :with_unlimited_subscription) }
  let(:entity) { create_entity_role(user, roles: %i[manager administrator]) }
  let(:asset) { create(:asset) }

  before do
    login_as user
    # also tried: sign_in
    #             login_as in each it block
    #             :user scope
  end

  describe 'GET #show' do
    it 'has the login problem (shallow)' do
      get asset_url(asset)
      # also tried:  get "http://localhost:3000/assets/1"
      #              get '/assets/1'
      expect(response).to be_successful
    end
  end

  describe 'GET #index' do
    it 'works as expected (still nested)' do
      get entity_assets_url(entity)
      expect(response).to be_successful
    end
  end
end
/assets
  GET #show
    #### login_as: queing on_next_request
    has the login problem (shallow) (FAILED - 1)
  GET #index
    #### login_as: queing on_next_request
    ####      ... executing callback
    works as expected (still nested)

The callback doesn't get executed in the failing test. Why?

Reference:
Rails 8.0.0
rspec-core (3.13.2)
rspec-expectations (3.13.3)
rspec-mocks (3.13.2)
rspec-rails (7.1.0)
rspec-support (3.13.1)
warden (1.2.9)

routes.rb:

Rails.application.routes.draw do

  devise_for :users
  devise_scope :user do
    get 'sign_in', to: 'devise/sessions#new'
    get 'login',   to: 'devise/sessions#new'
    get 'sign_up', to: 'devise/registrations#new'
    get '/users/sign_out' => 'devise/sessions#destroy'
  end

  root 'fixed_pages#index'

  # used by devise, after_sign_in_path_for()
  get '/user', to: 'entities#index', as: :user_root

  resources :entities, shallow: true do
    resources :vendors
    resources :assets
  end
end

Upvotes: 0

Views: 39

Answers (0)

Related Questions