mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Black 23.1.0 is released which, as the first release of the year, introduces the 2023 stable style. This incorporates most of last year's preview style. https://github.com/psf/black/releases/tag/23.1.0
		
			
				
	
	
		
			615 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			615 lines
		
	
	
		
			22 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| import time
 | |
| 
 | |
| from django.core.exceptions import ImproperlyConfigured
 | |
| from django.http import HttpResponse
 | |
| from django.test import RequestFactory, SimpleTestCase, override_settings
 | |
| from django.test.utils import require_jinja2
 | |
| from django.urls import resolve
 | |
| from django.views.generic import RedirectView, TemplateView, View
 | |
| 
 | |
| from . import views
 | |
| 
 | |
| 
 | |
| class SimpleView(View):
 | |
|     """
 | |
|     A simple view with a docstring.
 | |
|     """
 | |
| 
 | |
|     def get(self, request):
 | |
|         return HttpResponse("This is a simple view")
 | |
| 
 | |
| 
 | |
| class SimplePostView(SimpleView):
 | |
|     post = SimpleView.get
 | |
| 
 | |
| 
 | |
| class PostOnlyView(View):
 | |
|     def post(self, request):
 | |
|         return HttpResponse("This view only accepts POST")
 | |
| 
 | |
| 
 | |
| class CustomizableView(SimpleView):
 | |
|     parameter = {}
 | |
| 
 | |
| 
 | |
| def decorator(view):
 | |
|     view.is_decorated = True
 | |
|     return view
 | |
| 
 | |
| 
 | |
| class DecoratedDispatchView(SimpleView):
 | |
|     @decorator
 | |
|     def dispatch(self, request, *args, **kwargs):
 | |
|         return super().dispatch(request, *args, **kwargs)
 | |
| 
 | |
| 
 | |
| class AboutTemplateView(TemplateView):
 | |
|     def get(self, request):
 | |
|         return self.render_to_response({})
 | |
| 
 | |
|     def get_template_names(self):
 | |
|         return ["generic_views/about.html"]
 | |
| 
 | |
| 
 | |
| class AboutTemplateAttributeView(TemplateView):
 | |
|     template_name = "generic_views/about.html"
 | |
| 
 | |
|     def get(self, request):
 | |
|         return self.render_to_response(context={})
 | |
| 
 | |
| 
 | |
| class InstanceView(View):
 | |
|     def get(self, request):
 | |
|         return self
 | |
| 
 | |
| 
 | |
| class ViewTest(SimpleTestCase):
 | |
|     rf = RequestFactory()
 | |
| 
 | |
|     def _assert_simple(self, response):
 | |
|         self.assertEqual(response.status_code, 200)
 | |
|         self.assertEqual(response.content, b"This is a simple view")
 | |
| 
 | |
|     def test_no_init_kwargs(self):
 | |
|         """
 | |
|         A view can't be accidentally instantiated before deployment
 | |
|         """
 | |
|         msg = "This method is available only on the class, not on instances."
 | |
|         with self.assertRaisesMessage(AttributeError, msg):
 | |
|             SimpleView(key="value").as_view()
 | |
| 
 | |
|     def test_no_init_args(self):
 | |
|         """
 | |
|         A view can't be accidentally instantiated before deployment
 | |
|         """
 | |
|         msg = "as_view() takes 1 positional argument but 2 were given"
 | |
|         with self.assertRaisesMessage(TypeError, msg):
 | |
|             SimpleView.as_view("value")
 | |
| 
 | |
|     def test_pathological_http_method(self):
 | |
|         """
 | |
|         The edge case of an HTTP request that spoofs an existing method name is
 | |
|         caught.
 | |
|         """
 | |
|         self.assertEqual(
 | |
|             SimpleView.as_view()(
 | |
|                 self.rf.get("/", REQUEST_METHOD="DISPATCH")
 | |
|             ).status_code,
 | |
|             405,
 | |
|         )
 | |
| 
 | |
|     def test_get_only(self):
 | |
|         """
 | |
|         Test a view which only allows GET doesn't allow other methods.
 | |
|         """
 | |
|         self._assert_simple(SimpleView.as_view()(self.rf.get("/")))
 | |
|         self.assertEqual(SimpleView.as_view()(self.rf.post("/")).status_code, 405)
 | |
