106 lines
3.5 KiB
Python
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()
|