views:

192

answers:

3

I'm using django.test.client.Client to test whether some text shows up when a user is logged in. However, I the Client object doesn't seem to be keeping me logged in.

This test passes if done manually with Firefox but not when done with the Client object.

class Test(TestCase):
    def test_view(self):
        user.set_password(password)
        user.save()

        client = self.client
        # I thought a more manual way would work, but no luck
        # client.post('/login', {'username':user.username, 'password':password})
        login_successful = client.login(username=user.username, password=password)
        # this assert passes  
        self.assertTrue(login_successful)

        response = client.get("/path", follow=True)
        #whether follow=True or not doesn't seem to work

        self.assertContains(response, "needle" )

When I print response it returns the login form that is hidden by:

{% if not request.user.is_authenticated %}
    ... form ...
{% endif %}

This is confirmed when I run ipython manage.py shell.

The problem seems to be that the Client object is not keeping the session authenticated.

A: 

I use RequestContext to get the logged in user into the template context.

from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
from django.template import RequestContext

@login_required
def index(request):
   return render_to_response('page.html',
                             {},
                             context_instance=RequestContext(request))

and in the template

{% if user.is_authenticated %} ... {{ user.username }} .. {% endif %}

This works as expected (I don't get to this page without logging in, and when I get there, the username is present in response.content) when driven through the test client.

Dave W. Smith
I don't think that's the issue. If I weren't importing the context correctly then it wouldn't work in Firefox as well as with Client. The problem is that it does work in Firefox but not with client so I can't test the functionality.
Mystic
Your use of request.user.is_authenticated (rather than user.is_authenticated) suggests that you're not using the context. If it didn't work for you via a browser, I'd suspect that you're not passing `{'request': request}` to your template.
Dave W. Smith
A: 

FWIW, an update to Django 1.2 (I was running 1.1.1 before) fixed it. I have no idea what was broken there, considering when I last ran that test suite about 2 weeks ago, it worked great.

Fred
So you encountered the same problem?
Mystic
I also upgraded to Django 1.2 and the problem went away. Thanks!
Mystic
A: 

Just happened to me when retesting an app that has been working and forgotten for some months.

The solution (apart from updating to Django 1.2) is Patch #11821. In short, Python 2.6.5 has some bugfix in the Cookie module, triggering an edge case bug in the test client.

Javier