Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django's self.client.login(...) does not work in unit tests

I have created users for my unit tests in two ways:

1) Create a fixture for "auth.user" that looks roughly like this:

    {          "pk": 1,          "model": "auth.user",          "fields": {              "username": "homer",              "is_active": 1,              "password":  "sha1$72cd3$4935449e2cd7efb8b3723fb9958fe3bb100a30f2",              ...          }      } 

I've left out the seemingly unimportant parts.

2) Use 'create_user' in the setUp function (although I'd rather keep everything in my fixtures class):

def setUp(self):         User.objects.create_user('homer', '[email protected]', 'simpson')  

Note that the password is simpson in both cases.

I've verified that this info is correctly being loaded into the test database time and time again. I can grab the User object using User.objects.get. I can verify the password is correct using 'check_password.' The user is active.

Yet, invariably, self.client.login(username='homer', password='simpson') FAILS. I'm baffled as to why. I think I've read every single Internet discussion pertaining to this. Can anybody help?

The login code in my unit test looks like this:

    login = self.client.login(username='homer', password='simpson')      self.assertTrue(login)  

Thanks.

like image 868
thebossman Avatar asked Apr 11 '10 23:04

thebossman


People also ask

What is self client in Python?

self. client , is the built-in Django test client. This isn't a real browser, and doesn't even make real requests. It just constructs a Django HttpRequest object and passes it through the request/response process - middleware, URL resolver, view, template - and returns whatever Django produces.

How do I login as user in Django?

from django.contrib.auth import authenticate, login def my_view(request): username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: login(request, user) # Redirect to a success page. ... else: # Return an 'invalid ...

What is client in Django test?

The test client is a Python class that acts as a dummy web browser, allowing you to test your views and interact with your Django-powered application programmatically.


1 Answers

The code that doesn't work:

from django.contrib.auth.models import User from django.test import Client  user = User.objects.create(username='testuser', password='12345')  c = Client() logged_in = c.login(username='testuser', password='12345') 

Why doesn't it work?

In the snippet above, when the User is created the actual password hash is set to be 12345. When the client calls the login method, the value of the password argument, 12345, is passed through the hash function, resulting in something like

hash('12345') = 'adkfh5lkad438....' 

This is then compared to the hash stored in the database, and the client is denied access because 'adkfh5lkad438....' != '12345'

The Solution

The proper thing to do is call the set_password function, which passes the given string through the hash function and stores the result in User.password.

In addition, after calling set_password we must save the updated User object to the database:

user = User.objects.create(username='testuser') user.set_password('12345') user.save()  c = Client() logged_in = c.login(username='testuser', password='12345') 
like image 160
Pedro M Duarte Avatar answered Sep 20 '22 05:09

Pedro M Duarte



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!