import tempfile import unittest from concurrent.futures import ThreadPoolExecutor from pathlib import Path import app class StoreTests(unittest.TestCase): def setUp(self): self.temp = tempfile.TemporaryDirectory() self.store = app.Store(Path(self.temp.name) / "state.sqlite3") self.store.initialize() def tearDown(self): self.temp.cleanup() def test_empty_store(self): self.assertEqual(self.store.snapshot()["checks"], {}) self.assertEqual(self.store.snapshot()["revision"], 0) def test_shared_check_round_trip(self): result = self.store.set_check("crop-parsnip", True, "fred") self.assertEqual(result["revision"], 1) snapshot = self.store.snapshot() self.assertTrue(snapshot["checks"]["crop-parsnip"]) self.assertEqual(snapshot["updatedBy"], "fred") self.store.set_check("crop-parsnip", False, "kayla") snapshot = self.store.snapshot() self.assertFalse(snapshot["checks"]["crop-parsnip"]) self.assertEqual(snapshot["revision"], 2) def test_two_clients_keep_distinct_concurrent_changes(self): second_client = app.Store(self.store.path) def write(index): store = self.store if index % 2 else second_client store.set_check(f"concurrent-item-{index}", True, f"player-{index % 2}") with ThreadPoolExecutor(max_workers=2) as pool: list(pool.map(write, range(20))) snapshot = self.store.snapshot() self.assertEqual(snapshot["revision"], 20) self.assertEqual(len(snapshot["checks"]), 20) self.assertTrue(all(snapshot["checks"].values())) def test_planting_round_trip(self): spring_three = {"year": 1, "season": "spring", "day": 3} result = self.store.set_planting("crop-parsnip", spring_three, "fred") self.assertEqual(result["revision"], 1) self.assertEqual(self.store.snapshot()["plantings"], {"crop-parsnip": spring_three}) self.store.set_planting("crop-parsnip", None, "fred") snapshot = self.store.snapshot() self.assertEqual(snapshot["plantings"], {}) self.assertEqual(snapshot["revision"], 2) def test_undated_planted_checks_migrate_to_plantings(self): self.store.set_check("planted-crop-parsnip", True, "fred") self.store.set_check("planted-crop-potato", False, "fred") self.store.initialize() snapshot = self.store.snapshot() self.assertEqual(snapshot["checks"], {}) self.assertEqual( snapshot["plantings"], {"crop-parsnip": {"year": None, "season": None, "day": None}} ) self.assertEqual(snapshot["revision"], 3) def test_game_date_validation(self): self.assertTrue(app.valid_game_date({"year": 2, "season": "winter", "day": 28})) self.assertFalse(app.valid_game_date({"year": 1, "season": "spring", "day": 29})) self.assertFalse(app.valid_game_date({"year": True, "season": "spring", "day": 1})) self.assertFalse(app.valid_game_date({"year": 1, "season": "monsoon", "day": 1})) class StaticInteractionTests(unittest.TestCase): def test_native_checkboxes_cover_each_tickable_row(self): styles = (Path(__file__).parent.parent / "static" / "styles.css").read_text() self.assertIn(".today-card > input, .crop-row input, .bundle-item input", styles) self.assertIn("inset: 0", styles) self.assertNotIn(".crop-row input, .bundle-item input { position: absolute; opacity: 0; pointer-events: none; }", styles) if __name__ == "__main__": unittest.main()