Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test context and session in Django after redirect?

Tags:

django

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?

like image 843
Marconi Avatar asked Sep 01 '10 15:09

Marconi


2 Answers

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.

like image 110
Manoj Govindan Avatar answered Oct 20 '22 03:10

Manoj Govindan


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.

like image 27
Matthew J Morrison Avatar answered Oct 20 '22 04:10

Matthew J Morrison