|         self.assertEqual(
 | |
|             SimpleView.as_view()(self.rf.get("/", REQUEST_METHOD="FAKE")).status_code,
 | |
|             405,
 | |
|         )
 | |
| 
 | |
|     def test_get_and_head(self):
 | |
|         """
 | |
|         Test a view which supplies a GET method also responds correctly to HEAD.
 | |
|         """
 | |
|         self._assert_simple(SimpleView.as_view()(self.rf.get("/")))
 | |
|         response = SimpleView.as_view()(self.rf.head("/"))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_setup_get_and_head(self):
 | |
|         view_instance = SimpleView()
 | |
|         self.assertFalse(hasattr(view_instance, "head"))
 | |
|         view_instance.setup(self.rf.get("/"))
 | |
|         self.assertTrue(hasattr(view_instance, "head"))
 | |
|         self.assertEqual(view_instance.head, view_instance.get)
 | |
| 
 | |
|     def test_head_no_get(self):
 | |
|         """
 | |
|         Test a view which supplies no GET method responds to HEAD with HTTP 405.
 | |
|         """
 | |
|         response = PostOnlyView.as_view()(self.rf.head("/"))
 | |
|         self.assertEqual(response.status_code, 405)
 | |
| 
 | |
|     def test_get_and_post(self):
 | |
|         """
 | |
|         Test a view which only allows both GET and POST.
 | |
|         """
 | |
|         self._assert_simple(SimplePostView.as_view()(self.rf.get("/")))
 | |
|         self._assert_simple(SimplePostView.as_view()(self.rf.post("/")))
 | |
|         self.assertEqual(
 | |
|             SimplePostView.as_view()(
 | |
|                 self.rf.get("/", REQUEST_METHOD="FAKE")
 | |
|             ).status_code,
 | |
|             405,
 | |
|         )
 | |
| 
 | |
|     def test_invalid_keyword_argument(self):
 | |
|         """
 | |
|         View arguments must be predefined on the class and can't
 | |
|         be named like an HTTP method.
 | |
|         """
 | |
|         msg = (
 | |
|             "The method name %s is not accepted as a keyword argument to "
 | |
|             "SimpleView()."
 | |
|         )
 | |
|         # Check each of the allowed method names
 | |
|         for method in SimpleView.http_method_names:
 | |
|             with self.assertRaisesMessage(TypeError, msg % method):
 | |
|                 SimpleView.as_view(**{method: "value"})
 | |
| 
 | |
|         # Check the case view argument is ok if predefined on the class...
 | |
|         CustomizableView.as_view(parameter="value")
 | |
|         # ...but raises errors otherwise.
 | |
|         msg = (
 | |
|             "CustomizableView() received an invalid keyword 'foobar'. "
 | |
|             "as_view only accepts arguments that are already attributes of "
 | |
|             "the class."
 | |
|         )
 | |
|         with self.assertRaisesMessage(TypeError, msg):
 | |
|             CustomizableView.as_view(foobar="value")
 | |
| 
 | |
|     def test_calling_more_than_once(self):
 | |
|         """
 | |
|         Test a view can only be called once.
 | |
|         """
 | |
|         request = self.rf.get("/")
 | |
|         view = InstanceView.as_view()
 | |
|         self.assertNotEqual(view(request), view(request))
 | |
| 
 | |
|     def test_class_attributes(self):
 | |
|         """
 | |
|         The callable returned from as_view() has proper special attributes.
 | |
|         """
 | |
|         cls = SimpleView
 | |
|         view = cls.as_view()
 | |
|         self.assertEqual(view.__doc__, cls.__doc__)
 | |
|         self.assertEqual(view.__name__, "view")
 | |
|         self.assertEqual(view.__module__, cls.__module__)
 | |
|         self.assertEqual(view.__qualname__, f"{cls.as_view.__qualname__}.<locals>.view")
 | |
|         self.assertEqual(view.__annotations__, cls.dispatch.__annotations__)
 | |
|         self.assertFalse(hasattr(view, "__wrapped__"))
 | |
| 
 | |
|     def test_dispatch_decoration(self):
 | |
|         """
 | |
|         Attributes set by decorators on the dispatch method
 | |
|         are also present on the closure.
 | |
|         """
 | |
|         self.assertTrue(DecoratedDispatchView.as_view().is_decorated)
 | |
| 
 | |
|     def test_options(self):
 | |
