Files
meshcore-hub/tests/test_api/test_cli.py
T

91 lines
3.1 KiB
Python

"""Tests for the API CLI command (server launch wiring)."""
from unittest.mock import patch
from click.testing import CliRunner
from meshcore_hub.api.cli import api
# Opaque URL: satisfies the fail-fast database check; nothing connects
# (uvicorn.run is mocked, so the lifespan never starts).
_TEST_DB_URL = "postgresql+psycopg2://meshcorehub:pw@localhost:5432/meshcorehub"
def test_api_default_runs_single_process():
"""With the default worker count, the app object is passed directly and no
worker/factory options are used."""
runner = CliRunner()
with patch("uvicorn.run") as mock_run:
result = runner.invoke(
api, ["--database-url", _TEST_DB_URL], catch_exceptions=False
)
assert result.exit_code == 0
assert mock_run.call_count == 1
args, kwargs = mock_run.call_args
# Single-process path passes the built app object, not an import string.
assert not isinstance(args[0], str)
assert "workers" not in kwargs
def test_api_workers_uses_env_factory_import_string():
"""workers > 1 launches uvicorn against the env-driven factory by import
string with the requested worker count."""
runner = CliRunner()
with patch("uvicorn.run") as mock_run:
result = runner.invoke(
api,
["--database-url", _TEST_DB_URL, "--workers", "3"],
catch_exceptions=False,
)
assert result.exit_code == 0
args, kwargs = mock_run.call_args
assert args[0] == "meshcore_hub.api.app:create_app_from_env"
assert kwargs["workers"] == 3
assert kwargs["factory"] is True
def test_api_workers_from_env_var():
"""API_WORKERS env var drives the worker count (the Docker path)."""
runner = CliRunner()
with patch("uvicorn.run") as mock_run:
result = runner.invoke(
api,
["--database-url", _TEST_DB_URL],
env={"API_WORKERS": "2"},
catch_exceptions=False,
)
assert result.exit_code == 0
_, kwargs = mock_run.call_args
assert kwargs["workers"] == 2
def test_api_single_process_passes_spam_and_role_settings():
"""The single-process app must carry the env-configured spam + OIDC role
settings — previously this path dropped them, silently disabling the
spam hide-filter and custom role names (the env factory path was fine)."""
runner = CliRunner()
with patch("uvicorn.run") as mock_run:
result = runner.invoke(
api,
["--database-url", _TEST_DB_URL],
env={
"SPAM_DETECTION_ENABLED": "true",
"SPAM_SCORE_THRESHOLD": "0.8",
"OIDC_ROLE_ADMIN": "superadmin",
"OIDC_ROLE_OPERATOR": "moderator",
"OIDC_ROLE_MEMBER": "user",
},
catch_exceptions=False,
)
assert result.exit_code == 0
app = mock_run.call_args[0][0]
assert app.state.spam_detection_enabled is True
assert app.state.spam_score_threshold == 0.8
assert app.state.oidc_role_admin == "superadmin"
assert app.state.oidc_role_operator == "moderator"
assert app.state.oidc_role_member == "user"