Skip to content

Commit

Permalink
Include support for anonymous Users.
Browse files Browse the repository at this point in the history
  • Loading branch information
manstis committed Dec 6, 2023
1 parent cb0de0f commit f84f2bd
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 18 deletions.
5 changes: 5 additions & 0 deletions ansible_wisdom/main/cache/cache_per_user.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
from functools import wraps

from django.contrib.auth.models import AnonymousUser
from django.views.decorators.cache import cache_page


def cache_per_user(timeout):
def decorator(view_func):
@wraps(view_func)
def wrapped_view(request, *args, **kwargs):
user = request.user
if isinstance(user, AnonymousUser):
return view_func(request, *args, **kwargs)

user_uuid = request.user.uuid
return cache_page(timeout, key_prefix=f"_user_{user_uuid}_")(view_func)(
request, *args, **kwargs
Expand Down
54 changes: 36 additions & 18 deletions ansible_wisdom/main/tests/test_cache_per_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,54 @@ class TestView(View):
def get(self, request, *args, **kwargs):
return TestCachePerUser.TestResponse()

def test_cache_per_user(self):
view = TestCachePerUser.TestView()
@staticmethod
def mock_request(user_uuid=None):
"""
Some nasty hackery to avoid Django handling the (Test) View invocation.
Django ordinarily handles caching as part of it's URL lookup, dispatch
and response mechanism. We however don't have a _real_ route mapping
to this (Test) View.
:param user_uuid: User UUID for User. If None, no User will be associated with the Request
:return:
"""
request = Request(HttpRequest())
request.method = "GET"
request.META["SERVER_NAME"] = "localhost"
request.META["SERVER_PORT"] = 8080

def mock_user_request(user_uuid):
"""
Some nasty hackery to avoid Django handling the (Test) View invocation.
Django ordinarily handles caching as part of it's URL lookup, dispatch
and response mechanism. We however don't have a _real_ route mapping
to this (Test) View.
:param user_uuid:
:return:
"""
request = Request(HttpRequest())
request.method = "GET"
request.META["SERVER_NAME"] = "localhost"
request.META["SERVER_PORT"] = 8080
if user_uuid:
user = Mock()
user.uuid = user_uuid
request._user = user
return request

return request

def test_cache_per_authenticated_user(self):
view = TestCachePerUser.TestView()

# Check caching for user1
request_user1 = mock_user_request("uuid1")
request_user1 = TestCachePerUser.mock_request("uuid1")
response_user1 = view.get(request_user1).render().content
self.assertEqual(view.get(request_user1).render().content, response_user1)

time.sleep(1)

# Check caching for user2
request_user2 = mock_user_request("uuid2")
request_user2 = TestCachePerUser.mock_request("uuid2")
response_user2 = view.get(request_user2).render().content
self.assertEqual(view.get(request_user2).render().content, response_user2)
self.assertNotEqual(response_user1, response_user2)

def test_cache_per_unauthenticated_user(self):
view = TestCachePerUser.TestView()

# Check no caching for anonymous requests
request1 = TestCachePerUser.mock_request()
response1 = view.get(request1).render().content
self.assertIsNotNone(response1)

time.sleep(1)

request2 = TestCachePerUser.mock_request()
response2 = view.get(request2).render().content
self.assertNotEqual(response1, response2)

0 comments on commit f84f2bd

Please sign in to comment.