|         """
 | |
|         Views respond to HTTP OPTIONS requests with an Allow header
 | |
|         appropriate for the methods implemented by the view class.
 | |
|         """
 | |
|         request = self.rf.options("/")
 | |
|         view = SimpleView.as_view()
 | |
|         response = view(request)
 | |
|         self.assertEqual(200, response.status_code)
 | |
|         self.assertTrue(response.headers["Allow"])
 | |
| 
 | |
|     def test_options_for_get_view(self):
 | |
|         """
 | |
|         A view implementing GET allows GET and HEAD.
 | |
|         """
 | |
|         request = self.rf.options("/")
 | |
|         view = SimpleView.as_view()
 | |
|         response = view(request)
 | |
|         self._assert_allows(response, "GET", "HEAD")
 | |
| 
 | |
|     def test_options_for_get_and_post_view(self):
 | |
|         """
 | |
|         A view implementing GET and POST allows GET, HEAD, and POST.
 | |
|         """
 | |
|         request = self.rf.options("/")
 | |
|         view = SimplePostView.as_view()
 | |
|         response = view(request)
 | |
|         self._assert_allows(response, "GET", "HEAD", "POST")
 | |
| 
 | |
|     def test_options_for_post_view(self):
 | |
|         """
 | |
|         A view implementing POST allows POST.
 | |
|         """
 | |
|         request = self.rf.options("/")
 | |
|         view = PostOnlyView.as_view()
 | |
|         response = view(request)
 | |
|         self._assert_allows(response, "POST")
 | |
| 
 | |
|     def _assert_allows(self, response, *expected_methods):
 | |
|         "Assert allowed HTTP methods reported in the Allow response header"
 | |
|         response_allows = set(response.headers["Allow"].split(", "))
 | |
|         self.assertEqual(set(expected_methods + ("OPTIONS",)), response_allows)
 | |
| 
 | |
|     def test_args_kwargs_request_on_self(self):
 | |
|         """
 | |
|         Test a view only has args, kwargs & request once `as_view`
 | |
|         has been called.
 | |
|         """
 | |
|         bare_view = InstanceView()
 | |
|         view = InstanceView.as_view()(self.rf.get("/"))
 | |
|         for attribute in ("args", "kwargs", "request"):
 | |
|             self.assertNotIn(attribute, dir(bare_view))
 | |
|             self.assertIn(attribute, dir(view))
 | |
| 
 | |
|     def test_overridden_setup(self):
 | |
|         class SetAttributeMixin:
 | |
|             def setup(self, request, *args, **kwargs):
 | |
|                 self.attr = True
 | |
|                 super().setup(request, *args, **kwargs)
 | |
| 
 | |
|         class CheckSetupView(SetAttributeMixin, SimpleView):
 | |
|             def dispatch(self, request, *args, **kwargs):
 | |
|                 assert hasattr(self, "attr")
 | |
|                 return super().dispatch(request, *args, **kwargs)
 | |
| 
 | |
|         response = CheckSetupView.as_view()(self.rf.get("/"))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_not_calling_parent_setup_error(self):
 | |
|         class TestView(View):
 | |
|             def setup(self, request, *args, **kwargs):
 | |
|                 pass  # Not calling super().setup()
 | |
| 
 | |
|         msg = (
 | |
|             "TestView instance has no 'request' attribute. Did you override "
 | |
|             "setup() and forget to call super()?"
 | |
|         )
 | |
|         with self.assertRaisesMessage(AttributeError, msg):
 | |
|             TestView.as_view()(self.rf.get("/"))
 | |
| 
 | |
|     def test_setup_adds_args_kwargs_request(self):
 | |
|         request = self.rf.get("/")
 | |
|         args = ("arg 1", "arg 2")
 | |
|         kwargs = {"kwarg_1": 1, "kwarg_2": "year"}
 | |
| 
 | |
|         view = View()
 | |
|         view.setup(request, *args, **kwargs)
 | |
|         self.assertEqual(request, view.request)
 | |
|         self.assertEqual(args, view.args)
 | |
|         self.assertEqual(kwargs, view.kwargs)
 | |
| 
 | |
|     def test_direct_instantiation(self):
 | |
|         """
 | |
|         It should be possible to use the view by directly instantiating it
 | |
|         without going through .as_view() (#21564).
 | |
|         """
 | |
|         view = PostOnlyView()
 | |
|         response = view.dispatch(self.rf.head("/"))
 | |
