@@ -0,0 +1,41 @@ |
| 1 | +"""CLI tests for ``sway serve``. |
| 2 | + |
| 3 | +These cover argument validation only — actually running uvicorn would |
| 4 | +bind a port. The 0.0.0.0-without-api-key refusal is the load-bearing |
| 5 | +check (sprint plan risk #1: anyone-on-LAN-drives-your-GPU). |
| 6 | +""" |
| 7 | + |
| 8 | +from __future__ import annotations |
| 9 | + |
| 10 | +import pytest |
| 11 | + |
| 12 | +pytest.importorskip("fastapi") |
| 13 | + |
| 14 | +from typer.testing import CliRunner # noqa: E402 |
| 15 | + |
| 16 | +from dlm_sway.cli.app import app # noqa: E402 |
| 17 | + |
| 18 | + |
| 19 | +def test_serve_in_help() -> None: |
| 20 | + result = CliRunner().invoke(app, ["--help"]) |
| 21 | + assert result.exit_code == 0 |
| 22 | + assert "serve" in result.stdout |
| 23 | + |
| 24 | + |
| 25 | +def test_serve_refuses_public_bind_without_api_key() -> None: |
| 26 | + result = CliRunner().invoke(app, ["serve", "--host", "0.0.0.0", "--port", "8787"]) |
| 27 | + assert result.exit_code == 2 |
| 28 | + # Mix of stdout/stderr depending on typer version; check both. |
| 29 | + combined = (result.stdout or "") + (result.stderr or "") |
| 30 | + assert "--api-key" in combined |
| 31 | + assert "0.0.0.0" in combined |
| 32 | + |
| 33 | + |
| 34 | +def test_serve_rejects_zero_max_loaded_models() -> None: |
| 35 | + result = CliRunner().invoke(app, ["serve", "--max-loaded-models", "0"]) |
| 36 | + assert result.exit_code == 2 |
| 37 | + |
| 38 | + |
| 39 | +def test_serve_rejects_invalid_port() -> None: |
| 40 | + result = CliRunner().invoke(app, ["serve", "--port", "0"]) |
| 41 | + assert result.exit_code != 0 |