mirror of
https://github.com/ChuckBuilds/LEDMatrix.git
synced 2026-08-01 08:48:05 +00:00
fix(testing): add MockCacheManager.get_cached_data_with_strategy/save_cache
ledmatrix-leaderboard's data_fetcher.py calls these two real-CacheManager methods (src/cache_manager.py:313,817), but MockCacheManager had neither -- update() always hit an AttributeError, caught by a broad except and logged, so the harness rendered an empty-but-green leaderboard on every test run without ever exercising real standings data. Both mocks delegate to the existing get()/set() -- a mock doesn't need the real strategy's per-data-type max_age/market-hours timing, plugins under test just need the methods to exist and round-trip whatever was cached.
This commit is contained in:
@@ -71,6 +71,7 @@ class MockCacheManager:
|
|||||||
self.get_calls = []
|
self.get_calls = []
|
||||||
self.set_calls = []
|
self.set_calls = []
|
||||||
self.delete_calls = []
|
self.delete_calls = []
|
||||||
|
self.get_cached_data_with_strategy_calls = []
|
||||||
# Real temp dir for plugins that write/read files under cache_dir.
|
# Real temp dir for plugins that write/read files under cache_dir.
|
||||||
# Registered for cleanup so each mock instance doesn't leak a tmp dir.
|
# Registered for cleanup so each mock instance doesn't leak a tmp dir.
|
||||||
self.cache_dir = tempfile.mkdtemp(prefix="ledmatrix-mock-cache-")
|
self.cache_dir = tempfile.mkdtemp(prefix="ledmatrix-mock-cache-")
|
||||||
@@ -108,6 +109,24 @@ class MockCacheManager:
|
|||||||
self.delete_calls.append(key)
|
self.delete_calls.append(key)
|
||||||
if key in self._cache:
|
if key in self._cache:
|
||||||
del self._cache[key]
|
del self._cache[key]
|
||||||
|
|
||||||
|
def get_cached_data_with_strategy(self, key: str, data_type: str = 'default') -> Optional[Any]:
|
||||||
|
"""Mock of CacheManager.get_cached_data_with_strategy (src/cache_manager.py).
|
||||||
|
|
||||||
|
The real method picks a max_age/memory_ttl strategy per data_type
|
||||||
|
(and extends it during market-closed hours for market data) before
|
||||||
|
delegating to get_cached_data(). None of that timing nuance matters
|
||||||
|
for a mock -- plugins under test just need the method to exist and
|
||||||
|
return whatever was cached, so this delegates straight to get().
|
||||||
|
"""
|
||||||
|
self.get_cached_data_with_strategy_calls.append({'key': key, 'data_type': data_type})
|
||||||
|
return self.get(key)
|
||||||
|
|
||||||
|
def save_cache(self, key: str, data: Any) -> None:
|
||||||
|
"""Mock of CacheManager.save_cache (src/cache_manager.py) -- the
|
||||||
|
write-side counterpart to get_cached_data_with_strategy, used by the
|
||||||
|
same real-CacheManager-oriented plugins. Delegates to set()."""
|
||||||
|
self.set(key, data)
|
||||||
if key in self._cache_timestamps:
|
if key in self._cache_timestamps:
|
||||||
del self._cache_timestamps[key]
|
del self._cache_timestamps[key]
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
"""
|
||||||
|
Unit tests for src/plugin_system/testing/mocks.py.
|
||||||
|
|
||||||
|
MockCacheManager/MockPluginManager stand in for the real production
|
||||||
|
managers under the plugin safety harness -- a missing method here isn't a
|
||||||
|
harness bug in the abstract, it's a plugin silently failing to render
|
||||||
|
under test (confirmed on ledmatrix-leaderboard, which calls
|
||||||
|
get_cached_data_with_strategy() and previously hit an AttributeError that
|
||||||
|
its own broad except swallowed, producing an empty-but-green render).
|
||||||
|
"""
|
||||||
|
|
||||||
|
from src.plugin_system.testing.mocks import MockCacheManager
|
||||||
|
|
||||||
|
|
||||||
|
class TestMockCacheManagerStrategyMethod:
|
||||||
|
def test_get_cached_data_with_strategy_returns_cached_value(self):
|
||||||
|
cm = MockCacheManager()
|
||||||
|
cm.set("standings_nfl", {"teams": ["KC", "BUF"]})
|
||||||
|
result = cm.get_cached_data_with_strategy("standings_nfl", "sports_live")
|
||||||
|
assert result == {"teams": ["KC", "BUF"]}
|
||||||
|
|
||||||
|
def test_get_cached_data_with_strategy_returns_none_when_missing(self):
|
||||||
|
cm = MockCacheManager()
|
||||||
|
assert cm.get_cached_data_with_strategy("missing_key") is None
|
||||||
|
|
||||||
|
def test_get_cached_data_with_strategy_defaults_data_type(self):
|
||||||
|
cm = MockCacheManager()
|
||||||
|
cm.set("k", "v")
|
||||||
|
assert cm.get_cached_data_with_strategy("k") == "v"
|
||||||
|
|
||||||
|
def test_calls_are_tracked(self):
|
||||||
|
cm = MockCacheManager()
|
||||||
|
cm.get_cached_data_with_strategy("k", "sports_live")
|
||||||
|
assert cm.get_cached_data_with_strategy_calls == [{"key": "k", "data_type": "sports_live"}]
|
||||||
|
|
||||||
|
def test_save_cache_is_readable_via_strategy_lookup(self):
|
||||||
|
cm = MockCacheManager()
|
||||||
|
cm.save_cache("standings_nfl", {"teams": ["KC", "BUF"]})
|
||||||
|
assert cm.get_cached_data_with_strategy("standings_nfl") == {"teams": ["KC", "BUF"]}
|
||||||
Reference in New Issue
Block a user