State machine no longer transitions directly from IDLE to WAITING_FOR_USER on approval signals. Must see AGENT_WORKING first — this prevents stale buttons like "Run this time only" persisting in chat history from triggering the flash when no agent task is active. Also removed "Continue" and "Resume" from approval keywords (too generic, appear in normal chat text). Made-with: Cursor
83 lines
3.3 KiB
Python
83 lines
3.3 KiB
Python
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_stale_approval_from_idle_ignored(self):
|
|
"""Approval buttons in IDLE state (stale chat history) must not trigger flash."""
|
|
sm = StateMachine()
|
|
changed = sm.update(agent_working=False, approval_needed=True)
|
|
assert sm.state == FlasherState.IDLE
|
|
assert changed is False
|
|
|
|
def test_approval_after_working_triggers(self):
|
|
"""Approval buttons after seeing agent work should trigger flash."""
|
|
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
|