import unittest from typing import Any, cast from server.GameBoard import GameBoard from server.game_state_store import GameStateStoreBuilder, MemoryGameBoardStore, RedisGameBoardStore from snakes.TemplateSnake import TemplateSnake class _FakeRedis: def __init__(self): self.data = {} async def set(self, key, value, ex=None): self.data[key] = value async def get(self, key): return self.data.get(key) async def delete(self, key): self.data.pop(key, None) async def aclose(self): return None class TestGameStateStore(unittest.IsolatedAsyncioTestCase): def _build_board(self) -> GameBoard: board = GameBoard( game_id="game-1", width=11, height=11, ruleset={"name": "standard", "version": "v1.0.0"}, source="custom", map="standard", snake_class=TemplateSnake(), ) board.read_game_data( { "turn": 3, "board": { "food": [{"x": 1, "y": 1}], "hazards": [], "snakes": [ { "id": "me", "name": "me", "health": 99, "length": 3, "head": {"x": 2, "y": 2}, "body": [ {"x": 2, "y": 2}, {"x": 2, "y": 1}, {"x": 2, "y": 0}, ], } ], }, "you": { "id": "me", "name": "me", "health": 99, "length": 3, "head": {"x": 2, "y": 2}, "body": [ {"x": 2, "y": 2}, {"x": 2, "y": 1}, {"x": 2, "y": 0}, ], }, "game": {"timeout": 500}, } ) return board def test_builder_selects_store_backend(self): memory_store = GameStateStoreBuilder.build(backend="memory") redis_store = GameStateStoreBuilder.build(backend="redis") default_store = GameStateStoreBuilder.build(backend="unknown") self.assertIsInstance(memory_store, MemoryGameBoardStore) self.assertIsInstance(redis_store, RedisGameBoardStore) self.assertIsInstance(default_store, MemoryGameBoardStore) async def test_memory_backend_roundtrip(self): store = MemoryGameBoardStore() board = self._build_board() await store.save("game-1", board) loaded = cast(GameBoard, await store.load("game-1")) self.assertIsNotNone(loaded) self.assertEqual(loaded.id, "game-1") await store.delete("game-1") self.assertIsNone(await store.load("game-1")) async def test_redis_backend_roundtrip(self): store = RedisGameBoardStore() store._redis = cast(Any, _FakeRedis()) board = self._build_board() await store.save("game-1", board) loaded = cast(GameBoard, await store.load("game-1")) self.assertIsNotNone(loaded) self.assertEqual(loaded.id, "game-1") self.assertEqual(loaded.get_turn(), 3) await store.delete("game-1") self.assertIsNone(await store.load("game-1")) if __name__ == "__main__": unittest.main()