From f2b97fbf065a823423e8ee2d1841b68ab22c604a Mon Sep 17 00:00:00 2001 From: Ben Lomax Date: Sun, 8 Jan 2023 19:40:22 +0000 Subject: [PATCH] Moved cache decorators tests into decorators/test_cache.py. --- tests/decorators/test_cache.py | 108 +++++++++++++++++++++++++++++++++ tests/decorators/tests.py | 102 +------------------------------ 2 files changed, 109 insertions(+), 101 deletions(-) create mode 100644 tests/decorators/test_cache.py diff --git a/tests/decorators/test_cache.py b/tests/decorators/test_cache.py new file mode 100644 index 0000000000..934a69e3fd --- /dev/null +++ b/tests/decorators/test_cache.py @@ -0,0 +1,108 @@ +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") + + +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) diff --git a/tests/decorators/tests.py b/tests/decorators/tests.py index 70b03f6a3a..48f24503d0 100644 --- a/tests/decorators/tests.py +++ b/tests/decorators/tests.py @@ -1,5 +1,5 @@ from functools import update_wrapper, wraps -from unittest import TestCase, mock +from unittest import TestCase from django.contrib.admin.views.decorators import staff_member_required from django.contrib.auth.decorators import ( @@ -123,15 +123,6 @@ class DecoratorsTest(TestCase): self.assertEqual(response, ["test2", "test1"]) - 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") - def test_require_safe_accepts_only_safe_methods(self): """ Test for the require_safe decorator. @@ -523,94 +514,3 @@ class XFrameOptionsDecoratorsTests(TestCase): # the middleware's functionality, let's make sure it actually works... r = XFrameOptionsMiddleware(a_view)(req) self.assertIsNone(r.get("X-Frame-Options", None)) - - -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 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) - - -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")