test_tui_client.py 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. """Tests for the TUI control client against a real control server."""
  2. import os
  3. import shutil
  4. import tempfile
  5. import time
  6. import pytest
  7. from stt_daemon.assistant.control import ControlServer
  8. from stt_daemon.assistant.service import AssistantService
  9. from stt_daemon.config import Config
  10. from stt_daemon.tui.client import ControlClient
  11. class FakeSubscriber:
  12. def events(self):
  13. return iter(())
  14. def close(self):
  15. pass
  16. @pytest.fixture
  17. def server():
  18. directory = tempfile.mkdtemp(prefix="sttt-")
  19. path = os.path.join(directory, "c.sock")
  20. cfg = Config()
  21. cfg.assistant.control_socket = path
  22. service = AssistantService(cfg, FakeSubscriber())
  23. control = ControlServer(cfg, service, path=path)
  24. service.set_sinks(emit=control.broadcast, relay=control.relay)
  25. control.start()
  26. yield path, service, control
  27. control.close()
  28. service.stop()
  29. shutil.rmtree(directory, ignore_errors=True)
  30. def _wait(predicate, timeout=5.0):
  31. deadline = time.time() + timeout
  32. while time.time() < deadline:
  33. if predicate():
  34. return True
  35. time.sleep(0.01)
  36. return predicate()
  37. def test_client_subscribes_and_receives_status(server):
  38. path, _service, _control = server
  39. received: list[dict] = []
  40. client = ControlClient(path)
  41. client.connect()
  42. client.subscribe(viewer=True)
  43. client.start(received.append)
  44. assert _wait(lambda: any(e["type"] == "status" for e in received))
  45. client.close()
  46. def test_client_command_start_flips_mode_and_broadcasts(server):
  47. path, service, _control = server
  48. received: list[dict] = []
  49. client = ControlClient(path)
  50. client.connect()
  51. client.subscribe(viewer=True)
  52. client.start(received.append)
  53. assert _wait(lambda: any(e["type"] == "status" for e in received))
  54. client.send("command_start")
  55. assert _wait(lambda: service.modes.mode.value == "command_armed")
  56. assert _wait(
  57. lambda: any(e["type"] == "mode" and e["mode"] == "command_armed" for e in received)
  58. )
  59. client.close()
  60. def test_client_receives_relayed_transcript(server):
  61. path, service, _control = server
  62. received: list[dict] = []
  63. client = ControlClient(path)
  64. client.connect()
  65. client.subscribe(viewer=True)
  66. client.start(received.append)
  67. assert _wait(lambda: any(e["type"] == "status" for e in received))
  68. service.handle_event(
  69. {"v": 1, "type": "transcript", "seq": 1, "ts": time.time(), "text": "hello", "lang": "en"}
  70. )
  71. assert _wait(lambda: any(e["type"] == "transcript" and e["text"] == "hello" for e in received))
  72. client.close()