# SPDX-License-Identifier: GPL-3.0-or-later import io import json import os import tempfile import unittest from contextlib import redirect_stdout from pathlib import Path from enodia_sentinel.cli import main from enodia_sentinel.config import Config from enodia_sentinel.tui import ( TuiState, collect_model, complete_command, render_lines, run_tui_command, ) class TestTuiCore(unittest.TestCase): def setUp(self): self.dir = tempfile.TemporaryDirectory() self.tmp = Path(self.dir.name) self.cfg = Config() self.cfg.log_dir = self.tmp def tearDown(self): self.dir.cleanup() def test_command_completion_unique_and_common_prefix(self): self.assertEqual(complete_command("inc"), "incidents") self.assertEqual(complete_command("r"), "r") self.assertEqual(complete_command("zzz"), "zzz") def test_run_tui_command_switches_views_and_filters(self): state = TuiState() run_tui_command(state, "incidents") self.assertEqual(state.view, "incidents") run_tui_command(state, "filter ssh") self.assertEqual(state.filter_text, "ssh") run_tui_command(state, "clear") self.assertEqual(state.filter_text, "") run_tui_command(state, "quit") self.assertTrue(state.should_quit) def test_collect_model_and_render_status(self): model = collect_model(self.cfg) state = TuiState(model=model) lines = render_lines(state, width=80) self.assertTrue(any("Daemon:" in line for line in lines)) self.assertTrue(any("Heartbeat:" in line for line in lines)) def test_render_alerts_and_filter(self): (self.tmp / "alert-1.json").write_text(json.dumps({ "time": "2026-07-09T01:02:03-07:00", "alerts": [{ "severity": "CRITICAL", "sid": 100010, "signature": "reverse_shell", "detail": "bash connected to 8.8.8.8", }], })) state = TuiState(view="alerts", model=collect_model(self.cfg)) self.assertTrue(any("reverse_shell" in line for line in render_lines(state))) state.filter_text = "nomatch" self.assertEqual(render_lines(state), ["No rows match filter: nomatch"]) def test_cli_completion_outputs_scripts(self): for shell in ("bash", "zsh"): with self.subTest(shell=shell): buf = io.StringIO() with redirect_stdout(buf): code = main(["completion", shell]) self.assertEqual(code, 0) self.assertIn("enodia-sentinel", buf.getvalue()) self.assertIn("tui", buf.getvalue()) if __name__ == "__main__": unittest.main()