tags:

views:

25

answers:

2

I have a view that looks like this:

def login(request):
    ...
    # some variables has been set here
    ...
    if request.POST.get('remember_me', None):
        request.session.set_expiry(1209600) # 2 weeks
    return HttpResponseRedirect(reverse('dashboard'))

Now If I assert for the variables using context, I get the error: "AttributeError: 'HttpResponseRedirect' object has no attribute 'context' " this is the same for sessions. How do I test it then that some variables has been set and possible session expiration has been set even if i redirect?

A: 

What I've done (for checking session specifically), is to not use Django's test client and to create my own mock request object and pass it directly to my view, like this:

def test_method(self):
    class request(object):
        POST = {'dummy':'data'}
        class session:
            @staticmethod
            def set_expiry(nmbr):
                request.session.nmbr = nmbr

    views.login(request)
    self.assertEqual(request.session.nmbr, 1209600)

Another option may be using the "follow=True" argument when using Django's test Client.

Matthew J Morrison
+1  A: 

You cannot retrieve the context variables from a HttpResponseRedirect. It doesn't make sense why you are setting the context variables if you are redirecting anyway.

You certainly should be able to pick up variables from session after redirecting. I have done this in several of my test cases. How are you asserting the session data in your test case?

This is how I go about asserting session variables after a redirect:

response = self.client.post(reverse('foo'))
self.assertRedirects(response, reverse('bar', args = ['baz']), 
        status_code = 302, target_status_code = 200)
self.assertEqual('value', self.client.session.get('key'))

Self.client is an instance of django.test.client.Client in this case.

Update

(In response to @Marconi's comment) Here is one way of displaying a message to the user after redirecting. This is copied almost verbatim from my answer to another question.

Your first view can create a message for the current using auth and have the second view read and delete it. Something like this:

def first_view(request, *args, **kwargs):
    # all goes well
    message = _("<message for user>")
    request.user.message_set.create(message = message)
    return redirect('second_view')

def second_view(request, *args, **kwargs):
    # Render page

# Template for second_view:
{% for message in messages %}
   ... 
{% endfor %}

Messages are saved to the database. This means that you can access them even after a redirect. They are automatically read and deleted on rendering the template. You will have to use RequestContext for this to work.

Manoj Govindan
The reason I was looking to test context even on redirect is that I'm using django_notify app and just before the redirect I set some messages like:request.notifications.error(_(u"It's either your email or password is incorrect"))and then redirect back to login form so that forms don't retain previously entered values and also refreshing doesn't re-submit the form. I can access notifications if there's no redirect using:response.context['notifications']But the error above shows up when there's a redirect, I just wanna make sure that the message is shown. Or do you have any better way?
Marconi
@Marconi: I have updated my answer. See above.
Manoj Govindan