Search code examples
djangodjango-unittest

django tests response.request.user.is_authenticated() returning True after logout


I am trying to write some tests for the authentication part of my application and I encountered a problem with checking if the user is logged in or not. Here's the code:

    client = Client()

    # user signup form
    response = client.post(signup_url, data={
        'email': "lorem@ipsum.pl",
        'password1': 'hunter2',
        'password2': 'hunter2',
    }, follow=True)

    # checking if the user is logged in
    with self.assertRaises(KeyError):
        client.session['_auth_user_id']

    self.assertEquals(len(mail.outbox), 1)
    url = find_verification_url(mail.outbox[0].body)
    response = client.get(url, follow=True)
    self.assertEqual(200, response.status_code)

    user = User.objects.get(email="lorem@ipsum.pl")

    self.assertEqual(client.session['_auth_user_id'], user.pk)

    # how to logout a user?
    force_logout()

    self.assertFalse(response.request.user.is_authenticated())

The user fills the form and clicks submit, then receives an email with a verification url. After he clicks the verification url in the email he's supposed to get directed to the site and authenticated. My questions is, what is a good way to find out if the user is authenticated or not? What is a preferred way to log out a user in this situation? I want to check that if the user is logged out and clicks the link the verification link second time it doesn't work. I tried some things like:

client.logout()

But unfortunately it seems to work once every two times even when I remove this line.

Thanks for any help!


Solution

  • Ok so the problem was that the authentication system was using a timestamp function to know if a url was expired or not. When run in a test the verification url was not expired when it should be. The login request after the logout was too fast and the system was thinking that the verification url was still valid and the user got authenticated. And that's why user.is_authenticated() was returning True all the time.