You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

切换浅嵌套后RSpec中Assets路由的login_as失效问题排查

问题:浅嵌套路由下login_as的Warden回调未执行

问题背景

我正在将隶属于Entity的Assets切换为浅嵌套路由,并重新编写请求测试。新的浅嵌套路由(如/assets/1,原路由为/entities/1/assets/1)中login_as功能失效,但嵌套形式的路由(如#index或#new动作)可正常工作:

  • 浏览器手动测试所有路由均正常
  • 另一组隶属于Entity的Vendors切换为浅嵌套路由后未出现问题

问题定位

我将问题追踪到login_as方法内的Warden.on_next_request回调:在失败的测试中,回调已设置,但未被后续请求触发。以下是添加了诊断信息的Warden helper.rb代码:

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

测试代码及输出

测试代码

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
    # 也尝试过: sign_in
    #           在每个it块中调用login_as
    #           指定:user scope
  end

  describe 'GET #show' do
    it '存在登录问题(浅嵌套)' do
      get asset_url(asset)
      # 也尝试过:  get "http://localhost:3000/assets/1"
      #           get '/assets/1'
      expect(response).to be_successful
    end
  end

  describe 'GET #index' do
    it '符合预期(仍为嵌套)' do
      get entity_assets_url(entity)
      expect(response).to be_successful
    end
  end
end

测试输出

/assets
  GET #show
    #### login_as: queing on_next_request
    存在登录问题(浅嵌套)(失败 - 1)
  GET #index
    #### login_as: queing on_next_request
    ####      ... executing callback
    符合预期(仍为嵌套)

环境信息

  • 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'

  # 被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

提问

为何回调在失败的测试中未执行?

内容的提问来源于stack exchange,提问作者BEEK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 17:03:11