views:

50

answers:

1

I'm writing detailed functional tests for my views to complement the unit tests on my models. It's a Django project and I'm using the built in Django test framework with unittest. Obviously, one of the important things to check in these functional tests is that the permissions are set up correctly. With that in mind, I'm attempting something like this:

anonclient = Client()
userclient = Client()
userclient.login(username='test_user', password='test')
adminclient = Client()
adminclient.login(username='test_admin', password='test')

path = "/path/to/my/page"
anonresponse = anonclient.get(path)
userresponse = userclient.get(path)
adminresponse = adminclient.get(path)

I need to be able to confirm that the anonclient and userclient were both denied permission while the adminclient worked correctly. Howerver, I can't find a way to test that this has happened robustly!

At first I decided to check that the response was a 302 redirect (because a side effect of failing the permission check is being redirected) but this means it is impossible to tell the difference between functionality that automatically redirects the user and a failed permissions check. (I can't just use self.assertRedirects(response, url) because the target url can be overridden via the permission_required decorator's login_url parameter in the view!)

Perhaps I should look into extending the user_passes_test decorator so that it adds a property to the response object if the test fails? This could then be checked for in the tests. Failing that I will have to determine whether the request was successful by checking if the request's side-effects have happened. Doing it this way will work, but it will be extremely long winded, especially with a lot of these checks being done.

I can't imagine I am the first person to run into this issue, what's the right way to deal with this problem, or what have I missed?

Thanks very much!

+1  A: 

The django test client returns a boolean when you call the login method, which tells you if the login was successful.

[17] >>> from django.test import Client
[18] >>> c = Client()
[19] >>> c.login(username='superuser', password='bar')
[19] : False
[20] >>> c.login(username='superuser', password='correct_password')
[20] : True
Justin Lilly
Thanks Justin, but you've misunderstood my question - I need to check if the subsequent get is successful or if a permission error occurs (with resulting redirect).The login is working fine - I need to be able to test that the permission check is working on the Django view.
adamnfish
You should be able to check to see if the resulting url is the one which you tried to access. my_url = '/foo/' resp = c.get(my_url)Then you can check the ``resp`` object for things related to your resulting page. docs.djangoproject.com/en/dev/topics/testing/#testing-responses Specifically, status code, checking that the correct template was used, etc. Hope that helps!
Justin Lilly
As I said though, I'd like to be able to tell the difference between a view that serves a redirect and a view that is redirected by the user failing a test. I'm aware I can check for side-effects or sniff the resulting page (indeed, this is what I am doing for now) but I was wondering if there is a way to detect that the user failed a test and the view was not run, directly.It seems there isn't for now so I guess I'll submit a feature request after the 1.2 release or roll a patched user_passes_test decorator myself.
adamnfish