【问题标题】:Ruby on Rails Pundit's current_user is nil in integration testRuby on Rails Pundit 的 current_user 在集成测试中为零
【发布时间】:2016-03-15 01:39:15
【问题描述】:

我正在使用宝石 punditdevise。我有一个删除链接,只有在您是管理员时才会显示。我有一个集成测试,我想验证删除链接是否只对管理员显示。

test 'comment delete link shows when it should' do
  log_in_as @admin
  get movie_path(@movie)
  assert_select 'a[href=?]', movie_comment_path(comments(:one), @movie.id)
end

我的test_helper.rb 看起来像这样:

...
class ActiveSupport::TestCase
  ...
  def log_in_as(user, options = {})
    password = options[:password] || 'password'
    if integration_test?
      post user_session_path, 'user[email]' => user.email, 'user[password]' => user.password
    else
      Devise::TestHelpers.sign_in user
    end
  end

  private

    # Returns true inside an integration test.
    def integration_test?
      defined?(post_via_redirect)
    end

end

response.body 看起来没问题,但确实没有删除链接。当我运行开发服务器并自己访问页面时,有一个。我已将其缩小为专家在策略中使用的current_user,其值为nil。这是我的comment_policy.rb

class CommentPolicy
  attr_reader :current_user, :comment

  def initialize(current_user, model)
    @current_user = current_user
    @comment      = model
  end

  def create?
    if @current_user
      @current_user.member? or @current_user.content_creator? or @current_user.moderator? or @current_user.admin?
    end
  end

  def destroy?
    if @current_user
      @current_user == @comment.user or @current_user.moderator? or @current_user.admin?
    end
  end

end

作为结束语,我听说 Rails 5 选择了集成测试而不是控制器测试,因为我们从 Rails 4 中知道它们是为我们的控制器生成的默认测试类型。如果是这种情况,如果在控制器测试中工作的 sign_in/sign_out 帮助器也可以在集成测试中工作,那么在使用 Rails 5 时,devise 将非常有用.但是我还会遇到pundit 不知道current_user 是什么的问题吗?我假设这一切在控制器测试中都可以正常工作,因为current_user 仅限于控制器?非常感谢有关此主题的任何和所有亮点,但我真的很想弄清楚如何让集成测试与此设置一起工作,因为我现在想要编写大约十亿。

【问题讨论】:

    标签: ruby-on-rails-4 devise integration-testing pundit


    【解决方案1】:

    这并不完全重要,但它是否需要在策略中使用 current_user 或者它可以只在策略中使用 user。我的意思是根据 Github 上的 elabs/pundit README,我只会在任何地方使用 @useruser 而不是 current_user。如果我让您感到困惑,请阅读自述文件。

    此外,current_usernil 通常在您的请求没有有效的 CSRF 令牌时出现。当您通过转到localhost:3000 或w/e 在网站上手动执行此操作时,您首先在登录路径上执行get,然后使用您的凭据在登录路径上进行发布。在您的集成测试中,我似乎看不到您在哪里执行 get 以获得会话的 CSRF。

    希望对你有帮助!!!

    【讨论】:

    • 非常感谢,CSRF 对我来说是一个根本问题,现在我至少知道要解决什么了 :) 虽然我的问题与测试无关,只是不时发生的错误在通常效果良好的操作上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多