Files
box/tests/test_box_onboard_tui.py
operator 9f2a0e836d feat(tmux): implement multi-socket worker tally, regex auto-approver, and onboard TUI
- bin/tmux_auto_approver.py: multi-socket worker discovery across user and netns sockets
- Regex matching engine with 7 terminal prompt rules and hard security guardrails
- bin/box-onboard-tui.py: dedicated 4-tab curses TUI for fleet connects, tmux workers, rules, and audit logs
- Audit logging stream in logs/tmux/auto-approvals.jsonl and state in .state/
- Unit test suites covering engine, rules, guardrails, and curses rendering
2026-10-07 00:25:14 +00:00

106 lines
3.5 KiB
Python

#!/usr/bin/env python3
"""test_box_onboard_tui.py — Unit tests for dedicated Onboard Connects & Tmux Auto-Approver TUI."""
import curses
import os
import sys
import unittest
from pathlib import Path
from unittest.mock import MagicMock, patch
REPO_ROOT = Path(__file__).resolve().parent.parent
import importlib.util
tui_path = REPO_ROOT / "bin" / "box-onboard-tui.py"
spec = importlib.util.spec_from_file_location("box_onboard_tui", tui_path)
box_onboard_tui = importlib.util.module_from_spec(spec)
sys.modules["box_onboard_tui"] = box_onboard_tui
spec.loader.exec_module(box_onboard_tui)
BoxOnboardTUI = box_onboard_tui.BoxOnboardTUI
class TestBoxOnboardTUI(unittest.TestCase):
@patch("curses.init_pair")
@patch("curses.color_pair")
@patch("curses.has_colors", return_value=True)
@patch("curses.start_color")
@patch("box_onboard_tui.gather_tmux_tally")
@patch("box_onboard_tui.get_all_connects")
def test_tui_initialization_and_tabs(
self, mock_connects, mock_tally, mock_start_color, mock_has_colors, mock_color_pair, mock_init_pair
):
mock_stdscr = MagicMock()
mock_stdscr.getmaxyx.return_value = (40, 120)
mock_connects.return_value = [
{"node": "muse", "type": "fleet_agent", "email": "muse@test.com", "stage": "active_fleet"},
{"node": "test-client", "type": "onboard_pipeline", "email": "c@test.com", "stage": "awaiting_otp"},
]
mock_tally.return_value = MagicMock(
total_sockets=2,
total_sessions=3,
total_panes=5,
active_workers=2,
panes=[],
by_agent={"muse": {"sessions": 1, "panes": 2, "active_commands": ["muse-bin"], "auto_approve": True}},
)
app = BoxOnboardTUI(mock_stdscr)
self.assertEqual(app.current_tab, 0)
self.assertEqual(len(app.tabs), 4)
self.assertEqual(len(app.connects), 2)
# Tab navigation via key
app._handle_key(ord("\t"))
self.assertEqual(app.current_tab, 1)
app._handle_key(ord("\t"))
self.assertEqual(app.current_tab, 2)
app._handle_key(ord("\t"))
self.assertEqual(app.current_tab, 3)
app._handle_key(ord("\t"))
self.assertEqual(app.current_tab, 0)
@patch("curses.init_pair")
@patch("curses.color_pair")
@patch("curses.has_colors", return_value=True)
@patch("box_onboard_tui.gather_tmux_tally")
@patch("box_onboard_tui.get_all_connects")
def test_navigation_keys(
self, mock_connects, mock_tally, mock_has_colors, mock_color_pair, mock_init_pair
):
mock_stdscr = MagicMock()
mock_stdscr.getmaxyx.return_value = (40, 120)
mock_connects.return_value = [
{"node": f"node-{i}", "type": "fleet_agent"} for i in range(5)
]
app = BoxOnboardTUI(mock_stdscr)
self.assertEqual(app.sel_connect_idx, 0)
# Move down
app._handle_key(curses.KEY_DOWN)
self.assertEqual(app.sel_connect_idx, 1)
# Move up
app._handle_key(curses.KEY_UP)
self.assertEqual(app.sel_connect_idx, 0)
# Switch tab via number key '2'
app._handle_key(ord("2"))
self.assertEqual(app.current_tab, 1)
# Switch tab via number key '3'
app._handle_key(ord("3"))
self.assertEqual(app.current_tab, 2)
# Switch tab via number key '4'
app._handle_key(ord("4"))
self.assertEqual(app.current_tab, 3)
if __name__ == "__main__":
unittest.main()