|         self.assertEqual(response.status_code, 405)
 | |
| 
 | |
| 
 | |
| @override_settings(ROOT_URLCONF="generic_views.urls")
 | |
| class TemplateViewTest(SimpleTestCase):
 | |
|     rf = RequestFactory()
 | |
| 
 | |
|     def _assert_about(self, response):
 | |
|         response.render()
 | |
|         self.assertContains(response, "<h1>About</h1>")
 | |
| 
 | |
|     def test_get(self):
 | |
|         """
 | |
|         Test a view that simply renders a template on GET
 | |
|         """
 | |
|         self._assert_about(AboutTemplateView.as_view()(self.rf.get("/about/")))
 | |
| 
 | |
|     def test_head(self):
 | |
|         """
 | |
|         Test a TemplateView responds correctly to HEAD
 | |
|         """
 | |
|         response = AboutTemplateView.as_view()(self.rf.head("/about/"))
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|     def test_get_template_attribute(self):
 | |
|         """
 | |
|         Test a view that renders a template on GET with the template name as
 | |
|         an attribute on the class.
 | |
|         """
 | |
|         self._assert_about(AboutTemplateAttributeView.as_view()(self.rf.get("/about/")))
 | |
| 
 | |
|     def test_get_generic_template(self):
 | |
|         """
 | |
|         Test a completely generic view that renders a template on GET
 | |
|         with the template name as an argument at instantiation.
 | |
|         """
 | |
|         self._assert_about(
 | |
|             TemplateView.as_view(template_name="generic_views/about.html")(
 | |
|                 self.rf.get("/about/")
 | |
|             )
 | |
|         )
 | |
| 
 | |
|     def test_template_name_required(self):
 | |
|         """
 | |
|         A template view must provide a template name.
 | |
|         """
 | |
|         msg = (
 | |
|             "TemplateResponseMixin requires either a definition of "
 | |
|             "'template_name' or an implementation of 'get_template_names()'"
 | |
|         )
 | |
|         with self.assertRaisesMessage(ImproperlyConfigured, msg):
 | |
|             self.client.get("/template/no_template/")
 | |
| 
 | |
|     @require_jinja2
 | |
|     def test_template_engine(self):
 | |
|         """
 | |
|         A template view may provide a template engine.
 | |
|         """
 | |
|         request = self.rf.get("/using/")
 | |
|         view = TemplateView.as_view(template_name="generic_views/using.html")
 | |
|         self.assertEqual(view(request).render().content, b"DTL\n")
 | |
|         view = TemplateView.as_view(
 | |
|             template_name="generic_views/using.html", template_engine="django"
 | |
|         )
 | |
|         self.assertEqual(view(request).render().content, b"DTL\n")
 | |
|         view = TemplateView.as_view(
 | |
|             template_name="generic_views/using.html", template_engine="jinja2"
 | |
|         )
 | |
|         self.assertEqual(view(request).render().content, b"Jinja2\n")
 | |
| 
 | |
|     def test_template_params(self):
 | |
|         """
 | |
|         A generic template view passes kwargs as context.
 | |
|         """
 | |
|         response = self.client.get("/template/simple/bar/")
 | |
|         self.assertEqual(response.status_code, 200)
 | |
|         self.assertEqual(response.context["foo"], "bar")
 | |
|         self.assertIsInstance(response.context["view"], View)
 | |
| 
 | |
|     def test_extra_template_params(self):
 | |
|         """
 | |
|         A template view can be customized to return extra context.
 | |
|         """
 | |
|         response = self.client.get("/template/custom/bar/")
 | |
|         self.assertEqual(response.status_code, 200)
 | |
|         self.assertEqual(response.context["foo"], "bar")
 | |
|         self.assertEqual(response.context["key"], "value")
 | |
|         self.assertIsInstance(response.context["view"], View)
 | |
| 
 | |
|     def test_cached_views(self):
 | |
|         """
 | |
|         A template view can be cached
 | |
|         """
 | |
|         response = self.client.get("/template/cached/bar/")
 | |
|         self.assertEqual(response.status_code, 200)
 | |
| 
 | |
|         time.sleep(1.0)
 | |
| 
 | |
|         response2 = self.client.get("/template/cached/bar/")
 | |
|         self.assertEqual(response2.status_code, 200)
 | |
| 
 | |
|         self.assertEqual(response.content, response2.content)
 | |
