Я создал начальное приложение из RailsApps с помощью примера приложения rails-devise-pundit. Я пытаюсь написать тест пользовательского контроллера, потому что планирую изменить некоторые функции и хочу убедиться, что все по-прежнему работает. Эксперт UserPolicy не возвращает правильное значение, основанное на перечислении ролей в классе User. UserPolicy.index? показанный ниже метод возвращает false при вызове из первого теста в UsersControllerTest. Извините, здесь много кода и деталей. Я надеюсь, что каждый сможет следовать ему.
Вот неудачный тест в UsersControllersTest. Ответ: :redirect вместо :success.
require "test_helper"
class UsersControllerTest < ActionController::TestCase
def setup
@admin = users(:admin)
@admin.role = :admin
end
test "should get index page when authenticated as an admin" do
sign_in @admin
get :index
assert_response :success
end
...
end
Вот мой класс пользовательского контроллера, просто показывающий метод индекса, в котором моя проблема. authorize @users
должен вызывать метод UserPolicy.index?
.
class UsersController < ApplicationController
before_filter :authenticate_user!
after_action :verify_authorized, except: [:show]
def index
@users = User.all
authorize @users
end
...
end
Мой класс пользовательской политики эксперта. Когда я изменяю метод index?
, чтобы он возвращал true, ответ в моем UsersControllerTest будет: успех. Итак, по какой-то причине @user.admin?
не возвращает правильное значение.
class UserPolicy
attr_reader :user, :record
def initialize(user, record)
@user = user
@record = record
end
def index?
@user.admin?
end
...
end
Что еще более странно, так это то, что я создал класс UserPolicyTest, и когда я тестирую вызов index?
оттуда, я получаю правильный ответ. Этот тест работает правильно:
require 'test_helper'
class UserPolicyTest < ActiveSupport::TestCase
def setup
@admin = users(:admin)
@admin.role = :admin
end
def test_index
policy = UserPolicy.new @admin, nil
assert policy.index?
end
end
Вот моя модель пользователя:
class User < ActiveRecord::Base
devise :database_authenticatable, :registerable, :confirmable,
:recoverable, :rememberable, :trackable, :validatable
enum role: [:user, :vip, :admin]
after_initialize :set_default_role, :if => :new_record?
validates :name, presence: true
def set_default_role
self.role ||= :user
end
end
Вот мой тестовый прибор для администратора:
admin:
email: [email protected]
name: Mr Admin
role: admin
encrypted_password: $2a$10$PoBe1MvkoGJsjMVTEjKqgeBUp.xdfzWoiDjBzQhtLAj16NqIa2fOy
remember_created_at: nil
sign_in_count: 3
current_sign_in_at: 2014-01-02 08:31:23
last_sign_in_at: 2014-01-02 08:31:23
current_sign_in_ip: 127.0.0.1
last_sign_in_ip: 127.0.0.1
confirmation_token: nil
confirmed_at: 2014-01-02 08:31:23
confirmation_sent_at: 2014-01-02 08:30:59
created_at: 2014-01-02 08:30:59
updated_at: 2014-01-02 08:31:23
Я обнаружил, что установка роли в приспособлении не работает. Я предполагаю, что это из-за строки after_initialize :set_default_role, :if => :new_record?
в моей модели пользователя. Если есть другая причина или лучший способ справиться с этим, пожалуйста, дайте мне знать.
ОБНОВЛЕНИЕ: возможно, это вызвано сильными параметрами. Когда я попытался отладить свой код с помощью pry, я обнаружил, что в UsersControllerTest после входа в систему у пользователя-администратора была правильная роль 2. Но когда он попал в User.Policy.index?, роль была 0. Возможно, мне нужно добавить поле роли в параметры разработки. Я видел кое-что о том, как это сделать некоторое время назад. Это не выглядело легко. Если кто-то знает ответ, прежде чем я доберусь до него, пожалуйста, дайте мне знать.