Comment mieux écrire un matcher personnalisé RSpec pour tester le contrôle d'accès dans une application Rails
-
10-07-2019 - |
Question
OK, au lieu d'écrire un grand nombre de spécifications de contrôle d'accès et de les dupliquer dans bon nombre de mes fichiers de spécifications, je cherche à créer un matcher personnalisé. Donc au lieu de cela:
describe "access control" do
it "should prevent access by non-logged-in users"
it "should prevent access by normal users"
it "should prevent access by editor users"
it "should prevent access by admin users"
it "should allow access by super admin users"
end
Je veux faire quelque chose comme ça:
lambda do
get :index
end.should have_access_control(:allowed => [:super_admin], :disallowed => [:admin, :editor, :user])
Existe-t-il des exemples ou des suggestions sur la manière dont je peux faire quelque chose comme cela?
La solution
OK, J'ai trouvé une méthode pour y parvenir , même s'il n'utilise pas de matcher personnalisé. Incluez le code suivant dans votre fichier spec_helper.rb:
def access_control (code, options={})
options = {:allow => [], :disallow => []}.merge(options)
options[:allow].each do |user|
it "#{code} should allow #{user.to_s}" do
login_as(user)
eval code
response.should_not redirect_to(login_path)
end
end
options[:disallow].each do |user|
it "#{code} should disallow #{user.to_s}" do
login_as(user)
eval code
response.should redirect_to(login_path)
end
end
end
Et appelez-le comme suit:
access_control("get :index", {:allow => [:super_admin], :disallow => [:quentin, :admin]})
Vous pouvez ensuite l'utiliser pour créer une liste complète des méthodes devant être restreintes et des utilisateurs auxquels elles sont limitées.
Autres conseils
Je ne suis pas d'accord avec votre solution. Les tests ne devraient pas être un domaine pour exclure la duplication de ce type. Cela rend les tests plus difficiles à lire et à maintenir. En outre, il existe certainement un argument selon lequel la duplication dans les tests peut informer votre conception .
Dans l'exemple initial que vous avez cité, il existe 5 contextes différents qui doivent chacun être testés séparément et pouvoir être compris d'un coup d'œil. Votre solution, bien que soignée, nuit à ces deux objectifs.