"""Cache Utility Test file.""" import hashlib import pickle from unittest.mock import patch from redis import RedisError from moneyhub.constants.error import REDIS_ERROR from moneyhub.utils.cache import cache @patch('moneyhub.utils.cache.redis_client') def test_cache_miss(mock_redis_client): """Test a cache miss with redis.get and redis.set methods.""" @cache(ttl=123) def _sample_func(): return expected expected = _sample_func.__qualname__ + '_' + 'hello' mock_cache_key = _sample_func.__qualname__ + '_' + hashlib.sha256(repr( {'func_name': _sample_func.__qualname__, 'args': (), 'kwargs': {}}).encode()).hexdigest() mock_redis_client.return_value.get.return_value = None result = _sample_func() assert result == expected mock_redis_client().get.assert_called_once_with(mock_cache_key) mock_redis_client().set.assert_called_once_with(mock_cache_key, pickle.dumps(expected, protocol=pickle.HIGHEST_PROTOCOL), ex=123) # noqa:E501 @patch('moneyhub.utils.cache.redis_client') def test_cache_hit(mock_redis_client): """Test a cache hit with redis.get method.""" @cache(ttl=123) def _sample_func(): raise Exception('This should not happen') expected = _sample_func.__qualname__ + '_' + 'hello' func_hash = _sample_func.__qualname__ + '_' + hashlib.sha256(repr( {'func_name': _sample_func.__qualname__, 'args': (), 'kwargs': {}}).encode()).hexdigest() mock_redis_client.return_value.get.return_value = pickle.dumps(expected) result = _sample_func() assert result == expected mock_redis_client().get.assert_called_once_with(func_hash) mock_redis_client().set.assert_not_called() @patch('moneyhub.utils.cache.logger') @patch('moneyhub.utils.cache.sentry_sdk') @patch('moneyhub.utils.cache.redis_client') def test_cache_connection_errors(mock_redis_client, mock_sentry, mock_logger): """Test a cache error when connecting to redis.get method.""" @cache(ttl=123) def _sample_func(): return expected expected = _sample_func.__qualname__ + '_' + 'foo' func_hash = _sample_func.__qualname__ + '_' + hashlib.sha256(repr( {'func_name': _sample_func.__qualname__, 'args': (), 'kwargs': {}}).encode()).hexdigest() fake_error = RedisError('Fake error') mock_redis_client.return_value.get.side_effect = fake_error result = _sample_func() mock_redis_client().get.assert_called_once_with(func_hash) mock_redis_client().set.assert_not_called() mock_sentry.capture_exception.assert_called_with(fake_error) mock_logger.exception.assert_called_with(f'{REDIS_ERROR} {fake_error}') assert result == expected