TorbatYar/backend/services/delivery/app/tests/test_architecture.py
Mortezakoohjani 5c6a2e78cf feat(platform): seed service registry, deploy all modules, and fix homepage catalog.
Register all active platform services and base features in core DB so admin can manage them, add delivery/hospitality/sports-center backend phases, update apps catalog and production deploy tooling.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-27 12:39:51 +03:30

191 lines
6.5 KiB
Python

"""Architecture tests — Delivery module boundary enforcement."""
from __future__ import annotations
import ast
import re
from pathlib import Path
from app.models import foundation as models
FORBIDDEN_IMPORT_PREFIXES = (
"backend.services.accounting",
"backend.services.crm",
"backend.services.loyalty",
"backend.services.communication",
"backend.services.sports_center",
"backend.services.automation",
"backend.services.notification",
"backend.services.file_storage",
"backend.services.identity_access",
"backend.core_service",
)
FOUNDATION_MODELS = [
models.DeliveryOrganization,
models.DeliveryHub,
models.DeliveryRole,
models.DeliveryPermission,
models.ExternalProviderConfig,
models.RoutingEngineRegistration,
models.DeliveryConfiguration,
models.DeliverySetting,
models.DeliveryAuditLog,
]
def test_all_models_have_tenant_id():
from app.core.database import Base
import app.models # noqa: F401
skip = {"alembic_version"}
for table in Base.metadata.tables.values():
if table.name in skip:
continue
assert "tenant_id" in table.columns, f"{table.name} missing tenant_id"
def test_foundation_aggregates_are_independent():
assert len(FOUNDATION_MODELS) == 9
for model in FOUNDATION_MODELS:
assert hasattr(model, "tenant_id")
assert hasattr(model, "id")
assert not model.__mapper__.relationships
def test_no_dispatch_engine_tables():
from app.core.database import Base
import app.models # noqa: F401
names = set(Base.metadata.tables.keys())
assert "drivers" in names
assert "driver_credentials" in names
assert "driver_documents" in names
assert "driver_lifecycle_events" in names
assert "outbox_events" in names
forbidden = {
"dispatch_jobs",
"routes",
"tracking_sessions",
"vehicles",
"fleets",
"proof_of_delivery",
}
assert forbidden.isdisjoint(names)
def test_permissions_defined():
from app.permissions.definitions import ALL_PERMISSIONS, PERMISSION_PREFIXES
assert "delivery.view" in ALL_PERMISSIONS
assert "delivery.organizations.create" in ALL_PERMISSIONS
assert "delivery.external_providers.manage" in ALL_PERMISSIONS
assert "delivery.routing_engines.view" in ALL_PERMISSIONS
assert "delivery.audit.view" in ALL_PERMISSIONS
assert "delivery.drivers.create" in ALL_PERMISSIONS
assert "delivery.drivers.activate" in ALL_PERMISSIONS
assert "delivery.drivers.credentials.manage" in ALL_PERMISSIONS
assert "delivery.dispatch.manage" in ALL_PERMISSIONS
for prefix in PERMISSION_PREFIXES:
assert any(p.startswith(prefix.rstrip(".")) or p.startswith(prefix) for p in ALL_PERMISSIONS)
def test_events_defined():
from app.events.types import DeliveryEventType
assert DeliveryEventType.ORGANIZATION_CREATED.value == "delivery.organization.created"
assert DeliveryEventType.HUB_CREATED.value == "delivery.hub.created"
assert (
DeliveryEventType.EXTERNAL_PROVIDER_REGISTERED.value
== "delivery.external_provider.registered"
)
assert (
DeliveryEventType.ROUTING_ENGINE_REGISTERED.value
== "delivery.routing_engine.registered"
)
assert DeliveryEventType.DRIVER_CREATED.value == "delivery.driver.created"
assert DeliveryEventType.DRIVER_ACTIVATED.value == "delivery.driver.activated"
assert DeliveryEventType.DRIVER_STATUS_CHANGED.value == "delivery.driver.status_changed"
def test_platform_provider_contracts_exist():
from app.providers import (
AIProvider,
AccountingProvider,
CRMProvider,
CommunicationProvider,
FleetProvider,
IdentityProvider,
LoyaltyProvider,
NotificationProvider,
RoutingEngineProvider,
StorageProvider,
)
assert AccountingProvider is not None
assert CommunicationProvider is not None
assert RoutingEngineProvider is not None
assert FleetProvider is not None
assert LoyaltyProvider is not None
assert CRMProvider is not None
assert NotificationProvider is not None
assert StorageProvider is not None
assert AIProvider is not None
assert IdentityProvider is not None
def test_no_forbidden_service_imports():
root = Path(__file__).resolve().parents[1]
violations: list[str] = []
for path in root.rglob("*.py"):
if "tests" in path.parts:
continue
tree = ast.parse(path.read_text(encoding="utf-8"), filename=str(path))
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for alias in node.names:
for forbidden in FORBIDDEN_IMPORT_PREFIXES:
if alias.name.startswith(forbidden) or forbidden in alias.name:
violations.append(f"{path}: import {alias.name}")
elif isinstance(node, ast.ImportFrom) and node.module:
for forbidden in FORBIDDEN_IMPORT_PREFIXES:
if node.module.startswith(forbidden) or forbidden in node.module:
violations.append(f"{path}: from {node.module}")
assert violations == []
def test_api_ownership_is_delivery_only():
from app.api.v1 import api_router
prefixes = {getattr(r, "path", "") for r in api_router.routes}
joined = " ".join(sorted(prefixes))
assert "/organizations" in joined or any("/organizations" in p for p in prefixes)
assert "/hubs" in joined or any("/hubs" in p for p in prefixes)
assert "/drivers" in joined or any("/drivers" in p for p in prefixes)
forbidden = ("accounting", "crm", "loyalty", "notification", "automation", "sports")
for name in forbidden:
assert not re.search(rf"(^|/){re.escape(name)}(/|$|\s)", joined), name
def test_folder_structure():
root = Path(__file__).resolve().parents[2]
required = [
"app/models",
"app/repositories",
"app/services",
"app/validators",
"app/schemas",
"app/events",
"app/permissions",
"app/providers",
"app/policies",
"app/specifications",
"app/commands",
"app/queries",
"app/api/v1",
"app/tests",
"alembic/versions",
"README.md",
]
for rel in required:
assert (root / rel).exists(), f"missing {rel}"