Fallando prueba: sign_in(Fabricate(:user))

Tengo una especificación que comenzó a fallar hace unos días. Parece que se debe a algo relacionado con el timezone? No veo cómo pueda ser culpa de mi plugin, pero ¿quizás me estoy perdiendo 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
Ejecutando Rspec: plugins/discourse-topic-default-tag/spec/requests/actions_controller_spec.rb
Cargando plugins mientras se ejecutan las especificaciones

Ocurrió un error al cargar ./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 se encontraron ejemplos.


Finalizado en 0.00005 segundos (los archivos tardaron 3.52 segundos en cargarse)
0 ejemplos, 0 fallos, 1 error ocurrido fuera de los ejemplos
1 me gusta

Parece que te falta la columna de zona horaria en tu tabla user_options. ¿Has ejecutado las migraciones recientemente en tu base de datos de pruebas? RAILS_ENV=test bin/rake db:migrate

2 Me gusta

¡No, no! No, no lo he hecho. Ejecuté las migraciones en la base de datos de desarrollo, pero no en la de pruebas. ¡Gracias, David!

No entiendo qué está pasando ahora, pero es probable que este problema no sea tan sencillo. :wink:

2 Me gusta

Deberías recibir un mensaje cuando falten migraciones

Pero esto solo funcionará si estás usando el rails_helper. Sospecho que necesitas agregar require "rails_helper" al principio de tu archivo spec. Eso también podría resolver los otros problemas que estás viendo.

Edición: hmmm… quizás deberíamos agregar --require rails_helper al archivo .rspec para que no sea necesario añadirlo manualmente :thinking:

2 Me gusta

¡Eso suena como el tipo de error tonto que yo cometería! Por desgracia, sí tengo require 'rails_helper'.

Quizás ejecutar ./bin/rake autospec en lugar de bundle exec rake autospec fue mi problema, pero sigue fallando en Travis. Ahora, esta especificación parece estar haciendo un montón de cosas que no entiendo para mi pequeña prueba, pero esperaré a ver qué pasa.

Gracias de nuevo.

2 Me gusta

Tengo un problema con la función auxiliar sign_in, ¡cualquier ayuda será muy apreciada! :exploding_head: :

Cuando se usa en esta prueba, no parece proporcionar un current_user y falla con un 403 (en lugar de un 200).

Estoy ejecutando la prueba de la siguiente manera para aislarla, pero tampoco funciona así:

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

Si agrego un byebug en el controlador correspondiente y verifico current_user, es nil (¡de ahí el 403, supongo!):

Randomized with seed 50945

[5, 14] en /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

¿Tienes un arriba que cree ese usuario? (No soy lo suficientemente bueno para recordar cómo se llama o cómo hacerlo exactamente. Oh, ¿un fabricador? ¿Fabricaste ese usuario?

(O tal vez no lo vi, ya que estoy usando el teléfono).

1 me gusta

Sí, el usuario está creado. El objeto de usuario se ha instanciado. El problema está dentro del método sign_in o tiene algo que ver con el entorno? (Pero eso debería estar controlado)

1 me gusta

Tras una investigación más profunda, he encontrado lo siguiente:

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

@env.key?(CURRENT_USER_KEY) es true

por lo que current_user toma el valor de @env[CURRENT_USER_KEY]

Sin embargo, su valor es nil cuando esta línea se llama desde mi controlador durante una ejecución de prueba:

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

    raise Discourse::InvalidAccess.new unless current_user

No estoy seguro de por qué @env[CURRENT_USER_KEY] sería nil después de iniciar sesión en un usuario dentro de la especificación.

Noto que durante la ejecución de la prueba current_user se llama varias veces durante una sola prueba, y en un momento dado este atributo tiene un valor, pero no en cada llamada, y no cuando importa.

¿Tienes instalados otros plugins que podrían estar interfiriendo con el objeto current_user? Cloné discourse-follow y esa prueba funciona para mí:

❯ 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
2 Me gusta

¡Ah, gracias por verificarlo, David! Entonces debe ser algo peculiar de mi configuración de desarrollo.

No, no hay otros plugins instalados (además de los incluidos y el explorador de datos), pero dado que funciona para ti, me he inspirado a configurar una nueva instancia limpia de Docker para desarrollo y ver si puedo ejecutarla correctamente allí. ¡Salud! :beers:

1 me gusta

Sí, funcionó en el desarrollo de Docker:

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

¡Gracias!

3 Me gusta

Este tema se cerró automáticamente después de 20 horas. Ya no se permiten nuevas respuestas.