diff --git a/mcp_server/tests/test_tui_app.py b/mcp_server/tests/test_tui_app.py index 3f94156..592f8f9 100644 --- a/mcp_server/tests/test_tui_app.py +++ b/mcp_server/tests/test_tui_app.py @@ -360,6 +360,24 @@ def _gate_ready(): ) +def _docker_runtime(): + """Pin the launch runtime to docker, explicitly configured rather than inferred. + + The gate branches on the runtime (docker → StartContainersScreen, process → + StartBackendProcessScreen), so container-path tests must pin it: otherwise they read + the developer's own BACKEND_RUNTIME/saved choice and assert the wrong branch. Marking + it configured also skips the infer-from-what's-running block, which would consult the + real host for a backend process. + """ + return ( + patch("tui.app.backend_runtime_is_configured", return_value=True), + patch( + "tui.app.resolve_backend_runtime", + return_value=tui_app.local_env.BackendRuntime.DOCKER, + ), + ) + + class TestStartupGate: @pytest.mark.asyncio async def test_ready_gen_lands_on_dashboard(self): @@ -408,9 +426,11 @@ async def test_client_setup_skip_proceeds_to_sessions(self): @pytest.mark.asyncio async def test_containers_down_prompts_start(self): + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), - patch("tui.app.backend_runtime_is_configured", return_value=True), patch("tui.app.local_env.containers_running", return_value=False), ): app = tui_app.SpecFlowTUI(root=Path("/tmp/x"), generation_id=None, poll_interval=999) @@ -420,9 +440,11 @@ async def test_containers_down_prompts_start(self): @pytest.mark.asyncio async def test_start_no_quits_app(self): + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), - patch("tui.app.backend_runtime_is_configured", return_value=True), patch("tui.app.local_env.containers_running", return_value=False), ): app = tui_app.SpecFlowTUI(root=Path("/tmp/x"), generation_id=None, poll_interval=999) @@ -434,9 +456,11 @@ async def test_start_no_quits_app(self): @pytest.mark.asyncio async def test_start_yes_starts_then_proceeds(self): + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), - patch("tui.app.backend_runtime_is_configured", return_value=True), patch("tui.app.local_env.containers_running", return_value=False), patch("tui.app.local_env.start_containers", new=AsyncMock(return_value=0)), patch("tui.app.local_env.wait_backend_ready", new=AsyncMock(return_value=True)), @@ -454,7 +478,10 @@ async def test_start_yes_starts_then_proceeds(self): async def test_containers_up_but_backend_not_ready_says_unhealthy_not_down(self): # Containers running + backend not ready → the gate must not claim the # containers aren't running; it shows the "backend isn't healthy" prompt. + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), patch("tui.app.local_env.containers_running", return_value=True), patch("tui.app.local_env.backend_ready", new=AsyncMock(return_value=False)), @@ -476,7 +503,10 @@ async def test_backend_not_ready_retry_skips_compose_up(self): # In the up-but-not-ready path, retrying (y) re-polls readiness without # re-running `docker compose up` (the containers are already up). start = AsyncMock(return_value=0) + cfg, rt = _docker_runtime() with ( + cfg, + rt, patch("tui.app.local_env.is_setup_complete", return_value=True), patch("tui.app.local_env.containers_running", return_value=True), patch("tui.app.local_env.backend_ready", new=AsyncMock(return_value=False)),