PageRenderTime 363ms CodeModel.GetById 90ms app.highlight 110ms RepoModel.GetById 121ms app.codeStats 0ms

/tests/regressiontests/generic_views/base.py

https://code.google.com/p/mango-py/
Python | 293 lines | 257 code | 24 blank | 12 comment | 3 complexity | 74ba569ae5c2065a24761afea8485036 MD5 | raw file
  1import time
  2import unittest
  3
  4from django.core.exceptions import ImproperlyConfigured
  5from django.http import HttpResponse
  6from django.test import TestCase, RequestFactory
  7from django.utils import simplejson
  8from django.views.generic import View, TemplateView, RedirectView
  9
 10
 11class SimpleView(View):
 12    """
 13    A simple view with a docstring.
 14    """
 15    def get(self, request):
 16        return HttpResponse('This is a simple view')
 17
 18
 19class SimplePostView(SimpleView):
 20    post = SimpleView.get
 21
 22
 23class CustomizableView(SimpleView):
 24    parameter = {}
 25
 26def decorator(view):
 27    view.is_decorated = True
 28    return view
 29
 30
 31class DecoratedDispatchView(SimpleView):
 32
 33    @decorator
 34    def dispatch(self, request, *args, **kwargs):
 35        return super(DecoratedDispatchView, self).dispatch(request, *args, **kwargs)
 36
 37
 38class AboutTemplateView(TemplateView):
 39    def get(self, request):
 40        return self.render_to_response({})
 41
 42    def get_template_names(self):
 43        return ['generic_views/about.html']
 44
 45
 46class AboutTemplateAttributeView(TemplateView):
 47    template_name = 'generic_views/about.html'
 48
 49    def get(self, request):
 50        return self.render_to_response(context={})
 51
 52
 53class InstanceView(View):
 54
 55    def get(self, request):
 56        return self
 57
 58
 59class ViewTest(unittest.TestCase):
 60    rf = RequestFactory()
 61
 62    def _assert_simple(self, response):
 63        self.assertEqual(response.status_code, 200)
 64        self.assertEqual(response.content, 'This is a simple view')
 65
 66    def test_no_init_kwargs(self):
 67        """
 68        Test that a view can't be accidentally instantiated before deployment
 69        """
 70        try:
 71            view = SimpleView(key='value').as_view()
 72            self.fail('Should not be able to instantiate a view')
 73        except AttributeError:
 74            pass
 75
 76    def test_no_init_args(self):
 77        """
 78        Test that a view can't be accidentally instantiated before deployment
 79        """
 80        try:
 81            view = SimpleView.as_view('value')
 82            self.fail('Should not be able to use non-keyword arguments instantiating a view')
 83        except TypeError:
 84            pass
 85
 86    def test_pathological_http_method(self):
 87        """
 88        The edge case of a http request that spoofs an existing method name is caught.
 89        """
 90        self.assertEqual(SimpleView.as_view()(
 91            self.rf.get('/', REQUEST_METHOD='DISPATCH')
 92        ).status_code, 405)
 93
 94    def test_get_only(self):
 95        """
 96        Test a view which only allows GET doesn't allow other methods.
 97        """
 98        self._assert_simple(SimpleView.as_view()(self.rf.get('/')))
 99        self.assertEqual(SimpleView.as_view()(self.rf.post('/')).status_code, 405)
