Mantenerse seco mientras se prueba un controlador, autorizado a través de CanCan
-
27-09-2019 - |
Pregunta
Estoy escribiendo algunas pruebas con carácter retroactivo, utilizando RSpec, para un proyecto de rieles.
Estoy usando la gema CanCan para proporcionar autorización. Decidí escribir una especificación que pondrá a prueba el modelo ability.rb
.
Entonces fui a probar mis modelos restantes.
He seguido adelante a los controladores, y me he encontrado con un gran inconveniente: Estoy probando mis habilidades de nuevo
Básicamente, tengo que apagar una serie de modelos, y el talón de sus asociaciones; de lo contrario la respuesta sólo devuelve 403 Forbidden
.
La razón de esto, es que el controlador se encarga básicamente de preocuparse acerca de la autorización.
No estoy muy seguro de dónde ir desde aquí. Estoy apagando hasta 6 modelos, sólo para escribir una sola prueba.
I sé la capacidad de trabajo, eso es lo que es para ability_spec.rb
.
Así que esta pregunta es realmente 2 veces:
- ¿Debo estar probando el modelo de habilidad por separado?
- debe El controlador comprueba estar preocupados con permisos adecuados?
Editar require 'spec_helper' Idear incluir :: # TestHelpers para dar el acceso del usuario a las especificaciones ayudantes
describe TokensController do
before(:each) do
@mock_user = User.new(:username => "bob", :email => "user@user.com", :password => "longpassword")
@mock_user.role = "admin"
sign_in @mock_user
#Ability.stub!('can').and_return(true)
end
it "should let me see grids/:g_id/tokens index" do
test_grid = mock_model(Grid)
test_token = mock_model(Token)
Grid.stub!(:find).and_return(test_grid)
Token.stub!(:find).and_return(test_token)
get 'index'
a1 = Ability.new(@mock_user)
a1.can?(:index, Token).should be_true # This line works fine; as it should
puts response.status #This returns 403, which means CanCan::AccessDenied was raised
end
end
Gracias,
Robbie
Solución
hago la prueba del modelo de can-can por separado, pero las pruebas lo que permitirá en qué condiciones.
Creo que si usted está haciendo cosas como
authorize! :take_over, @the_world
A continuación, yo creo que debería estar comprobando que en el controlador. No estoy seguro de que necesita para probar todas las 6 versiones de sus modelos sin embargo.
Se puede apagar la Ability.can? clase y tiene que responder verdadero / falso, y la prueba de cómo sus manijas del controlador cuando puede (y más importante) cuando no puede continuar.
Otros consejos
No estoy seguro si esto es demasiado tarde para ti, pero sólo se encontró con el mismo problema y lo resolvió mediante el siguiente ejemplo de código -
before do
@user = Factory.create(:user)
sign_in @user
@abilities = Ability.new(@user)
Ability.stub(:new).and_return(@abilities)
end
end
He apagó Habilidad # nueva, y me da una referencia a la instancia de capacidad que los controles del usuario actual. Entonces, puedo apagar habilidades específicas, como la siguiente:
@abilities.stub!(:can?).with(:destroy, regatta).and_return(true)
o dar privilegios de administrador:
@abilities.stub!(:can?).and_return(false)
Al igual que en la respuesta de Sam, pero a partir de la página wiki CanCan en las pruebas:
Controlador de pruebas
Si desea la funcionalidad de autorización de ensayo a nivel del controlador es una opción para iniciar sesión en el usuario que tiene los permisos adecuados.
user = User.create!(:admin => true) # I recommend a factory for this
# log in user however you like, alternatively stub `current_user` method
session[:user_id] = user.id
get :index
assert_template :index # render the template since he should have access
Como alternativa, si desea probar el comportamiento del regulador independientemente de lo que está dentro de la clase Capacidad, es fácil de apagar la capacidad con cualquier comportamiento que desea.
def setup
@ability = Object.new
@ability.extend(CanCan::Ability)
@controller.stubs(:current_ability).returns(@ability)
end
test "render index if have read ability on project" do
@ability.can :read, Project
get :index
assert_template :index
end
Si tiene permisos muy complejos que puede dar lugar a muchas posibilidades de ramificación. Si estos son probadas en la capa del controlador entonces se puede llevar a pruebas lentos y hinchado. En lugar de eso recomiendo mantener autorización controlador pruebas de luz y probar la funcionalidad de autorización más a fondo en el modelo de Capacidad a través de pruebas de unidad como se muestra en la parte superior.
creo que las necesidades de autorización por hacer sobre todo para los controladores para asegurarse de que su autorización está trabajando correctamente con los controladores. Así que para hacerlo SECO usted puede implementar su propio matcher
para ser utilizado como esto
let!(:user) {create :user}
before { login_user_request user}
it "grants admin access to show action" do
expect{ get :show, {id: user.id} }.to be_authorized
end
it "denies user access to edit action" do
expect{ get :edit, {id: user.id} }.to be_un_authorized
end
y luego poner en práctica estos comparadores con su propia manera de prueba de cómo se autorizó una solicitud o no
RSpec::Matchers.define :be_authorized do
match do |block|
block.call
expect(response).to be_success
end
def supports_block_expectations?
true
end
end
RSpec::Matchers.define :be_un_authorized do
match do |block|
expect{
block.call
}.to raise_error(Pundit::NotAuthorizedError)
end
def supports_block_expectations?
true
end
end
¿Por qué no se incluye un
can :manage, :all do
user.is_ultrasuper == 1
end
en su capacidad y luego tener un parámetro is_ultrasuper en uno de los usuarios del accesorio:
one:
id: 1
username: my_username
is_ultrasuper: 1
A continuación, ingrese a este usuario en la configuración de sus pruebas. Esta en las pruebas que debe ser capaz de hacer nada en absoluto.