test_members.py 3.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283
  1. """Tests du registre des membres. Lancer depuis la racine du projet : python -m unittest"""
  2. import json
  3. import tempfile
  4. import unittest
  5. from pathlib import Path
  6. from bot.members import MemberRegistry
  7. ENTRY = {"username": "bob", "global_name": "Bob", "nickname": None, "former_names": [],
  8. "notified": True, "memory": False, "first_seen": "2026-10-31"}
  9. class BrokenRegistryTest(unittest.IsolatedAsyncioTestCase):
  10. """Registre illisible : rien n'est oublié, la mémoire est coupée jusqu'à sa réparation."""
  11. def setUp(self):
  12. self._tmp = tempfile.TemporaryDirectory()
  13. self.path = Path(self._tmp.name) / "registre.json"
  14. def tearDown(self):
  15. self._tmp.cleanup()
  16. def load(self, members: dict | None = None, text: str | None = None) -> MemberRegistry:
  17. if text is None:
  18. text = json.dumps({"version": 1, "members": members})
  19. self.path.write_text(text, encoding="utf-8")
  20. return MemberRegistry(self.path)
  21. async def assert_broken_and_kept(self, registry: MemberRegistry) -> None:
  22. before = self.path.read_bytes()
  23. self.assertIsNotNone(registry.broken)
  24. await registry.see(222, "alice", "Alice") # rien n'est écrit
  25. self.assertEqual(self.path.read_bytes(), before)
  26. self.assertEqual(list(self.path.parent.iterdir()), [self.path]) # ni copie, ni fichier temporaire
  27. async def test_truncated_file(self):
  28. text = json.dumps({"version": 1, "members": {"111": ENTRY}})
  29. with self.assertLogs("chatbot.members", "ERROR"):
  30. registry = self.load(text=text[:-20])
  31. await self.assert_broken_and_kept(registry)
  32. async def test_malformed_memory_field(self):
  33. with self.assertLogs("chatbot.members", "ERROR"):
  34. registry = self.load({"111": {**ENTRY, "memory": "non"}})
  35. await self.assert_broken_and_kept(registry)
  36. async def test_missing_memory_field(self):
  37. entry = dict(ENTRY)
  38. del entry["memory"]
  39. with self.assertLogs("chatbot.members", "ERROR"):
  40. registry = self.load({"111": entry})
  41. await self.assert_broken_and_kept(registry)
  42. async def test_entry_without_username(self):
  43. with self.assertLogs("chatbot.members", "ERROR"):
  44. registry = self.load({"111": {**ENTRY, "username": None}})
  45. await self.assert_broken_and_kept(registry)
  46. async def test_valid_file(self):
  47. registry = self.load({"111": ENTRY})
  48. self.assertIsNone(registry.broken)
  49. self.assertFalse(registry.memory_enabled(111))
  50. await registry.see(222, "alice", "Alice")
  51. self.assertIn("222", json.loads(self.path.read_text(encoding="utf-8"))["members"])
  52. async def test_file_with_bom(self):
  53. # Registre corrigé à la main puis enregistré avec BOM (Bloc-notes) : toujours lisible.
  54. self.path.write_text(json.dumps({"version": 1, "members": {"111": ENTRY}}), encoding="utf-8-sig")
  55. registry = MemberRegistry(self.path)
  56. self.assertIsNone(registry.broken)
  57. self.assertFalse(registry.memory_enabled(111))
  58. await registry.see(222, "alice", "Alice")
  59. self.assertIn("222", json.loads(self.path.read_text(encoding="utf-8"))["members"]) # réécrit sans BOM
  60. async def test_missing_file(self):
  61. registry = MemberRegistry(self.path)
  62. self.assertIsNone(registry.broken)
  63. self.assertEqual(registry.members(), {})
  64. if __name__ == "__main__":
  65. unittest.main()