Текущий_пользователь Ruby on Rails Pundit равен нулю в интеграционном тесте

Я использую драгоценные камни pundit и devise. У меня есть ссылка для удаления, которая отображается только в том случае, если вы являетесь администратором. У меня есть интеграционный тест, в котором я хотел бы убедиться, что ссылка на удаление отображается только для администраторов.

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, в качестве типов тестов по умолчанию, которые будут генерироваться для наших контроллеров. Если это так, то devise был бы намного полезнее из коробки при использовании Rails 5, если бы хелперы sign_in/sign_out, работающие в тестах контроллера, также работали и в интеграционных тестах. Но будет ли у меня все еще эта проблема с pundit, не знающим, что такое current_user? Я предполагаю, что все это отлично работает в тестах контроллеров, потому что current_user привязан к контроллерам? Я очень ценю любой свет, пролитый на эту тему, но я действительно хотел бы выяснить, как заставить интеграционные тесты работать с этой настройкой, потому что у меня есть около миллиарда, которые я хочу написать прямо сейчас.


person Jake Smith    schedule 15.03.2016    source источник


Ответы (1)


Не то, чтобы это имело большое значение, но нужно ли использовать current_user в политике или можно просто использовать пользователя в политике. Под этим я подразумеваю, согласно README elabs/pundit на Github, я бы просто везде использовал @user и user вместо current_user. Прочтите README, если я вас запутал.

Кроме того, nil вместо current_user обычно возникает, когда у вас нет действительного токена CSRF для вашего запроса. Когда вы делаете это на веб-сайте вручную, перейдя на localhost:3000 или w/e, вы сначала выполняете get на пути входа в систему, прежде чем делать публикацию на пути входа со своими учетными данными. В вашем интеграционном тесте я, кажется, не вижу, где вы выполняете это get, чтобы получить CSRF для своего сеанса.

Надеюсь это поможет!!!

person Billy Ferguson    schedule 19.04.2017
comment
большое спасибо, CSRF для меня является корневой проблемой, теперь я, по крайней мере, знаю, что исправить :) Хотя моя проблема не была связана с тестами, просто ошибка, которая время от времени возникает при действиях, которые обычно работают хорошо. - person Avael Kross; 13.02.2018