django/tests/decorators/test_cache.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

128 lines
4.3 KiB
Python
Raw Normal View History

from unittest import mock
from django.http import HttpRequest, HttpResponse
from django.test import SimpleTestCase
from django.utils.decorators import method_decorator
from django.views.decorators.cache import cache_control, cache_page, never_cache
class HttpRequestProxy:
def __init__(self, request):
self._request = request
def __getattr__(self, attr):
"""Proxy to the underlying HttpRequest object."""
return getattr(self._request, attr)
class CacheControlDecoratorTest(SimpleTestCase):
def test_cache_control_decorator_http_request(self):
class MyClass:
@cache_control(a="b")
def a_view(self, request):
return HttpResponse()
msg = (
"cache_control didn't receive an HttpRequest. If you are "
"decorating a classmethod, be sure to use @method_decorator."
)
request = HttpRequest()
with self.assertRaisesMessage(TypeError, msg):
MyClass().a_view(request)
with self.assertRaisesMessage(TypeError, msg):
MyClass().a_view(HttpRequestProxy(request))
def test_cache_control_decorator_http_request_proxy(self):
class MyClass:
@method_decorator(cache_control(a="b"))
def a_view(self, request):
return HttpResponse()
request = HttpRequest()
response = MyClass().a_view(HttpRequestProxy(request))
self.assertEqual(response.headers["Cache-Control"], "a=b")
def test_cache_control_empty_decorator(self):
@cache_control()
def a_view(request):
return HttpResponse()
response = a_view(HttpRequest())
self.assertEqual(response.get("Cache-Control"), "")
def test_cache_control_full_decorator(self):
@cache_control(max_age=123, private=True, public=True, custom=456)
def a_view(request):
return HttpResponse()
response = a_view(HttpRequest())
cache_control_items = response.get("Cache-Control").split(", ")
self.assertEqual(
set(cache_control_items), {"max-age=123", "private", "public", "custom=456"}
)
class CachePageDecoratorTest(SimpleTestCase):
def test_cache_page(self):
def my_view(request):
return "response"
my_view_cached = cache_page(123)(my_view)
self.assertEqual(my_view_cached(HttpRequest()), "response")
my_view_cached2 = cache_page(123, key_prefix="test")(my_view)
self.assertEqual(my_view_cached2(HttpRequest()), "response")
class NeverCacheDecoratorTest(SimpleTestCase):
@mock.patch("time.time")
def test_never_cache_decorator_headers(self, mocked_time):
@never_cache
def a_view(request):
return HttpResponse()
mocked_time.return_value = 1167616461.0
response = a_view(HttpRequest())
self.assertEqual(
response.headers["Expires"],
"Mon, 01 Jan 2007 01:54:21 GMT",
)
self.assertEqual(
response.headers["Cache-Control"],
"max-age=0, no-cache, no-store, must-revalidate, private",
)
def test_never_cache_decorator_expires_not_overridden(self):
@never_cache
def a_view(request):
return HttpResponse(headers={"Expires": "tomorrow"})
response = a_view(HttpRequest())
self.assertEqual(response.headers["Expires"], "tomorrow")
def test_never_cache_decorator_http_request(self):
class MyClass:
@never_cache
def a_view(self, request):
return HttpResponse()
request = HttpRequest()
msg = (
"never_cache didn't receive an HttpRequest. If you are decorating "
"a classmethod, be sure to use @method_decorator."
)
with self.assertRaisesMessage(TypeError, msg):
MyClass().a_view(request)
with self.assertRaisesMessage(TypeError, msg):
MyClass().a_view(HttpRequestProxy(request))
def test_never_cache_decorator_http_request_proxy(self):
class MyClass:
@method_decorator(never_cache)
def a_view(self, request):
return HttpResponse()
request = HttpRequest()
response = MyClass().a_view(HttpRequestProxy(request))
self.assertIn("Cache-Control", response.headers)
self.assertIn("Expires", response.headers)