【问题标题】:Authentication failing during functional tests功能测试期间身份验证失败
【发布时间】:2011-09-29 00:56:47
【问题描述】:

我正在开发一个 Ruby on Rails 应用程序,但我的功能测试存在一些问题。特别是,当我通过具有类似凭据(相同角色等)的用户登录时,我在测试期间不断被拒绝访问可以在浏览器中访问的页面。例如,下面是控制器测试的代码:

include Devise::TestHelpers
include Authorization::TestHelper
...
setup do
  @user = Factory(:user)
  @user.roles << Factory(:refinery_role)
  @user.roles << Factory(:agency_role)
  @user.save
  sign_in @user

  @agency = AgencyOrganization.create :name => "Test Agency"

  @adv1 = AdvertiserOrganization.create :name => "Test Advertiser", :parent => @agency

  UserOrganization.create :user_id => @user.id, :organization_id => @agency.id
end

test "agency user can edit advertiser" do
  assert @user.has_role? :agency #passes
  should_be_allowed_to :update, :advertiser_organizations #passes

  get :edit, {:id => @adv1.id}, {:agency_id => @agency.id}

  assert_equal "/unauthorized", request.env['PATH_INFO'] #passes :'(
  assert_template :edit #fails
  # and more tests we never get to
end

(显然,这些并不是我真正想要检查的所有断言,但它们证明了正在发生的事情。)

不管怎样,上述测试失败并引发以下异常:

4) Failure:
test_agency_user_can_edit_advertiser(AdvertiserOrganizationsControllerTest [/Users/gworley/.rvm/gems/ruby-1.9.2-p180@portal/gems/declarative_authorization-0.5.1/lib/declarative_authorization/maintenance.rb:170]:
Exception raised:
<#<Authorization::NotAuthorized: No matching rules found for update for #<Authorization::GuestUser:0x00000101cda2b0 @role_symbols=[:guest]> (roles [:guest], privileges [:update, :manage], context :advertiser_organizations).>>.

同样,正如我所说,当您实际运行应用程序时,一切正常,它只是让测试工作(虽然也许应用程序只是偶然工作,谁知道呢?)。

【问题讨论】:

  • 如何检查用户是否登录?为什么要发送:agency_id 作为会话变量?
  • 我想我没有检查,因为他们应该在每次测试之前通过安装程序登录,并且它适用于其他测试,而且我有一个带有断言的测试,只有当我执行signout @user 在它之前。至于:agency_id,用户可能有多个机构,但他们一次只能与一个机构互动,所以这似乎是一种传递信息的好方法。仍在学习 Rails,所以也许这不是最好的方法。
  • 可以看看sign_in方法定义吗?
  • sign_in 在 Devise::TestHelpers 中定义

标签: ruby-on-rails ruby-on-rails-3 devise functional-testing declarative-authorization


【解决方案1】:

这是在黑暗中拍摄的,因为我没有在我的应用程序中使用 Devise,但是我们使用的身份验证系统具有这种特性,它只是在会话中设置 :user_id,而会话哈希会破坏它在测试中。

我注意到你的测试方法是在会话中设置:agency_id

尝试完全删除会话哈希,看看您得到的错误是否被替换为缺少:agency_id 而不是身份验证错误,或者将 Devise 用于身份验证的任何会话变量添加到哈希中。

【讨论】:

  • 基于此,我看了一下session,正常使用的时候里面有几个东西,包括'warden.user.user.key' =&gt; ["User", "3"]或者类似的东西。将它放在会话中会使测试以一种新的有趣方式失败,这表明它实际上是在尝试访问所需的控制器方法。还有一些身份验证令牌未在测试中设置并且存在于用户会话中。
  • 经过更多测试,您确实帮我找到了答案:我需要在会话中手动设置'warden.user.user.key' 的值才能使身份验证工作。谢谢一百万!
【解决方案2】:

您在设置中缺少request.env["devise.mapping"] = Devise.mappings[:user]

查看设计wiki 了解更多信息。我个人会将这个登录功能提取到一个单独的模块中,并根据要求包含它。即login_user/login_agency_user

【讨论】:

  • 我试过了,但似乎没有任何区别(即使按照 wiki 的建议调整为使用 @request...)。
  • 您是否仍然遇到同样的错误? /Authorization::GuestUser/
  • 不,现在只是我仍然被重定向到/unauthorized。在我尝试你的建议之前,这实际上是由其他东西修复的,但我忘记更新过去显示失败的部分。
  • 我应该补充一点,我不是唯一的开发人员,所以之前的失败可能已经被其他人解决了,但我仍然无法访问该页面,即使我确实有正确的角色和授权规则。
  • 您是否也在使用 CanCan 或某种授权 gem?你能打印出current_user吗?
【解决方案3】:

别忘了设置 Authorization.current_user 否则 DA 不会知道谁登录了

  def current_user
    @controller.current_user
  end
  def with_sign_in(u)
    sign_in u
    Authorization.current_user = current_user 
    yield
    sign_out u
    Authorization.current_user = nil
  end

【讨论】:

    【解决方案4】:

    authentication(你是谁)还是 authorization(你可以做什么)失败了?如果授权失败,则可能是您使用的 declarative_authorization gem 有问题。如果是身份验证问题,那么很可能是 Devise gem 或 Devise TestHelpers 的问题。这个similar question 可能会有所帮助。如果没有任何效果,那么也应该可以像这样删除身份验证

      before :each do
        @current_user = Factory(:user)
        controller.stub!(:current_user).and_return(@current_user)
        controller.stub!(:user_signed_in?).and_return(:true)
        controller.stub!(:authenticate_user!).and_return(:true)
      end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-01-04
      • 1970-01-01
      • 2018-11-11
      • 2015-08-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多