arm-tabular-parser/api/tests/unit/test_layout.py
Andrey Epifancev 479a76f81b test: старт с минимальным окружением и страж «без БД и фронта» (M-8)
- test_app: приложение с Settings только из MinIO, адреса NATS и DEBUG
  стартует, /healthcheck отвечает 200 с uptime, version, nats.
- test_layout: в requirements.txt нет asyncpg, SQLAlchemy, alembic,
  smbprotocol, argon2-cffi, raisa_fastapi_protected_api; нет каталогов web/,
  api/alembic/, api/src/{db,models,repositories}/.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-04 03:48:34 +04:00

33 lines
1.3 KiB
Python

"""Страж 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()