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.http import urlencode
|
||||||
from django.utils.itercompat import is_iterable
|
from django.utils.itercompat import is_iterable
|
||||||
from django.db import transaction, close_connection
|
from django.db import transaction, close_connection
|
||||||
|
from django.test.utils import ContextList
|
||||||
|
|
||||||
BOUNDARY = 'BoUnDaRyStRiNg'
|
BOUNDARY = 'BoUnDaRyStRiNg'
|
||||||
MULTIPART_CONTENT = 'multipart/form-data; boundary=%s' % BOUNDARY
|
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.
|
Stores templates and contexts that are rendered.
|
||||||
"""
|
"""
|
||||||
store.setdefault('template',[]).append(template)
|
store.setdefault('template', []).append(template)
|
||||||
store.setdefault('context',[]).append(context)
|
store.setdefault('context', ContextList()).append(context)
|
||||||
|
|
||||||
def encode_multipart(boundary, data):
|
def encode_multipart(boundary, data):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -6,6 +6,20 @@ from django.test import signals
|
||||||
from django.template import Template
|
from django.template import Template
|
||||||
from django.utils.translation import deactivate
|
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):
|
def instrumented_test_render(self, context):
|
||||||
"""
|
"""
|
||||||
An instrumented Template render method, providing a signal
|
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
|
If the rendered page used multiple templates, then ``context`` will be a
|
||||||
list of ``Context`` objects, in the order in which they were rendered.
|
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
|
.. attribute:: request
|
||||||
|
|
||||||
The request data that stimulated the response.
|
The request data that stimulated the response.
|
||||||
|
|
|
@ -5,9 +5,10 @@ import os
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
from django.test import Client, TestCase
|
from django.test import Client, TestCase
|
||||||
|
from django.test.utils import ContextList
|
||||||
from django.core.urlresolvers import reverse
|
from django.core.urlresolvers import reverse
|
||||||
from django.core.exceptions import SuspiciousOperation
|
from django.core.exceptions import SuspiciousOperation
|
||||||
from django.template import TemplateDoesNotExist, TemplateSyntaxError
|
from django.template import TemplateDoesNotExist, TemplateSyntaxError, Context
|
||||||
|
|
||||||
class AssertContainsTests(TestCase):
|
class AssertContainsTests(TestCase):
|
||||||
def test_contains(self):
|
def test_contains(self):
|
||||||
|
@ -455,6 +456,26 @@ class zzUrlconfSubstitutionTests(TestCase):
|
||||||
url = reverse('arg_view', args=['somename'])
|
url = reverse('arg_view', args=['somename'])
|
||||||
self.assertEquals(url, '/test_client_regress/arg_view/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):
|
class SessionTests(TestCase):
|
||||||
fixtures = ['testdata.json']
|
fixtures = ['testdata.json']
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,7 @@ urlpatterns = patterns('',
|
||||||
(r'^staff_only/$', views.staff_only_view),
|
(r'^staff_only/$', views.staff_only_view),
|
||||||
(r'^get_view/$', views.get_view),
|
(r'^get_view/$', views.get_view),
|
||||||
(r'^request_data/$', views.request_data),
|
(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'),
|
url(r'^arg_view/(?P<name>.+)/$', views.view_with_argument, name='arg_view'),
|
||||||
(r'^login_protected_redirect_view/$', views.login_protected_redirect_view),
|
(r'^login_protected_redirect_view/$', views.login_protected_redirect_view),
|
||||||
(r'^redirects/$', redirect_to, {'url': '/test_client_regress/redirects/further/'}),
|
(r'^redirects/$', redirect_to, {'url': '/test_client_regress/redirects/further/'}),
|
||||||
|
|
|
@ -19,15 +19,16 @@ def get_view(request):
|
||||||
return HttpResponse("Hello world")
|
return HttpResponse("Hello world")
|
||||||
get_view = login_required(get_view)
|
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"
|
"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-foo':request.GET.get('foo',None),
|
||||||
'get-bar':request.GET.get('bar',None),
|
'get-bar':request.GET.get('bar',None),
|
||||||
'post-foo':request.POST.get('foo',None),
|
'post-foo':request.POST.get('foo',None),
|
||||||
'post-bar':request.POST.get('bar',None),
|
'post-bar':request.POST.get('bar',None),
|
||||||
'request-foo':request.REQUEST.get('foo',None),
|
'request-foo':request.REQUEST.get('foo',None),
|
||||||
'request-bar':request.REQUEST.get('bar',None),
|
'request-bar':request.REQUEST.get('bar',None),
|
||||||
|
'data': data,
|
||||||
})
|
})
|
||||||
|
|
||||||
def view_with_argument(request, name):
|
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