Files
orion/tests/fixtures/module_fixtures.py
Samir Boulahtit d7a0ff8818 refactor: complete module-driven architecture migration
This commit completes the migration to a fully module-driven architecture:

## Models Migration
- Moved all domain models from models/database/ to their respective modules:
  - tenancy: User, Admin, Vendor, Company, Platform, VendorDomain, etc.
  - cms: MediaFile, VendorTheme
  - messaging: Email, VendorEmailSettings, VendorEmailTemplate
  - core: AdminMenuConfig
- models/database/ now only contains Base and TimestampMixin (infrastructure)

## Schemas Migration
- Moved all domain schemas from models/schema/ to their respective modules:
  - tenancy: company, vendor, admin, team, vendor_domain
  - cms: media, image, vendor_theme
  - messaging: email
- models/schema/ now only contains base.py and auth.py (infrastructure)

## Routes Migration
- Moved admin routes from app/api/v1/admin/ to modules:
  - menu_config.py -> core module
  - modules.py -> tenancy module
  - module_config.py -> tenancy module
- app/api/v1/admin/ now only aggregates auto-discovered module routes

## Menu System
- Implemented module-driven menu system with MenuDiscoveryService
- Extended FrontendType enum: PLATFORM, ADMIN, VENDOR, STOREFRONT
- Added MenuItemDefinition and MenuSectionDefinition dataclasses
- Each module now defines its own menu items in definition.py
- MenuService integrates with MenuDiscoveryService for template rendering

## Documentation
- Updated docs/architecture/models-structure.md
- Updated docs/architecture/menu-management.md
- Updated architecture validation rules for new exceptions

## Architecture Validation
- Updated MOD-019 rule to allow base.py in models/schema/
- Created core module exceptions.py and schemas/ directory
- All validation errors resolved (only warnings remain)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 21:02:56 +01:00

160 lines
4.5 KiB
Python

# tests/fixtures/module_fixtures.py
"""
Module system test fixtures.
Provides fixtures for testing platform module enablement, configuration,
and access control.
"""
import uuid
from datetime import datetime, timezone
import pytest
from app.modules.tenancy.models import Platform
from app.modules.tenancy.models import PlatformModule
@pytest.fixture
def platform_with_modules(db, test_super_admin):
"""Create a test platform with specific modules enabled."""
unique_id = str(uuid.uuid4())[:8]
platform = Platform(
code=f"modtest_{unique_id}",
name=f"Module Test Platform {unique_id}",
description="A test platform with module configuration",
path_prefix=f"modtest{unique_id}",
is_active=True,
is_public=True,
default_language="en",
supported_languages=["en", "fr"],
)
db.add(platform)
db.flush()
# Enable specific modules via junction table
enabled_modules = ["billing", "inventory", "orders"]
for module_code in enabled_modules:
pm = PlatformModule(
platform_id=platform.id,
module_code=module_code,
is_enabled=True,
enabled_at=datetime.now(timezone.utc),
enabled_by_user_id=test_super_admin.id,
config={},
)
db.add(pm)
# Add a disabled module
pm_disabled = PlatformModule(
platform_id=platform.id,
module_code="marketplace",
is_enabled=False,
disabled_at=datetime.now(timezone.utc),
disabled_by_user_id=test_super_admin.id,
config={},
)
db.add(pm_disabled)
db.commit()
db.refresh(platform)
return platform
@pytest.fixture
def platform_with_config(db, test_super_admin):
"""Create a test platform with module configuration."""
unique_id = str(uuid.uuid4())[:8]
platform = Platform(
code=f"cfgtest_{unique_id}",
name=f"Config Test Platform {unique_id}",
description="A test platform with module config",
path_prefix=f"cfgtest{unique_id}",
is_active=True,
is_public=True,
default_language="en",
supported_languages=["en"],
)
db.add(platform)
db.flush()
# Add module with configuration
pm = PlatformModule(
platform_id=platform.id,
module_code="billing",
is_enabled=True,
enabled_at=datetime.now(timezone.utc),
enabled_by_user_id=test_super_admin.id,
config={
"stripe_mode": "test",
"default_trial_days": 30,
"allow_free_tier": True,
},
)
db.add(pm)
# Add inventory module with config
pm_inv = PlatformModule(
platform_id=platform.id,
module_code="inventory",
is_enabled=True,
enabled_at=datetime.now(timezone.utc),
enabled_by_user_id=test_super_admin.id,
config={
"low_stock_threshold": 5,
"enable_locations": True,
},
)
db.add(pm_inv)
db.commit()
db.refresh(platform)
return platform
@pytest.fixture
def platform_all_modules_disabled(db, test_super_admin):
"""Create a test platform with all optional modules disabled."""
unique_id = str(uuid.uuid4())[:8]
platform = Platform(
code=f"nomod_{unique_id}",
name=f"No Modules Platform {unique_id}",
description="A test platform with minimal modules",
path_prefix=f"nomod{unique_id}",
is_active=True,
is_public=True,
default_language="en",
supported_languages=["en"],
settings={"enabled_modules": []}, # Legacy format for testing
)
db.add(platform)
db.commit()
db.refresh(platform)
return platform
@pytest.fixture
def module_factory(db, test_super_admin):
"""Factory for creating PlatformModule records."""
def _create_module(
platform_id: int,
module_code: str,
is_enabled: bool = True,
config: dict | None = None,
):
pm = PlatformModule(
platform_id=platform_id,
module_code=module_code,
is_enabled=is_enabled,
enabled_at=datetime.now(timezone.utc) if is_enabled else None,
enabled_by_user_id=test_super_admin.id if is_enabled else None,
disabled_at=None if is_enabled else datetime.now(timezone.utc),
disabled_by_user_id=None if is_enabled else test_super_admin.id,
config=config or {},
)
db.add(pm)
db.commit()
db.refresh(pm)
return pm
return _create_module