import pytest from cursor_flasher.state import FlasherState, StateMachine class TestStateMachine: def test_initial_state_is_idle(self): sm = StateMachine() assert sm.state == FlasherState.IDLE def test_idle_to_agent_working(self): sm = StateMachine() changed = sm.update(agent_working=True, approval_needed=False) assert sm.state == FlasherState.AGENT_WORKING assert changed is True def test_agent_working_to_waiting(self): sm = StateMachine() sm.update(agent_working=True, approval_needed=False) changed = sm.update(agent_working=False, approval_needed=False) assert sm.state == FlasherState.WAITING_FOR_USER assert changed is True def test_approval_needed_triggers_waiting(self): sm = StateMachine() sm.update(agent_working=True, approval_needed=False) changed = sm.update(agent_working=False, approval_needed=True) assert sm.state == FlasherState.WAITING_FOR_USER assert changed is True def test_idle_does_not_jump_to_waiting(self): sm = StateMachine() changed = sm.update(agent_working=False, approval_needed=False) assert sm.state == FlasherState.IDLE assert changed is False def test_waiting_to_user_interacting(self): sm = StateMachine() sm.update(agent_working=True, approval_needed=False) sm.update(agent_working=False, approval_needed=False) assert sm.state == FlasherState.WAITING_FOR_USER changed = sm.dismiss() assert sm.state == FlasherState.IDLE assert changed is True def test_waiting_to_agent_working(self): sm = StateMachine() sm.update(agent_working=True, approval_needed=False) sm.update(agent_working=False, approval_needed=False) changed = sm.update(agent_working=True, approval_needed=False) assert sm.state == FlasherState.AGENT_WORKING assert changed is True def test_no_change_returns_false(self): sm = StateMachine() sm.update(agent_working=True, approval_needed=False) changed = sm.update(agent_working=True, approval_needed=False) assert changed is False def test_cooldown_prevents_immediate_retrigger(self): sm = StateMachine(cooldown=5.0) sm.update(agent_working=True, approval_needed=False) sm.update(agent_working=False, approval_needed=False) assert sm.state == FlasherState.WAITING_FOR_USER sm.dismiss() sm.update(agent_working=True, approval_needed=False) changed = sm.update(agent_working=False, approval_needed=False) assert sm.cooldown == 5.0 def test_direct_approval_from_idle(self): """If we detect approval buttons without seeing agent_working first, still transition to WAITING_FOR_USER.""" sm = StateMachine() changed = sm.update(agent_working=False, approval_needed=True) assert sm.state == FlasherState.WAITING_FOR_USER assert changed is True