Django-Python Django Login test failed with factory_boy and Authtools

django, factory-boy, python, unit-testing

Solution

I answer myself. The solution is: Factory_boy under the hook calls `model.objects.create()`. When you create a user, the auth model calls `model.objects.create_user()`. Both work. But the difference is that `create_user` usees `django.contrib.auth.hashers.make_password` for password encryption and `create` saves the password as plain text. Then the solution is:

from django.core.urlresolvers import reverse


from django_webtest import WebTest
from authtools.models import User
from rest_framework import status


from .factories import UserFactory, user_password


class UserLoginTests(WebTest):

    def setUp(self):
        self.user = UserFactory()


    def tearDown(self):
        User.objects.get(email = self.user.email).delete()

    def test_user_login_client(self):
        self.resp = self.client.login(username = self.user.email, password = user_password
        )
        self.assertEqual(self.resp, True)
        self.client.logout()

    def test_user_logsin_view(self):
        Home_View = self.app.get(reverse('users_home'))
        Login_Form = Home_View.forms['login-form']
        Login_Form['username'] = self.user.email
        Login_Form['password'] = user_password
        response = Login_Form.submit().follow()
        self.assertEqual(redirect.status_code, status_HTTP_200_ok)
        self.client.logout() 

And the factories

import factory


from django.conf import settings
from django.contrib.auth.hashers import make_password

user_password = 'test'   # Testing password 

class UserFactory (factory.DjangoModelFactory):
    """
    Factory used to instanciate a :class: Users.User
    """

    class Meta:
        model = settings.AUTH_USER_MODEL

    name = factory.Sequence(lambda n: 'user%d' % n)
    email = factory.LazyAttribute(lambda obj: '%s@eCRD.com' % obj.name)
    password = make_password(user_password)
    is_active = True

Problem

My unit testings are failing when i want to test Login functionality. When I test in my browser is's OK. I'm using: ``` django==1.6.5 factory-boy==2.4.1 WebTest==2.0.15 django-webtest==1.7.7 nose==1.3.3 django-nose==1.2 ``` There are no custom user model. The user model is authtools.models.User. My views: ``` from authtools.views import LoginView from django.views.generic import TemplateView from django.core.urlresolvers import reverse class Home_view(LoginView): template_name = 'users/home.html' disallow_authenticated = False def get_success_url(self): return reverse('users:blob') class Blob_view (TemplateView): template_name = "users/blob.html" ``` My factories: ``` import factory from django.conf import settings from django.contrib.auth.hashers import make_password class UserFactory (factory.DjangoModelFactory): """ Factory used to instanciate a :class: Users.User """ class Meta: model = settings.AUTH_USER_MODEL name = factory.Sequence(lambda n: 'user%d' % n) email = factory.LazyAttribute(lambda obj: '%s@eCRD.com' % obj.name) password = make_password('eCRD') is_active = True ``` My tests: There are two test. The first test the client login, the second test the views: ``` from django.core.urlresolvers import reverse from django_webtest import WebTest from authtools.models import User from rest_framework import status from .factories import UserFactory class UserLoginTests(WebTest): def setUp(self): self.user = UserFactory() def tearDown(self): User.objects.get(email = self.user.email).delete() def test_user_login_client(self): self.resp = self.client.login(username = self.user.email, password = self.user.password ) self.assertEqual(self.resp, True) self.client.logout() def test_user_logsin_view(self): Home_View = self.app.get(reverse('users_home')) Login_Form = Home_View.forms['login-form'] Login_Form['username'] = self.user.email Login_Form['password'] = self.user.password response = Login_Form.submit().follow() self.assertEqual(redirect.status_code, status_HTTP_200_ok) self.client.logout() ``` Both test failed. But in the browser it work well. Thanks.

Original source