diff --git a/api/tests/unit/test_app.py b/api/tests/unit/test_app.py index 48e34c3..77e214e 100644 --- a/api/tests/unit/test_app.py +++ b/api/tests/unit/test_app.py @@ -143,6 +143,20 @@ async def test_nats_disabled_starts_nothing_and_healthcheck_reports_off( assert events == ["s3.close"] +async def test_minimal_environment_starts_and_healthcheck_answers( + patched_app: Any, monkeypatch: pytest.MonkeyPatch, minimal_settings: Callable[..., Any] +) -> None: + """Старт с минимальным окружением: только MinIO, адрес NATS и DEBUG (без seed/jwt, БД и SMB).""" + monkeypatch.setattr(patched_app, "settings", minimal_settings()) + assert patched_app.settings.NATS_ENABLED is True + + async with running_app(patched_app) as client: + response = await client.get("/healthcheck") + + assert response.status_code == 200 # noqa: PLR2004 - HTTP 200 + assert set(response.json()) == {"uptime", "version", "nats"} + + async def test_nats_enabled_subscribes_worker_and_reports_ok( patched_app: Any, monkeypatch: pytest.MonkeyPatch, events: list[str] ) -> None: diff --git a/api/tests/unit/test_layout.py b/api/tests/unit/test_layout.py new file mode 100644 index 0000000..6a60a4b --- /dev/null +++ b/api/tests/unit/test_layout.py @@ -0,0 +1,32 @@ +"""Страж spec «Сервис не зависит от БД и фронта» (DECISION-4): ни зависимостей БД/SMB/шаблонной авторизации, ни +каталогов фронта, миграций, моделей и репозиториев.""" + +import re +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parents[3] +REQUIREMENTS = REPO_ROOT / "api" / "requirements.txt" +FORBIDDEN_PACKAGES = ( + "asyncpg", + "sqlalchemy", + "alembic", + "smbprotocol", + "argon2-cffi", + "raisa_fastapi_protected_api", +) +FORBIDDEN_DIRS = ("web", "api/alembic", "api/src/db", "api/src/models", "api/src/repositories") + + +@pytest.mark.parametrize("package", FORBIDDEN_PACKAGES) +def test_requirements_have_no_database_or_template_auth_packages(package: str) -> None: + name = re.sub(r"[-_.]", "[-_.]", package) # имена пакетов сравниваются по PEP 503: -, _ и . равнозначны + pattern = re.compile(rf"^\s*{name}\s*(?:[=<>!~;\[]|$)", re.IGNORECASE) + lines = REQUIREMENTS.read_text(encoding="utf-8").splitlines() + assert not [line for line in lines if pattern.match(line)] + + +@pytest.mark.parametrize("directory", FORBIDDEN_DIRS) +def test_no_frontend_or_database_directories(directory: str) -> None: + assert not (REPO_ROOT / directory).exists()