Falha no teste: sign_in(Fabricate(:user))

Tenho um teste que começou a falhar há alguns dias. Parece ser algo relacionado ao timezone? Não vejo como isso seja culpa do meu plugin, mas talvez eu esteja perdendo algo?

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
Executando Rspec: plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb
Carregando plugins enquanto executa os testes

Ocorreu um erro ao carregar ./plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb.
Failure/Error: UserOption.create!(user_id: id)

NoMethodError:
  método `timezone' não definido para #<UserOption:0x000055dd7af16ca8>
  Significava?  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)>'
Nenhum exemplo encontrado.


Finalizado em 0,00005 segundos (os arquivos levaram 3,52 segundos para carregar)
0 exemplos, 0 falhas, 1 erro ocorreu fora dos exemplos

Parece que você está com a coluna de fuso horário faltando na sua tabela user_options. Você executou as migrações recentemente no seu banco de dados de teste? RAILS_ENV=test bin/rake db:migrate

Por que, não! Não, eu não executei. Eu rodas as migrações no banco de dados de desenvolvimento, mas não no de teste. Obrigado, David!

Não entendo o que está acontecendo agora, mas provavelmente não é um problema tão iniciante assim. :wink:

Você deve receber uma mensagem quando houver migrações pendentes

Mas isso só funcionará se você estiver usando o rails_helper. Suspeito que você precise adicionar require "rails_helper" no topo do seu arquivo spec. Isso pode resolver também os outros problemas que você está enfrentando.

Edição: hmm… talvez devêssemos adicionar --require rails_helper ao arquivo .rspec, para que não seja necessário adicioná-lo manualmente :thinking:

Isso parece o tipo de erro bobo que eu faria! Infelizmente, eu realmente tenho require 'rails_helper'.

Talvez executar ./bin/rake autospec em vez de bundle exec rake autospec tenha sido o problema, mas ainda está falhando no Travis. Agora, esse spec parece estar fazendo um monte de coisas que eu não entendo para o meu único spec pequeno, mas vou apenas esperar e ver o que acontece.

Obrigado novamente.

Estou tendo um problema com a função de ajuda sign_in, qualquer ajuda será muito apreciada! :exploding_head: :

Quando usada neste teste, ela não parece entregar um current_user e falha com um 403 (em vez de um 200).

Estou executando o teste assim para isolá-lo, mas não funciona de qualquer maneira:

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

Se eu adicionar um byebug no controlador correspondente e verificar o current_user, ele é nil (daí o 403, imagino!):

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:
=\u003e 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

Você tem um acima que cria esse usuário? (Não sou bom o suficiente para lembrar como se chama ou exatamente como fazer. Ah, um fabricador, talvez. Você fabricou esse usuário?

(ou talvez eu não tenha visto, pois estou no celular))

Sim, o usuário foi criado com sucesso. O objeto do usuário foi instanciado. O problema está dentro do método sign_in ou tem algo a ver com o ambiente? (Mas isso deveria estar controlado)

Após uma investigação mais aprofundada, encontrei o seguinte:

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

@env.key?(CURRENT_USER_KEY) é true

portanto, current_user assume o valor de @env[CURRENT_USER_KEY]

No entanto, seu valor é nil quando essa linha é chamada do meu controlador durante uma execução de teste:

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

    raise Discourse::InvalidAccess.new unless current_user

Não tenho certeza do motivo pelo qual @env[CURRENT_USER_KEY] seria nil após o login de um usuário dentro da especificação.

Notei que, durante a execução do teste, current_user é chamado várias vezes durante apenas um teste e, em um determinado momento, esse atributo possui um valor, mas não em todas as chamadas e não quando importa.

Você tem algum outro plugin instalado que possa estar interferindo no objeto current_user? Clonei o discourse-follow e esse teste funciona para mim:

❯ 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

Ah, obrigado por verificar, David! Então deve ser algo peculiar na minha configuração de desenvolvimento!

Não, não há outros plugins instalados (além dos embutidos e do data explorer), mas, já que funciona para você, estou inspirado a configurar uma nova instância limpa de dev no Docker e ver se consigo executá-la com sucesso por lá. Valeu! :beers:

Sim, funcionou no dev do Docker:

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

obrigado!!