"""BL-05: locked install API returns 404 (no fingerprint) on all endpoints.""" from unittest.mock import patch import pytest from fastapi import HTTPException @pytest.fixture def locked(): with patch("server.api.install._is_locked", return_value=True): yield @pytest.fixture def unlocked(): with patch("server.api.install._is_locked", return_value=False): yield def _assert_not_found(exc: HTTPException) -> None: assert exc.status_code == 404 assert exc.detail == "Not found" @pytest.mark.asyncio async def test_status_locked_404(locked): from server.api.install import install_status with pytest.raises(HTTPException) as exc: await install_status() _assert_not_found(exc.value) @pytest.mark.asyncio async def test_status_unlocked_200(unlocked): from server.api.install import install_status with patch("server.api.install._has_env", return_value=False): result = await install_status() assert result["locked"] is False assert "configured" in result @pytest.mark.asyncio async def test_env_check_locked_404(locked): from server.api.install import env_check with pytest.raises(HTTPException) as exc: await env_check() _assert_not_found(exc.value) @pytest.mark.asyncio async def test_connection_check_locked_404(locked): from server.api.install import connection_check with pytest.raises(HTTPException) as exc: await connection_check() _assert_not_found(exc.value) @pytest.mark.asyncio async def test_state_locked_404(locked): from server.api.install import get_install_state with pytest.raises(HTTPException) as exc: await get_install_state() _assert_not_found(exc.value) @pytest.mark.asyncio async def test_lock_endpoint_locked_404(locked): from server.api.install import lock_install with pytest.raises(HTTPException) as exc: await lock_install() _assert_not_found(exc.value) @pytest.mark.asyncio async def test_init_db_locked_404(locked): from server.api.install import init_db, InitDbRequest req = InitDbRequest( db_host="localhost", db_port="3306", db_name="nexus", db_user="root", db_pass="x", ) with pytest.raises(HTTPException) as exc: await init_db(req) _assert_not_found(exc.value) def test_reject_if_locked_raises_404(): from server.api.install import _reject_if_locked with patch("server.api.install._is_locked", return_value=True): with pytest.raises(HTTPException) as exc: _reject_if_locked() _assert_not_found(exc.value) @pytest.mark.asyncio async def test_test_credentials_locked_404(locked): from server.api.install import test_credentials, InitDbRequest req = InitDbRequest( db_host="localhost", db_port="3306", db_name="nexus", db_user="root", db_pass="x", ) with pytest.raises(HTTPException) as exc: await test_credentials(req) _assert_not_found(exc.value) @pytest.mark.asyncio async def test_create_admin_locked_404(locked): from server.api.install import create_admin, CreateAdminRequest req = CreateAdminRequest( install_token="tok", db_pass="x", admin_password="secret12", ) with pytest.raises(HTTPException) as exc: await create_admin(req) _assert_not_found(exc.value) def test_install_router_has_lock_dependency(): """Router-level lock guard runs before per-route handlers (BL-05).""" from server.api.install import router assert router.dependencies, "install router must enforce lock before body validation"