Reputation: 220
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