Fixed #10482 -- Unified access to response.context when inspecting responses from the test client. Thanks to James Bennett for the design, and Julien Phalip for the patch.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@10084 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
61a2708c41
commit
ee2f04d79e
|
@ -20,6 +20,7 @@ from django.utils.encoding import smart_str
|
|||
from django.utils.http import urlencode
|
||||
from django.utils.itercompat import is_iterable
|
||||
from django.db import transaction, close_connection
|
||||
from django.test.utils import ContextList
|
||||
|
||||
BOUNDARY = 'BoUnDaRyStRiNg'
|
||||
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
|
||||
|
@ -80,8 +81,8 @@ def store_rendered_templates(store, signal, sender, template, context, **kwargs)
|
|||
"""
|
||||
Stores templates and contexts that are rendered.
|
||||
"""
|
||||
store.setdefault('template',[]).append(template)
|
||||
store.setdefault('context',[]).append(context)
|
||||
store.setdefault('template', []).append(template)
|
||||
store.setdefault('context', ContextList()).append(context)
|
||||
|
||||
def encode_multipart(boundary, data):
|
||||
"""
|
||||
|
|
|
@ -6,6 +6,20 @@ from django.test import signals
|
|||
from django.template import Template
|
||||
from django.utils.translation import deactivate
|
||||
|
||||
class ContextList(list):
|
||||
"""A wrapper that provides direct key access to context items contained
|
||||
in a list of context objects.
|
||||
"""
|
||||
def __getitem__(self, key):
|
||||
if isinstance(key, basestring):
|
||||
for subcontext in self:
|
||||
if key in subcontext:
|
||||
return subcontext[key]
|
||||
raise KeyError
|
||||
else:
|
||||
return super(ContextList, self).__getitem__(key)
|
||||
|
||||
|
||||
def instrumented_test_render(self, context):
|
||||
"""
|
||||
An instrumented Template render method, providing a signal
|
||||
|
|
|
@ -712,6 +712,16 @@ Specifically, a ``Response`` object has the following attributes:
|
|||
If the rendered page used multiple templates, then ``context`` will be a
|
||||
list of ``Context`` objects, in the order in which they were rendered.
|
||||
|
||||
.. versionadded:: 1.1
|
||||
|
||||
Regardless of the number of templates used during rendering, you can
|
||||
retrieve context values using the ``[]`` operator. For example, the
|
||||
context variable ``name`` could be retrieved using::
|
||||
|
||||
>>> response = client.get('/foo/')
|
||||
>>> response.context['name']
|
||||
'Arthur'
|
||||
|
||||
.. attribute:: request
|
||||
|
||||
The request data that stimulated the response.
|
||||
|
|
|
@ -5,9 +5,10 @@ import os
|
|||
from django.conf import settings
|
||||
|
||||
from django.test import Client, TestCase
|
||||
from django.test.utils import ContextList
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.core.exceptions import SuspiciousOperation
|
||||
from django.template import TemplateDoesNotExist, TemplateSyntaxError
|
||||
from django.template import TemplateDoesNotExist, TemplateSyntaxError, Context
|
||||
|
||||
class AssertContainsTests(TestCase):
|
||||
def test_contains(self):
|
||||
|
@ -455,6 +456,26 @@ class zzUrlconfSubstitutionTests(TestCase):
|
|||
url = reverse('arg_view', args=['somename'])
|
||||
self.assertEquals(url, '/test_client_regress/arg_view/somename/')
|
||||
|
||||
class ContextTests(TestCase):
|
||||
fixtures = ['testdata']
|
||||
|
||||
def test_single_context(self):
|
||||
"Context variables can be retrieved from a single context"
|
||||
response = self.client.get("/test_client_regress/request_data/", data={'foo':'whiz'})
|
||||
self.assertEqual(response.context.__class__, Context)
|
||||
self.assertEqual(response.context['get-foo'], 'whiz')
|
||||
self.assertEqual(response.context['request-foo'], 'whiz')
|
||||
self.assertEqual(response.context['data'], 'sausage')
|
||||
|
||||
def test_inherited_context(self):
|
||||
"Context variables can be retrieved from a list of contexts"
|
||||
response = self.client.get("/test_client_regress/request_data_extended/", data={'foo':'whiz'})
|
||||
self.assertEqual(response.context.__class__, ContextList)
|
||||
self.assertEqual(len(response.context), 2)
|
||||
self.assertEqual(response.context['get-foo'], 'whiz')
|
||||
self.assertEqual(response.context['request-foo'], 'whiz')
|
||||
self.assertEqual(response.context['data'], 'bacon')
|
||||
|
||||
class SessionTests(TestCase):
|
||||
fixtures = ['testdata.json']
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ urlpatterns = patterns('',
|
|||
(r'^staff_only/$', views.staff_only_view),
|
||||
(r'^get_view/$', views.get_view),
|
||||
(r'^request_data/$', views.request_data),
|
||||
(r'^request_data_extended/$', views.request_data, {'template':'extended.html', 'data':'bacon'}),
|
||||
url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'),
|
||||
(r'^login_protected_redirect_view/$', views.login_protected_redirect_view),
|
||||
(r'^redirects/$', redirect_to, {'url': '/test_client_regress/redirects/further/'}),
|
||||
|
|
|
@ -19,15 +19,16 @@ def get_view(request):
|
|||
return HttpResponse("Hello world")
|
||||
get_view = login_required(get_view)
|
||||
|
||||
def request_data(request):
|
||||
def request_data(request, template='base.html', data='sausage'):
|
||||
"A simple view that returns the request data in the context"
|
||||
return render_to_response('base.html', {
|
||||
return render_to_response(template, {
|
||||
'get-foo':request.GET.get('foo',None),
|
||||
'get-bar':request.GET.get('bar',None),
|
||||
'post-foo':request.POST.get('foo',None),
|
||||
'post-bar':request.POST.get('bar',None),
|
||||
'request-foo':request.REQUEST.get('foo',None),
|
||||
'request-bar':request.REQUEST.get('bar',None),
|
||||
'data': data,
|
||||
})
|
||||
|
||||
def view_with_argument(request, name):
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
{% extends "base.html" %}
|
||||
{% block title %}Extended template{% endblock %}
|
||||
{% block content %}
|
||||
This is just a template extending the base.
|
||||
{% endblock %}
|
Loading…
Reference in New Issue