Сбой теста: sign_in(Fabricate(:user))

У меня есть тест, который начал падать несколько дней назад. Похоже, дело в чем-то, связанном с timezone? Я не вижу, чтобы это была вина моего плагина, но, возможно, я что-то упускаю?

require 'rails_helper'

describe TopicDefaultTag::ActionsController do
  before do
    Jobs.run_immediately!
  end

  it 'can list' do
    sign_in(Fabricate(:user))
    get "/topic-default-tag/list.json"
    expect(response.status).to eq(200)
  end
end
Запуск Rspec: plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb
Загрузка плагинов при запуске тестов

Произошла ошибка при загрузке ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb.
Failure/Error: UserOption.create!(user_id: id)

NoMethodError:
  undefined method `timezone' for #<UserOption:0x000055dd7af16ca8>
  Did you mean?  timeout
# ./app/models/user.rb:1343:in `create_user_option'
# (eval):19:in `block (2 levels) in run_file'
# ./spec/rails_helper.rb:79:in `<top (required)>'
# ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb:1:in `require'
# ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb:1:in `<top (required)>'
No examples found.


Finished in 0.00005 seconds (files took 3.52 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples

Похоже, у вас отсутствует столбец timezone в таблице user_options. Вы недавно выполняли миграции в тестовой базе данных? RAILS_ENV=test bin/rake db:migrate

Почему, нет! Нет, я не запускал. Я выполнил миграции в базе данных dev, но не в test. Спасибо, Дэвид!

Я пока не понимаю, что происходит, но эта проблема, скорее всего, не такая уж и для новичков. :wink:

Вы должны получать сообщение, если миграции отсутствуют

Однако это сработает только если вы используете rails_helper. Я предполагаю, что вам нужно добавить require "rails_helper" в начало вашего spec-файла. Это также может решить другие проблемы, с которыми вы столкнулись.

Редактирование: хм… возможно, стоит добавить --require rails_helper в файл .rspec, чтобы не пришлось добавлять его вручную :thinking:

Звучит как та самая глупая ошибка, которую мог бы совершить я! Увы, у меня есть require 'rails_helper'.

Возможно, проблема была в том, что я запускал ./bin/rake autospec вместо bundle exec rake autospec, но на Travis оно всё равно падает. Теперь этот тест, похоже, делает кучу всего, чего я не понимаю для своего одного маленького теста, но я просто подожду и посмотрю, что будет.

Спасибо ещё раз.

У меня возникла проблема с функцией-помощником sign_in, любая помощь будет очень полезна! :exploding_head: :

При использовании в этом тесте, похоже, она не устанавливает current_user, и тест завершается с ошибкой 403 (вместо 200).

Я запускаю тест следующим образом, чтобы изолировать проблему, но это тоже не помогает:

LOAD_PLUGINS=1 RAILS_ENV=test rspec plugins/discourse-follow/spec/requests/follow_controller_spec.rb:32

Если я добавлю byebug в соответствующий контроллер и проверю current_user, он окажется nil (отсюда, думаю, и ошибка 403!):

Randomized with seed 50945

[5, 14] in /home/merefield/code/discourse-follow/app/controllers/follow/follow_controller.rb
    5:   def update
    6:     params.require(:username)
    7:     params.require(:follow)
    8:     byebug
    9:
=> 10:     raise Discourse::InvalidAccess.new unless current_user
   11:     raise Discourse::InvalidParameters.new if current_user.username == params[:username]
   12:
   13:     if user = User.find_by(username: params[:username])
   14:       updater = Follow::Updater.new(current_user, user)
(byebug) current_user
nil

У вас есть выше, который создаёт этого пользователя? (Я недостаточно хорошо помню, как это называется и как именно это делается. О, может, фабрикатор? Вы сфабриковали этого пользователя?

(или, возможно, я не заметил, так как я с телефона))

Да, пользователь создан. Объект пользователя инициализирован. Проблема в методе sign_in или, возможно, связана с окружением? (Но это должно контролироваться)

При дальнейшем расследовании я обнаружил следующее:

в def current_user (discourse/lib/auth/default_current_user_provider.rb at 1472e47aae5bfdfb6fd9abfe89beb186c751f514 · discourse/discourse · GitHub)

@env.key?(CURRENT_USER_KEY) возвращает true

следовательно, current_user принимает значение @env[CURRENT_USER_KEY]

Однако его значение равно nil, когда эта строка вызывается из моего контроллера во время выполнения теста:

  def update
    params.require(:username)
    params.require(:follow)

    raise Discourse::InvalidAccess.new unless current_user

Непонятно, почему @env[CURRENT_USER_KEY] может быть nil после входа пользователя в рамках спецификации?

Я заметил, что во время выполнения теста current_user вызывается несколько раз в рамках одного теста, и в какой-то момент этот атрибут имеет значение, но не при каждом вызове и не в тот момент, когда это действительно важно.

У вас установлены какие-либо другие плагины, которые могут конфликтовать с объектом current_user? Я клонировал discourse-follow, и этот тест у меня проходит:

❯ LOAD_PLUGINS=1 bin/rspec plugins/discourse-follow/spec/requests/follow_controller_spec.rb   

Randomized with seed 28704
...

Finished in 0.45075 seconds (files took 3.34 seconds to load)
3 examples, 0 failures

Randomized with seed 28704

Ах, спасибо за проверку, Дэвид! Значит, дело должно быть в чём-то специфичном в моей среде разработки!

Нет, других плагинов не установлено (кроме встроенных и Data Explorer), но раз у вас это работает, я решил настроить чистый новый экземпляр Docker для разработки и посмотреть, получится ли у меня запустить его там. Ура! :beers:

Да, поработал над разработкой Docker:

d/rake plugin:spec["discourse-follow"]

Спасибо!!