App Engine Python SDK version 1.7.4 (2)
[gae.git] / python / lib / django_1_4 / tests / regressiontests / templates / response.py
blob5feb8cc51b02c5d7aff58af691664308f266b847
1 from __future__ import with_statement
3 import os
4 import pickle
5 import time
6 from datetime import datetime
8 from django.utils import unittest
9 from django.test import RequestFactory, TestCase
10 from django.conf import settings
11 import django.template.context
12 from django.template import Template, Context
13 from django.template.response import (TemplateResponse, SimpleTemplateResponse,
14 ContentNotRenderedError)
16 def test_processor(request):
17 return {'processors': 'yes'}
18 test_processor_name = 'regressiontests.templates.response.test_processor'
21 # A test middleware that installs a temporary URLConf
22 class CustomURLConfMiddleware(object):
23 def process_request(self, request):
24 request.urlconf = 'regressiontests.templates.alternate_urls'
27 class BaseTemplateResponseTest(unittest.TestCase):
28 # tests rely on fact that global context
29 # processors should only work when RequestContext is used.
31 def setUp(self):
32 self.factory = RequestFactory()
33 self._old_processors = settings.TEMPLATE_CONTEXT_PROCESSORS
34 self._old_TEMPLATE_DIRS = settings.TEMPLATE_DIRS
35 settings.TEMPLATE_CONTEXT_PROCESSORS = [test_processor_name]
36 settings.TEMPLATE_DIRS = (
37 os.path.join(
38 os.path.dirname(__file__),
39 'templates'
42 # Force re-evaluation of the contex processor list
43 django.template.context._standard_context_processors = None
45 def tearDown(self):
46 settings.TEMPLATE_DIRS = self._old_TEMPLATE_DIRS
47 settings.TEMPLATE_CONTEXT_PROCESSORS = self._old_processors
48 # Force re-evaluation of the contex processor list
49 django.template.context._standard_context_processors = None
52 class SimpleTemplateResponseTest(BaseTemplateResponseTest):
54 def _response(self, template='foo', *args, **kwargs):
55 return SimpleTemplateResponse(Template(template), *args, **kwargs)
57 def test_template_resolving(self):
58 response = SimpleTemplateResponse('first/test.html')
59 response.render()
60 self.assertEqual('First template\n', response.content)
62 templates = ['foo.html', 'second/test.html', 'first/test.html']
63 response = SimpleTemplateResponse(templates)
64 response.render()
65 self.assertEqual('Second template\n', response.content)
67 response = self._response()
68 response.render()
69 self.assertEqual(response.content, 'foo')
71 def test_explicit_baking(self):
72 # explicit baking
73 response = self._response()
74 self.assertFalse(response.is_rendered)
75 response.render()
76 self.assertTrue(response.is_rendered)
78 def test_render(self):
79 # response is not re-rendered without the render call
80 response = self._response().render()
81 self.assertEqual(response.content, 'foo')
83 # rebaking doesn't change the rendered content
84 response.template_name = Template('bar{{ baz }}')
85 response.render()
86 self.assertEqual(response.content, 'foo')
88 # but rendered content can be overridden by manually
89 # setting content
90 response.content = 'bar'
91 self.assertEqual(response.content, 'bar')
93 def test_iteration_unrendered(self):
94 # unrendered response raises an exception on iteration
95 response = self._response()
96 self.assertFalse(response.is_rendered)
98 def iteration():
99 for x in response:
100 pass
101 self.assertRaises(ContentNotRenderedError, iteration)
102 self.assertFalse(response.is_rendered)
104 def test_iteration_rendered(self):
105 # iteration works for rendered responses
106 response = self._response().render()
107 res = [x for x in response]
108 self.assertEqual(res, ['foo'])
110 def test_content_access_unrendered(self):
111 # unrendered response raises an exception when content is accessed
112 response = self._response()
113 self.assertFalse(response.is_rendered)
114 self.assertRaises(ContentNotRenderedError, lambda: response.content)
115 self.assertFalse(response.is_rendered)
117 def test_content_access_rendered(self):
118 # rendered response content can be accessed
119 response = self._response().render()
120 self.assertEqual(response.content, 'foo')
122 def test_set_content(self):
123 # content can be overriden
124 response = self._response()
125 self.assertFalse(response.is_rendered)
126 response.content = 'spam'
127 self.assertTrue(response.is_rendered)
128 self.assertEqual(response.content, 'spam')
129 response.content = 'baz'
130 self.assertEqual(response.content, 'baz')
132 def test_dict_context(self):
133 response = self._response('{{ foo }}{{ processors }}',
134 {'foo': 'bar'})
135 self.assertEqual(response.context_data, {'foo': 'bar'})
136 response.render()
137 self.assertEqual(response.content, 'bar')
139 def test_context_instance(self):
140 response = self._response('{{ foo }}{{ processors }}',
141 Context({'foo': 'bar'}))
142 self.assertEqual(response.context_data.__class__, Context)
143 response.render()
144 self.assertEqual(response.content, 'bar')
146 def test_kwargs(self):
147 response = self._response(content_type = 'application/json', status=504)
148 self.assertEqual(response['content-type'], 'application/json')
149 self.assertEqual(response.status_code, 504)
151 def test_args(self):
152 response = SimpleTemplateResponse('', {}, 'application/json', 504)
153 self.assertEqual(response['content-type'], 'application/json')
154 self.assertEqual(response.status_code, 504)
156 def test_post_callbacks(self):
157 "Rendering a template response triggers the post-render callbacks"
158 post = []
160 def post1(obj):
161 post.append('post1')
162 def post2(obj):
163 post.append('post2')
165 response = SimpleTemplateResponse('first/test.html', {})
166 response.add_post_render_callback(post1)
167 response.add_post_render_callback(post2)
169 # When the content is rendered, all the callbacks are invoked, too.
170 response.render()
171 self.assertEqual('First template\n', response.content)
172 self.assertEqual(post, ['post1','post2'])
175 def test_pickling(self):
176 # Create a template response. The context is
177 # known to be unpickleable (e.g., a function).
178 response = SimpleTemplateResponse('first/test.html', {
179 'value': 123,
180 'fn': datetime.now,
182 self.assertRaises(ContentNotRenderedError,
183 pickle.dumps, response)
185 # But if we render the response, we can pickle it.
186 response.render()
187 pickled_response = pickle.dumps(response)
188 unpickled_response = pickle.loads(pickled_response)
190 self.assertEqual(unpickled_response.content, response.content)
191 self.assertEqual(unpickled_response['content-type'], response['content-type'])
192 self.assertEqual(unpickled_response.status_code, response.status_code)
194 # ...and the unpickled reponse doesn't have the
195 # template-related attributes, so it can't be re-rendered
196 template_attrs = ('template_name', 'context_data', '_post_render_callbacks')
197 for attr in template_attrs:
198 self.assertFalse(hasattr(unpickled_response, attr))
200 # ...and requesting any of those attributes raises an exception
201 for attr in template_attrs:
202 with self.assertRaises(AttributeError):
203 getattr(unpickled_response, attr)
205 def test_repickling(self):
206 response = SimpleTemplateResponse('first/test.html', {
207 'value': 123,
208 'fn': datetime.now,
210 self.assertRaises(ContentNotRenderedError,
211 pickle.dumps, response)
213 response.render()
214 pickled_response = pickle.dumps(response)
215 unpickled_response = pickle.loads(pickled_response)
216 repickled_response = pickle.dumps(unpickled_response)
218 class TemplateResponseTest(BaseTemplateResponseTest):
220 def _response(self, template='foo', *args, **kwargs):
221 return TemplateResponse(self.factory.get('/'), Template(template),
222 *args, **kwargs)
224 def test_render(self):
225 response = self._response('{{ foo }}{{ processors }}').render()
226 self.assertEqual(response.content, 'yes')
228 def test_render_with_requestcontext(self):
229 response = self._response('{{ foo }}{{ processors }}',
230 {'foo': 'bar'}).render()
231 self.assertEqual(response.content, 'baryes')
233 def test_render_with_context(self):
234 response = self._response('{{ foo }}{{ processors }}',
235 Context({'foo': 'bar'})).render()
236 self.assertEqual(response.content, 'bar')
238 def test_kwargs(self):
239 response = self._response(content_type = 'application/json',
240 status=504)
241 self.assertEqual(response['content-type'], 'application/json')
242 self.assertEqual(response.status_code, 504)
244 def test_args(self):
245 response = TemplateResponse(self.factory.get('/'), '', {},
246 'application/json', 504)
247 self.assertEqual(response['content-type'], 'application/json')
248 self.assertEqual(response.status_code, 504)
250 def test_custom_app(self):
251 response = self._response('{{ foo }}', current_app="foobar")
253 rc = response.resolve_context(response.context_data)
255 self.assertEqual(rc.current_app, 'foobar')
257 def test_pickling(self):
258 # Create a template response. The context is
259 # known to be unpickleable (e.g., a function).
260 response = TemplateResponse(self.factory.get('/'),
261 'first/test.html', {
262 'value': 123,
263 'fn': datetime.now,
265 self.assertRaises(ContentNotRenderedError,
266 pickle.dumps, response)
268 # But if we render the response, we can pickle it.
269 response.render()
270 pickled_response = pickle.dumps(response)
271 unpickled_response = pickle.loads(pickled_response)
273 self.assertEqual(unpickled_response.content, response.content)
274 self.assertEqual(unpickled_response['content-type'], response['content-type'])
275 self.assertEqual(unpickled_response.status_code, response.status_code)
277 # ...and the unpickled reponse doesn't have the
278 # template-related attributes, so it can't be re-rendered
279 template_attrs = ('template_name', 'context_data',
280 '_post_render_callbacks', '_request', '_current_app')
281 for attr in template_attrs:
282 self.assertFalse(hasattr(unpickled_response, attr))
284 # ...and requesting any of those attributes raises an exception
285 for attr in template_attrs:
286 with self.assertRaises(AttributeError):
287 getattr(unpickled_response, attr)
289 def test_repickling(self):
290 response = SimpleTemplateResponse('first/test.html', {
291 'value': 123,
292 'fn': datetime.now,
294 self.assertRaises(ContentNotRenderedError,
295 pickle.dumps, response)
297 response.render()
298 pickled_response = pickle.dumps(response)
299 unpickled_response = pickle.loads(pickled_response)
300 repickled_response = pickle.dumps(unpickled_response)
303 class CustomURLConfTest(TestCase):
304 urls = 'regressiontests.templates.urls'
306 def setUp(self):
307 self.old_MIDDLEWARE_CLASSES = settings.MIDDLEWARE_CLASSES
308 settings.MIDDLEWARE_CLASSES = list(settings.MIDDLEWARE_CLASSES) + [
309 'regressiontests.templates.response.CustomURLConfMiddleware'
312 def tearDown(self):
313 settings.MIDDLEWARE_CLASSES = self.old_MIDDLEWARE_CLASSES
315 def test_custom_urlconf(self):
316 response = self.client.get('/template_response_view/')
317 self.assertEqual(response.status_code, 200)
318 self.assertContains(response, 'This is where you can find the snark: /snark/')
321 class CacheMiddlewareTest(TestCase):
322 urls = 'regressiontests.templates.alternate_urls'
324 def setUp(self):
325 self.old_MIDDLEWARE_CLASSES = settings.MIDDLEWARE_CLASSES
326 self.CACHE_MIDDLEWARE_SECONDS = settings.CACHE_MIDDLEWARE_SECONDS
328 settings.CACHE_MIDDLEWARE_SECONDS = 2.0
329 settings.MIDDLEWARE_CLASSES = list(settings.MIDDLEWARE_CLASSES) + [
330 'django.middleware.cache.FetchFromCacheMiddleware',
331 'django.middleware.cache.UpdateCacheMiddleware',
334 def tearDown(self):
335 settings.MIDDLEWARE_CLASSES = self.old_MIDDLEWARE_CLASSES
336 settings.CACHE_MIDDLEWARE_SECONDS = self.CACHE_MIDDLEWARE_SECONDS
338 def test_middleware_caching(self):
339 response = self.client.get('/template_response_view/')
340 self.assertEqual(response.status_code, 200)
342 time.sleep(1.0)
344 response2 = self.client.get('/template_response_view/')
345 self.assertEqual(response2.status_code, 200)
347 self.assertEqual(response.content, response2.content)
349 time.sleep(2.0)
351 # Let the cache expire and test again
352 response2 = self.client.get('/template_response_view/')
353 self.assertEqual(response2.status_code, 200)
355 self.assertNotEqual(response.content, response2.content)