Разработать sign_in не работает в спецификации контроллера - PullRequest
0 голосов
/ 31 мая 2018

Похоже, что помощник sign_in от devise не работает.

Обычная процедура входа работает как прелесть, проверенная с помощью интеграционного теста и заполнения формы входа вручную.Оба метода дали правильное значение для current_user.

Я хотел проверить функции контроллера редактирования профиля пользователя и столкнулся с проблемой «не авторизован».Это привело меня к текущим спецификациям, где я просто хотел подтвердить, что на самом деле пользователь не вошел в систему, и поэтому current_user равен nil.

Полагаю, в моем коде просто что-то не так.

У вас есть какие-нибудь советы по решению моей проблемы?

Я использую Rails 5.2 и ruby ​​2.5.0

models / user.rb

class User < ApplicationRecord
  enum role: [:registered, :editor, :admin]
  after_initialize :set_default_role, if: :new_record?

  def set_default_role
    self.role ||= :registered
  end

  # Include default devise modules. Others available are:
  devise :invitable, :database_authenticatable, :registerable,
         :recoverable, :rememberable, :trackable, :validatable

контроллеры / application_controller.rb

class ApplicationController < ActionController::Base

  before_action :authenticate_user!
  before_action :configure_permitted_parameters, if: :devise_controller?

  protected

  def configure_permitted_parameters
    devise_parameter_sanitizer.permit(:sign_up, keys: [:first_name,  :last_name, :approved])
  end
end

контроллеры / registration_controller.rb

class RegistrationsController < Devise::RegistrationsController

  private

  def after_inactive_sign_up_path_for(resource)
    show_post_register_info_path
  end   
end

config / route.rb

Rails.application.routes.draw do

  devise_for :users, controllers: { registrations: 'registrations'}

  root to: 'welcome#home
  get 'show_post_register_info', to: 'static_pages#show_post_register_info'
end

specs / rails_heper.rb

require 'rspec/rails'
require 'devise'

Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }

RSpec.configure do |config|
  config.include Devise::Test::ControllerHelpers, type: :controller
  config.include Devise::Test::ControllerHelpers, type: :view
  config.include Devise::Test::IntegrationHelpers
  config.extend ControllerMacros, type: :controller
  ...
end

support / controller_macros.rb

module ControllerMacros
  def login_user
    before(:each) do
        @request.env["devise.mapping"] = Devise.mappings[:user]
        user = FactoryBot.create(:user)
        sign_in user
    end
  end
end

и, наконец, мой controller_spec:

require 'rails_helper'

RSpec.describe RegistrationsController, type: :controller do

describe 'registrations#update'  do

    context 'signing in a registered user' do
      login_user

      it 'should have a current_user' do
        expect(subject.current_user).to_not eq(nil)
      end

      it 'should be signed in' do
        expect(subject.user_signed_in?).to be true
      end
    end
  end
end

Результат:

1) RegistrationsController registrations#update as a registered user changes the password
 Failure/Error: expect(subject.user_signed_in?).to be true

   expected true
        got false

2) RegistrationsController registrations#update as a registered user should have a current_user
 Failure/Error: expect(subject.current_user).to_not eq(nil)

   expected: value != nil
        got: nil

Ответы [ 2 ]

0 голосов
/ 01 июня 2018

В Specs / support / controller_macros.rb я немного отредактировал процедуру входа в систему:

def login_user
  before  do
    @request.env["devise.mapping"] = Devise.mappings[:user]
    user = FactoryBot.create(:user)
    subject.sign_in user # was sign_in user
  end
end

Я действительно не знаю, почему мне нужно вызывать метод sign_in из объекта контроллера (controller.sign_inтоже работает), но меня это устраивает.

Может быть, соменон хочет объяснить, почему это должно быть subject.sign_in user.

0 голосов
/ 01 июня 2018

Единственное, что выскакивает, основываясь на том, что вы поделились, это то, что когда я использовал помощника sign_in из Devise в спецификациях контроллера, я заключил его в блок before (или фигурные скобки),похоже на то, что ниже, и похоже на то, что есть в вашем модуле login_in.Может быть, попытаться избавиться от (:each).Кроме того, вы можете вставить pry или byebug в свой метод login_user, чтобы увидеть, срабатывает ли метод при запуске спецификаций контроллера.

let!(:user) { create(:user) }

context 'user is logged in' do
  before { sign_in user }

  it 'allows some thing' do
    # some expectation....
  end
end
...