import json import tempfile import unittest from pathlib import Path from halloween.controller import Controller class ControllerTest(unittest.TestCase): def setUp(self): self.folder = tempfile.TemporaryDirectory() self.addCleanup(self.folder.cleanup) self.now = 100.0 self.path = Path(self.folder.name) self.controller = Controller(self.path, clock=lambda: self.now) def test_start_needs_clear_zone_and_fresh_trigger(self): self.assertEqual(self.controller.status()["mode"], "voll") self.assertFalse(self.controller.trigger()[0]) self.controller.zone_clear() self.assertTrue(self.controller.trigger()[0]) self.assertFalse(self.controller.trigger()[0]) self.now += 11 self.assertFalse(self.controller.trigger()[0]) self.controller.zone_clear() self.assertTrue(self.controller.trigger()[0]) def test_stop_latches_until_reset_and_new_clear_zone(self): self.controller.zone_clear() self.controller.stop() self.assertFalse(self.controller.trigger()[0]) self.controller.reset() self.assertFalse(self.controller.trigger()[0]) self.controller.zone_clear() self.assertTrue(self.controller.trigger()[0]) def test_mode_persists_and_corrupt_file_fails_closed(self): self.controller.set_mode("sanft") self.assertEqual(Controller(self.path).mode, "sanft") (self.path / "settings.json").write_text("{kaputt", encoding="utf-8") broken = Controller(self.path) self.assertEqual(broken.mode, "aus") self.assertIsNotNone(broken.config_error) broken.zone_clear() self.assertFalse(broken.trigger()[0]) broken.set_mode("voll") self.assertEqual(json.loads((self.path / "settings.json").read_text())["mode"], "voll") def test_mode_change_cancels_running_sequence(self): self.controller.zone_clear() self.assertTrue(self.controller.trigger()[0]) self.controller.set_mode("aus") self.assertFalse(self.controller.trigger()[0]) self.assertFalse(self.controller.status()["zone_clear_seen"]) if __name__ == "__main__": unittest.main()