"""Tests for worker poller snapshot diffing."""
from maniple.poller import _build_snapshot, _build_transition_events
class _FakeSession:
"""Minimal session stub for poller diff tests."""
def __init__(self, session_id: str, idle: bool, agent_type: str = "claude") -> None:
"""Initialize with a session id, idle state, and agent type."""
self.session_id = session_id
self._idle = idle
self.agent_type = agent_type
self.project_path = ""
self.claude_session_id = None
def is_idle(self) -> bool:
"""Return whether the session is idle."""
return self._idle
def to_dict(self) -> dict:
"""Return a minimal serialized representation of the session."""
return {"session_id": self.session_id}
class _FakeRegistry:
"""Registry stub that returns a predefined set of sessions."""
def __init__(self, sessions: list[_FakeSession]) -> None:
"""Initialize with a list of sessions."""
self._sessions = sessions
def list_all(self) -> list[_FakeSession]:
"""Return all sessions in the registry."""
return list(self._sessions)
def _snapshot_for(*sessions: _FakeSession) -> dict:
# Build a snapshot from a set of fake sessions.
return _build_snapshot(_FakeRegistry(list(sessions)))
class TestPollerTransitions:
"""Transition detection for worker snapshots."""
def test_new_worker_emits_started_once(self) -> None:
"""New worker should emit worker_started only on first appearance."""
snapshot = _snapshot_for(_FakeSession("alpha", False))
events = _build_transition_events({}, snapshot, "2026-01-27T12:00:00Z")
assert [event.type for event in events] == ["worker_started"]
assert _build_transition_events(snapshot, snapshot, "2026-01-27T12:00:10Z") == []
def test_idle_transition_emits_worker_idle(self) -> None:
"""Active -> idle transition should emit worker_idle."""
previous = _snapshot_for(_FakeSession("alpha", False))
current = _snapshot_for(_FakeSession("alpha", True))
events = _build_transition_events(previous, current, "2026-01-27T12:01:00Z")
# Verify the emitted event and payload details.
assert len(events) == 1
event = events[0]
assert event.type == "worker_idle"
assert event.data["previous_state"] == "active"
assert event.data["state"] == "idle"
def test_active_transition_emits_worker_active(self) -> None:
"""Idle -> active transition should emit worker_active."""
previous = _snapshot_for(_FakeSession("alpha", True))
current = _snapshot_for(_FakeSession("alpha", False))
events = _build_transition_events(previous, current, "2026-01-27T12:02:00Z")
# Verify the emitted event and payload details.
assert len(events) == 1
event = events[0]
assert event.type == "worker_active"
assert event.data["previous_state"] == "idle"
assert event.data["state"] == "active"
def test_removed_worker_emits_closed(self) -> None:
"""Removed worker should emit worker_closed with previous state."""
previous = _snapshot_for(_FakeSession("alpha", True))
events = _build_transition_events(previous, {}, "2026-01-27T12:03:00Z")
# Verify the emitted event and payload details.
assert len(events) == 1
event = events[0]
assert event.type == "worker_closed"
assert event.data["previous_state"] == "idle"
assert event.data["state"] == "closed"