| 
 | |
|         time.sleep(2.0)
 | |
| 
 | |
|         # Let the cache expire and test again
 | |
|         response2 = self.client.get("/template/cached/bar/")
 | |
|         self.assertEqual(response2.status_code, 200)
 | |
| 
 | |
|         self.assertNotEqual(response.content, response2.content)
 | |
| 
 | |
|     def test_content_type(self):
 | |
|         response = self.client.get("/template/content_type/")
 | |
|         self.assertEqual(response.headers["Content-Type"], "text/plain")
 | |
| 
 | |
|     def test_resolve_view(self):
 | |
|         match = resolve("/template/content_type/")
 | |
|         self.assertIs(match.func.view_class, TemplateView)
 | |
|         self.assertEqual(match.func.view_initkwargs["content_type"], "text/plain")
 | |
| 
 | |
|     def test_resolve_login_required_view(self):
 | |
|         match = resolve("/template/login_required/")
 | |
|         self.assertIs(match.func.view_class, TemplateView)
 | |
| 
 | |
|     def test_extra_context(self):
 | |
|         response = self.client.get("/template/extra_context/")
 | |
|         self.assertEqual(response.context["title"], "Title")
 | |
| 
 | |
| 
 | |
| @override_settings(ROOT_URLCONF="generic_views.urls")
 | |
| class RedirectViewTest(SimpleTestCase):
 | |
|     rf = RequestFactory()
 | |
| 
 | |
|     def test_no_url(self):
 | |
|         "Without any configuration, returns HTTP 410 GONE"
 | |
|         response = RedirectView.as_view()(self.rf.get("/foo/"))
 | |
|         self.assertEqual(response.status_code, 410)
 | |
| 
 | |
|     def test_default_redirect(self):
 | |
|         "Default is a temporary redirect"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.get("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_permanent_redirect(self):
 | |
|         "Permanent redirects are an option"
 | |
|         response = RedirectView.as_view(url="/bar/", permanent=True)(
 | |
|             self.rf.get("/foo/")
 | |
|         )
 | |
|         self.assertEqual(response.status_code, 301)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_temporary_redirect(self):
 | |
|         "Temporary redirects are an option"
 | |
|         response = RedirectView.as_view(url="/bar/", permanent=False)(
 | |
|             self.rf.get("/foo/")
 | |
|         )
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_include_args(self):
 | |
|         "GET arguments can be included in the redirected URL"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.get("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|         response = RedirectView.as_view(url="/bar/", query_string=True)(
 | |
|             self.rf.get("/foo/?pork=spam")
 | |
|         )
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/?pork=spam")
 | |
| 
 | |
|     def test_include_urlencoded_args(self):
 | |
|         "GET arguments can be URL-encoded when included in the redirected URL"
 | |
|         response = RedirectView.as_view(url="/bar/", query_string=True)(
 | |
|             self.rf.get("/foo/?unicode=%E2%9C%93")
 | |
|         )
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/?unicode=%E2%9C%93")
 | |
| 
 | |
|     def test_parameter_substitution(self):
 | |
|         "Redirection URLs can be parameterized"
 | |
|         response = RedirectView.as_view(url="/bar/%(object_id)d/")(
 | |
|             self.rf.get("/foo/42/"), object_id=42
 | |
|         )
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/42/")
 | |
| 
 | |
|     def test_named_url_pattern(self):
 | |
|         "Named pattern parameter should reverse to the matching pattern"
 | |
|         response = RedirectView.as_view(pattern_name="artist_detail")(
 | |
|             self.rf.get("/foo/"), pk=1
 | |
|         )
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.headers["Location"], "/detail/artist/1/")
 | |
| 
 | |
|     def test_named_url_pattern_using_args(self):
 | |
|         response = RedirectView.as_view(pattern_name="artist_detail")(
 | |
|             self.rf.get("/foo/"), 1
 | |
|         )
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.headers["Location"], "/detail/artist/1/")
 | |
| 
 | |
|     def test_redirect_POST(self):
 | |