100        self.assertEqual(SimpleView.as_view()(
101            self.rf.get('/', REQUEST_METHOD='FAKE')
102        ).status_code, 405)
103
104    def test_get_and_post(self):
105        """
106        Test a view which only allows both GET and POST.
107        """
108        self._assert_simple(SimplePostView.as_view()(self.rf.get('/')))
109        self._assert_simple(SimplePostView.as_view()(self.rf.post('/')))
110        self.assertEqual(SimplePostView.as_view()(
111            self.rf.get('/', REQUEST_METHOD='FAKE')
112        ).status_code, 405)
113
114    def test_invalid_keyword_argument(self):
115        """
116        Test that view arguments must be predefined on the class and can't
117        be named like a HTTP method.
118        """
119        # Check each of the allowed method names
120        for method in SimpleView.http_method_names:
121            kwargs = dict(((method, "value"),))
122            self.assertRaises(TypeError, SimpleView.as_view, **kwargs)
123
124        # Check the case view argument is ok if predefined on the class...
125        CustomizableView.as_view(parameter="value")
126        # ...but raises errors otherwise.
127        self.assertRaises(TypeError, CustomizableView.as_view, foobar="value")
128
129    def test_calling_more_than_once(self):
130        """
131        Test a view can only be called once.
132        """
133        request = self.rf.get('/')
134        view = InstanceView.as_view()
135        self.assertNotEqual(view(request), view(request))
136
137    def test_class_attributes(self):
138        """
139        Test that the callable returned from as_view() has proper
140        docstring, name and module.
141        """
142        self.assertEqual(SimpleView.__doc__, SimpleView.as_view().__doc__)
143        self.assertEqual(SimpleView.__name__, SimpleView.as_view().__name__)
144        self.assertEqual(SimpleView.__module__, SimpleView.as_view().__module__)
145
146    def test_dispatch_decoration(self):
147        """
148        Test that attributes set by decorators on the dispatch method
149        are also present on the closure.
150        """
151        self.assertTrue(DecoratedDispatchView.as_view().is_decorated)
152
153
154class TemplateViewTest(TestCase):
155    urls = 'regressiontests.generic_views.urls'
156
157    rf = RequestFactory()
158
159    def _assert_about(self, response):
160        response.render()
161        self.assertEqual(response.status_code, 200)
162        self.assertContains(response, '<h1>About</h1>')
163
164    def test_get(self):
165        """
166        Test a view that simply renders a template on GET
167        """
168        self._assert_about(AboutTemplateView.as_view()(self.rf.get('/about/')))
169
170    def test_get_template_attribute(self):
171        """
172        Test a view that renders a template on GET with the template name as
173        an attribute on the class.
174        """
175        self._assert_about(AboutTemplateAttributeView.as_view()(self.rf.get('/about/')))
176
177    def test_get_generic_template(self):
178        """
179        Test a completely generic view that renders a template on GET
180        with the template name as an argument at instantiation.
181        """
182        self._assert_about(TemplateView.as_view(template_name='generic_views/about.html')(self.rf.get('/about/')))
183
184    def test_template_name_required(self):
185        """
186        A template view must provide a template name
187        """
188        self.assertRaises(ImproperlyConfigured, self.client.get, '/template/no_template/')
189
190    def test_template_params(self):
191        """
192        A generic template view passes kwargs as context.
193        """
194        response = self.client.get('/template/simple/bar/')
195        self.assertEqual(response.status_code, 200)
196        self.assertEqual(response.context['params'], {'foo': 'bar'})
197
198    def test_extra_template_params(self):
199        """
200        A template view can be customized to return extra context.
201        """
202        response = self.client.get('/template/custom/bar/')
203        self.assertEqual(response.status_code, 200)
204        self.assertEqual(response.context['params'], {'foo': 'bar'})
205        self.assertEqual(response.context['key'], 'value')
206
207    def test_cached_views(self):
208        """
209        A template view can be cached
210        """
211        response = self.client.get('/template/cached/bar/')
212        self.assertEqual(response.status_code, 200)
213
214        time.sleep(1.0)
215
216        response2 = self.client.get('/template/cached/bar/')
217        self.assertEqual(response2.status_code, 200)
218
219        self.assertEqual(response.content, response2.content)
220
221        time.sleep(2.0)
222
223        # Let the cache expire and test again
224        response2 = self.client.get('/template/cached/bar/')
225        self.assertEqual(response2.status_code, 200)
226
227        self.assertNotEqual(response.content, response2.content)
228
229class RedirectViewTest(unittest.TestCase):
230    rf = RequestFactory()
231
232    def test_no_url(self):
233        "Without any configuration, returns HTTP 410 GONE"
234        response = RedirectView.as_view()(self.rf.get('/foo/'))
235        self.assertEqual(response.status_code, 410)
236
237    def test_permanaent_redirect(self):
238        "Default is a permanent redirect"
239        response = RedirectView.as_view(url='/bar/')(self.rf.get('/foo/'))
240        self.assertEqual(response.status_code, 301)
241        self.assertEqual(response['Location'], '/bar/')
242
243    def test_temporary_redirect(self):
244        "Permanent redirects are an option"
245        response = RedirectView.as_view(url='/bar/', permanent=False)(self.rf.get('/foo/'))
246        self.assertEqual(response.status_code, 302)
247        self.assertEqual(response['Location'], '/bar/')
248
249    def test_include_args(self):
250        "GET arguments can be included in the redirected URL"
251        response = RedirectView.as_view(url='/bar/')(self.rf.get('/foo/'))
252        self.assertEqual(response.status_code, 301)
253        self.assertEqual(response['Location'], '/bar/')
254
255        response = RedirectView.as_view(url='/bar/', query_string=True)(self.rf.get('/foo/?pork=spam'))
256        self.assertEqual(response.status_code, 301)
257        self.assertEqual(response['Location'], '/bar/?pork=spam')
258
259    def test_parameter_substitution(self):
260        "Redirection URLs can be parameterized"
261        response = RedirectView.as_view(url='/bar/%(object_id)d/')(self.rf.get('/foo/42/'), object_id=42)
262        self.assertEqual(response.status_code, 301)
263        self.assertEqual(response['Location'], '/bar/42/')
264
265    def test_redirect_POST(self):
266        "Default is a permanent redirect"
267        response = RedirectView.as_view(url='/bar/')(self.rf.post('/foo/'))
268        self.assertEqual(response.status_code, 301)
269        self.assertEqual(response['Location'], '/bar/')
270
271    def test_redirect_HEAD(self):
272        "Default is a permanent redirect"
273        response = RedirectView.as_view(url='/bar/')(self.rf.head('/foo/'))
274        self.assertEqual(response.status_code, 301)
275        self.assertEqual(response['Location'], '/bar/')
276
277    def test_redirect_OPTIONS(self):
278        "Default is a permanent redirect"
279        response = RedirectView.as_view(url='/bar/')(self.rf.options('/foo/'))
280        self.assertEqual(response.status_code, 301)
281        self.assertEqual(response['Location'], '/bar/')
282
283    def test_redirect_PUT(self):
284        "Default is a permanent redirect"
285        response = RedirectView.as_view(url='/bar/')(self.rf.put('/foo/'))
286        self.assertEqual(response.status_code, 301)
287        self.assertEqual(response['Location'], '/bar/')
288
289    def test_redirect_DELETE(self):
290        "Default is a permanent redirect"
291        response = RedirectView.as_view(url='/bar/')(self.rf.delete('/foo/'))
292        self.assertEqual(response.status_code, 301)
293        self.assertEqual(response['Location'], '/bar/')