"""Tests for timmy.events — SensoryEvent model.""" import json from datetime import UTC, datetime from timmy.events import SensoryEvent class TestSensoryEvent: def test_defaults(self): ev = SensoryEvent(source="gitea", event_type="push") assert ev.source == "gitea" assert ev.event_type == "push" assert ev.actor == "" assert ev.data == {} assert isinstance(ev.timestamp, datetime) def test_custom_fields(self): ts = datetime(2025, 1, 1, tzinfo=UTC) ev = SensoryEvent( source="bitcoin", event_type="new_block", timestamp=ts, data={"height": 900_000}, actor="network", ) assert ev.data["height"] == 900_000 assert ev.actor == "network" assert ev.timestamp == ts def test_to_dict(self): ev = SensoryEvent(source="time", event_type="morning") d = ev.to_dict() assert d["source"] == "time" assert d["event_type"] == "morning" assert isinstance(d["timestamp"], str) def test_to_json(self): ev = SensoryEvent(source="terminal", event_type="command", data={"cmd": "ls"}) raw = ev.to_json() parsed = json.loads(raw) assert parsed["source"] == "terminal" assert parsed["data"]["cmd"] == "ls" def test_from_dict_roundtrip(self): ev = SensoryEvent( source="gitea", event_type="issue_opened", data={"number": 42}, actor="alice", ) d = ev.to_dict() restored = SensoryEvent.from_dict(d) assert restored.source == ev.source assert restored.event_type == ev.event_type assert restored.data == ev.data assert restored.actor == ev.actor def test_json_serializable(self): """SensoryEvent must be JSON-serializable (acceptance criterion).""" ev = SensoryEvent(source="gitea", event_type="push", data={"ref": "main"}) raw = ev.to_json() parsed = json.loads(raw) assert parsed["source"] == "gitea"