In my rails app I have two user roles: 'student' and 'admin'. They have different access authorization to different pages, e.g., 'admin' can access listing users page (index) but 'student' cannot. This is controlled using cancancan.
Now I am writing tests for controllers and, since I have two different roles, (to my knowledge) I need two separate tests for a single behaviour, for example:
test "should get index for admin" do
sign_in(users(:admin))
get "index"
assert_response :success
end
test "should not get index for student" do
sign_in(users(:student))
get "index"
assert_response :unauthorized
end
where sign_in(*)
is the method for handing user login (sessions etc.)
As I am considering adding more roles (e.g. 'manager', 'agent'), I need to add new tests for all the controller methods each time I add a role. This is tedious and not "DRY", so I am trying to find a more elegant way to handle this. Here is my first thought:
In my test_helper.rb, I added:
def assert_admin_only(&block)
sign_in(users(:admin))
instance_exec(&block)
assert_response :success
sign_out
sign_in(users(:student))
instance_exec(&block)
assert_response :unauthorized
sign_out
sign_in(users(:agent))
instance_exec(&block)
assert_response :unauthorized
sign_out
end
Then in my test:
test "should get index for admin only" do
assert_admin_only do
get "index"
end
end
So that each time I added a new role, I only have to add a few lines in the test_helper.rb method in order to test the abilities.
However, it does not work as I thought because "Functional tests allow you to test a single controller action per test method." according to Rails API DOC, while in my code I was firing two actions or even more. For some reason I can't figure out, it seems that the sign_in
and sign_out
don't actually change the current_user (although they are working perfectly in real requests), which essentially make my attempt fail.
In a word, I want to reuse my tests for different user roles so that I don't have to waste my time copying and pasting existing codes every time I add a new role. I would really appreciate it if you guys could provide some brilliant ideas.
Aucun commentaire:
Enregistrer un commentaire