8

I wanted to introduce unit testing to a Django application. Although I started failing on the first thing I wanted to test. Can you tell me what I am doing wrong?

The view I want to test

@user_passes_test(lambda u: u.has_module_perms('myModule'))
def myView(request):
    ...someCode...

I wanted to test the user_passes_test bit, I also have more complex tests so I wanted to know if my tests let the right users and only them access the view. I focused on the bit that didn't work and simplified it a bit.

from django.contrib.auth.models import User
from django.test import TestCase
from settings import DJANGO_ROOT

class PermissionsTestCase(TestCase):
    fixtures = [DJANGO_ROOT + 'testdata.json']

    def setUp(self):
        self.user = User.objects.create(username='user', password='pass')
        self.user.save()

    def test_permissions_overview(self):
        url = '/secret/'

        #User not logged in (guest)
        response = self.client.get(url)
        self.assertRedirects(response, 'http://testserver/accounts/login/?next=/secret/')

        #Logged in user that should not be able to see this page
        response = self.client.get(url)
        self.client.login(username='user', password='pass')
        self.assertRedirects(response, 'http://testserver/accounts/login/?next=/secret/')

        #Logged in user that has 'myModule' module permissions 
        self.user.user_permissions.add('myModule.view_myThing')
        self.user.save()
        self.assertTrue(self.user.has_module_perms('myModule')) #This one fails
        self.client.login(username='user',password='pass')
        response = self.client.get(url)
        self.assertContains(response,  "What to look for") #This one too

And the last bit keeps on failing. The permission doesn't get through. Any ideas?

timovdw
  • 311
  • 2
  • 10
  • `self.user.user_permissions.add('myModule.view_myThing')` cannot work. The answer as to why it cannot work can be found here: [Invalid Literal error when adding a user permission to a Django user object](http://stackoverflow.com/questions/10131271/invalid-literal-error-when-adding-a-user-permission-to-a-django-user-object) – Louis Feb 17 '14 at 20:57
  • You have to pass a Permission object inside user_permissions.add() method. You can't just pass a string. – reetesh11 Dec 01 '17 at 05:35

2 Answers2

5

This won't convert the password to hash

User.objects.create(username='user', password='pass')

the correct way to create user is :

User.objects.create_user(username='user', password='pass')

here is full summary

>>> from django.contrib.auth.models import User
>>> x=User.objects.create(username='user', password='pass')    
>>> x.password
'pass'
>>> from django.test import Client
>>> c = Client()
>>> c.login(username='user',password='pass')
False

# But create_user works
>>> y=User.objects.create_user(username='user2', password='pass')    
>>> y.password
u'pbkdf2_sha256$12000$oh55gfrnCZn5$hwGrkUZx38siegWHLXSYoNDT2SSP1M5+Whh5PnJZD8I='
>>> c.login(username='user2',password='pass')
True
suhailvs
  • 20,182
  • 14
  • 100
  • 98
  • thanks, almost forgot about this, but you boosted our unit testing again! Such a stupid mistake though :/ – timovdw Aug 01 '14 at 15:03
-3

Permissions are strings.

# this tests to see if a user has 'myModule'
@user_passes_test(lambda u: u.has_module_perms('myModule'))

#gives the user a completely different permission called 'myModule.view_myThing'
self.user.user_permissions.add('myModule.view_myThing')

#tests to see if user has a permission called 'myModule' which is not 'myModule.view_myThing'
self.assertTrue(self.user.has_module_perms('myModule'))

Base on what you have written I cannot infer your intent but you have at least 2 distinct permissions you are attempting to add/check. I would change the permissions you give to the user as follows: self.user.user_permissions.add('myModule')

Victor 'Chris' Cabral
  • 2,135
  • 1
  • 16
  • 33