"""Tests for core cache utilities""" from apps.core.cache import ( CacheManager, _build_cache_key, cache_method, cache_result, ) from django.core.cache import cache from django.test import TestCase class CacheResultDecoratorTest(TestCase): """Tests for @cache_result decorator""" def setUp(self): cache.clear() self.call_count = 0 def test_result_is_cached(self): """Test that function result is cached""" @cache_result(timeout=60, key_prefix="test") def expensive_function(x): self.call_count += 1 return x * 2 # First call - should execute result1 = expensive_function(5) self.assertEqual(result1, 10) self.assertEqual(self.call_count, 1) # Second call - should return cached result result2 = expensive_function(5) self.assertEqual(result2, 10) self.assertEqual(self.call_count, 1) # Still 1, not called again def test_different_args_not_cached(self): """Test that different arguments create different cache entries""" @cache_result(timeout=60, key_prefix="test") def expensive_function(x): self.call_count += 1 return x * 2 result1 = expensive_function(5) result2 = expensive_function(10) self.assertEqual(result1, 10) self.assertEqual(result2, 20) self.assertEqual(self.call_count, 2) def test_kwargs_included_in_cache_key(self): """Test that kwargs are included in cache key""" @cache_result(timeout=60, key_prefix="test") def expensive_function(x, multiplier=2): self.call_count += 1 return x * multiplier result1 = expensive_function(5, multiplier=2) result2 = expensive_function(5, multiplier=3) self.assertEqual(result1, 10) self.assertEqual(result2, 15) self.assertEqual(self.call_count, 2) class CacheMethodDecoratorTest(TestCase): """Tests for @cache_method decorator""" def setUp(self): cache.clear() def test_classmethod_caching(self): """Test caching works with classmethod""" call_count = {"value": 0} class MyService: @classmethod @cache_method(timeout=60, key_prefix="service") def get_data(cls, item_id): call_count["value"] += 1 return {"id": item_id, "data": "test"} # First call result1 = MyService.get_data(1) self.assertEqual(result1["id"], 1) self.assertEqual(call_count["value"], 1) # Second call - should be cached result2 = MyService.get_data(1) self.assertEqual(result2["id"], 1) self.assertEqual(call_count["value"], 1) # Different argument result3 = MyService.get_data(2) self.assertEqual(result3["id"], 2) self.assertEqual(call_count["value"], 2) class CacheManagerTest(TestCase): """Tests for CacheManager""" def setUp(self): cache.clear() self.manager = CacheManager("test_prefix") def test_set_and_get(self): """Test basic set and get operations""" self.manager.set("key1", "value1", timeout=60) result = self.manager.get("key1") self.assertEqual(result, "value1") def test_get_default(self): """Test get returns default for missing key""" result = self.manager.get("nonexistent", default="default_value") self.assertEqual(result, "default_value") def test_delete(self): """Test delete operation""" self.manager.set("key1", "value1") self.manager.delete("key1") result = self.manager.get("key1") self.assertIsNone(result) def test_get_or_set(self): """Test get_or_set operation""" call_count = {"value": 0} def compute_value(): call_count["value"] += 1 return "computed" # First call - should compute result1 = self.manager.get_or_set("key1", compute_value) self.assertEqual(result1, "computed") self.assertEqual(call_count["value"], 1) # Second call - should return cached result2 = self.manager.get_or_set("key1", compute_value) self.assertEqual(result2, "computed") self.assertEqual(call_count["value"], 1) def test_prefix_applied(self): """Test that prefix is applied to keys""" self.manager.set("mykey", "myvalue") # Direct cache access should use prefixed key direct_result = cache.get("test_prefix:mykey") self.assertEqual(direct_result, "myvalue") class BuildCacheKeyTest(TestCase): """Tests for _build_cache_key function""" def test_key_includes_function_name(self): """Test cache key includes function name""" def my_function(): pass key = _build_cache_key(my_function, "", (), {}) self.assertIn("my_function", key) def test_key_includes_prefix(self): """Test cache key includes prefix""" def my_function(): pass key = _build_cache_key(my_function, "myprefix", (), {}) self.assertTrue(key.startswith("myprefix:")) def test_different_args_different_keys(self): """Test different arguments produce different keys""" def my_function(): pass key1 = _build_cache_key(my_function, "", (1, 2), {}) key2 = _build_cache_key(my_function, "", (1, 3), {}) self.assertNotEqual(key1, key2) def test_different_kwargs_different_keys(self): """Test different kwargs produce different keys""" def my_function(): pass key1 = _build_cache_key(my_function, "", (), {"a": 1}) key2 = _build_cache_key(my_function, "", (), {"a": 2}) self.assertNotEqual(key1, key2)