|         "Default is a temporary redirect"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.post("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_redirect_HEAD(self):
 | |
|         "Default is a temporary redirect"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.head("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_redirect_OPTIONS(self):
 | |
|         "Default is a temporary redirect"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.options("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_redirect_PUT(self):
 | |
|         "Default is a temporary redirect"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.put("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_redirect_PATCH(self):
 | |
|         "Default is a temporary redirect"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.patch("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_redirect_DELETE(self):
 | |
|         "Default is a temporary redirect"
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.delete("/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
|         self.assertEqual(response.url, "/bar/")
 | |
| 
 | |
|     def test_redirect_when_meta_contains_no_query_string(self):
 | |
|         "regression for #16705"
 | |
|         # we can't use self.rf.get because it always sets QUERY_STRING
 | |
|         response = RedirectView.as_view(url="/bar/")(self.rf.request(PATH_INFO="/foo/"))
 | |
|         self.assertEqual(response.status_code, 302)
 | |
| 
 | |
|     def test_direct_instantiation(self):
 | |
|         """
 | |
|         It should be possible to use the view without going through .as_view()
 | |
|         (#21564).
 | |
|         """
 | |
|         view = RedirectView()
 | |
|         response = view.dispatch(self.rf.head("/foo/"))
 | |
|         self.assertEqual(response.status_code, 410)
 | |
| 
 | |
| 
 | |
| class GetContextDataTest(SimpleTestCase):
 | |
|     def test_get_context_data_super(self):
 | |
|         test_view = views.CustomContextView()
 | |
|         context = test_view.get_context_data(kwarg_test="kwarg_value")
 | |
| 
 | |
|         # the test_name key is inserted by the test classes parent
 | |
|         self.assertIn("test_name", context)
 | |
|         self.assertEqual(context["kwarg_test"], "kwarg_value")
 | |
|         self.assertEqual(context["custom_key"], "custom_value")
 | |
| 
 | |
|         # test that kwarg overrides values assigned higher up
 | |
|         context = test_view.get_context_data(test_name="test_value")
 | |
|         self.assertEqual(context["test_name"], "test_value")
 | |
| 
 | |
|     def test_object_at_custom_name_in_context_data(self):
 | |
|         # Checks 'pony' key presence in dict returned by get_context_date
 | |
|         test_view = views.CustomSingleObjectView()
 | |
|         test_view.context_object_name = "pony"
 | |
|         context = test_view.get_context_data()
 | |
|         self.assertEqual(context["pony"], test_view.object)
 | |
| 
 | |
|     def test_object_in_get_context_data(self):
 | |
|         # Checks 'object' key presence in dict returned by get_context_date #20234
 | |
|         test_view = views.CustomSingleObjectView()
 | |
|         context = test_view.get_context_data()
 | |
|         self.assertEqual(context["object"], test_view.object)
 | |
| 
 | |
| 
 | |
| class UseMultipleObjectMixinTest(SimpleTestCase):
 | |
|     rf = RequestFactory()
 | |
| 
 | |
|     def test_use_queryset_from_view(self):
 | |
|         test_view = views.CustomMultipleObjectMixinView()
 | |
|         test_view.get(self.rf.get("/"))
 | |
|         # Don't pass queryset as argument
 | |
|         context = test_view.get_context_data()
 | |
|         self.assertEqual(context["object_list"], test_view.queryset)
 | |
| 
 | |
|     def test_overwrite_queryset(self):
 | |
|         test_view = views.CustomMultipleObjectMixinView()
 | |
|         test_view.get(self.rf.get("/"))
 | |
|         queryset = [{"name": "Lennon"}, {"name": "Ono"}]
 | |
|         self.assertNotEqual(test_view.queryset, queryset)
 | |
|         # Overwrite the view's queryset with queryset from kwarg
 | |
|         context = test_view.get_context_data(object_list=queryset)
 | |
|         self.assertEqual(context["object_list"], queryset)
 | |
| 
 | |
| 
 | |
| class SingleObjectTemplateResponseMixinTest(SimpleTestCase):
 | |
|     def test_template_mixin_without_template(self):
 | |
|         """
 | |
|         We want to makes sure that if you use a template mixin, but forget the
 | |
|         template, it still tells you it's ImproperlyConfigured instead of
 | |
|         TemplateDoesNotExist.
 | |
|         """
 | |
|         view = views.TemplateResponseWithoutTemplate()
 | |
|         msg = (
 | |
|             "TemplateResponseMixin requires either a definition of "
 | |
|             "'template_name' or an implementation of 'get_template_names()'"
 | |
|         )
 | |
|         with self.assertRaisesMessage(ImproperlyConfigured, msg):
 | |
|             view.get_template_names()
 |