Files
orion/tests/integration/middleware/middleware_test_routes.py
Samir Boulahtit c2c0e3c740
Some checks failed
CI / ruff (push) Successful in 10s
CI / validate (push) Has been cancelled
CI / dependency-scanning (push) Has been cancelled
CI / docs (push) Has been cancelled
CI / deploy (push) Has been cancelled
CI / pytest (push) Has started running
refactor: rename platform_domain → main_domain to avoid confusion with platform.domain
The setting `settings.platform_domain` (the global/main domain like "wizard.lu")
was easily confused with `platform.domain` (per-platform domain like "rewardflow.lu").
Renamed to `settings.main_domain` / `MAIN_DOMAIN` env var across the entire codebase.

Also updated docs to reflect the refactored store detection logic with
`is_platform_domain` / `is_subdomain_of_platform` guards.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-14 04:45:28 +01:00

565 lines
20 KiB
Python

# tests/integration/middleware/middleware_test_routes.py
"""
Test routes for middleware integration tests.
These routes are registered at module load time and used by middleware tests
to verify that store context, theme, and other middleware features work correctly.
IMPORTANT: Routes are organized by prefix to avoid conflicts:
- /middleware-test/* - General middleware testing
- /api/middleware-test/* - API context testing
- /admin/middleware-test/* - Admin context testing
- /store/middleware-test/* - Store dashboard context testing
- /storefront/middleware-test/* - Storefront context testing
"""
from fastapi import APIRouter, Request
# Main test router for general middleware tests
router = APIRouter(prefix="/middleware-test")
# =============================================================================
# Store Context Detection Routes
# =============================================================================
@router.get("/subdomain-detection")
async def test_subdomain_detection(request: Request):
"""Test store detection via subdomain routing."""
store = getattr(request.state, "store", None)
return {
"store_detected": store is not None,
"store_id": store.id if store else None,
"store_code": store.store_code if store else None,
"store_name": store.name if store else None,
"detection_method": "subdomain",
}
@router.get("/subdomain-port")
async def test_subdomain_port(request: Request):
"""Test store detection via subdomain with port number."""
store = getattr(request.state, "store", None)
return {
"store_detected": store is not None,
"store_code": store.store_code if store else None,
}
@router.get("/nonexistent-subdomain")
async def test_nonexistent_subdomain(request: Request):
"""Test nonexistent subdomain handling."""
store = getattr(request.state, "store", None)
return {
"store_detected": store is not None,
"store": None, # Don't serialize store object
}
@router.get("/custom-domain")
async def test_custom_domain(request: Request):
"""Test store detection via custom domain."""
store = getattr(request.state, "store", None)
return {
"store_detected": store is not None,
"store_id": store.id if store else None,
"store_code": store.store_code if store else None,
"detection_method": "custom_domain",
}
@router.get("/custom-domain-www")
async def test_custom_domain_www(request: Request):
"""Test store detection via custom domain with www prefix."""
store = getattr(request.state, "store", None)
return {
"store_detected": store is not None,
"store_code": store.store_code if store else None,
}
@router.get("/merchant-domain-detection")
async def test_merchant_domain_detection(request: Request):
"""Test store detection via merchant domain routing."""
store = getattr(request.state, "store", None)
store_context = getattr(request.state, "store_context", None)
return {
"store_detected": store is not None,
"store_id": store.id if store else None,
"store_code": store.store_code if store else None,
"store_name": store.name if store else None,
"merchant_domain": store_context.get("merchant_domain") if store_context else None,
"merchant_id": store_context.get("merchant_id") if store_context else None,
}
@router.get("/inactive-store-detection")
async def test_inactive_store_detection(request: Request):
"""Test inactive store detection."""
store = getattr(request.state, "store", None)
return {"store_detected": store is not None}
@router.get("/platform-domain")
async def test_main_domain(request: Request):
"""Test platform domain without subdomain."""
store = getattr(request.state, "store", None)
return {"store_detected": store is not None}
@router.get("/store-id-injection")
async def test_store_id_injection(request: Request):
"""Test store_id injection into request.state."""
store = getattr(request.state, "store", None)
store_id = store.id if store else None
return {
"has_store_id": store_id is not None,
"store_id": store_id,
"store_id_type": type(store_id).__name__ if store_id is not None else None,
}
@router.get("/store-object-injection")
async def test_store_object_injection(request: Request):
"""Test full store object injection into request.state."""
store = getattr(request.state, "store", None)
return {
"has_store": store is not None,
"store_attributes": (
{
"id": store.id,
"name": store.name,
"code": store.store_code,
"subdomain": store.subdomain,
"is_active": store.is_active,
}
if store
else None
),
}
# =============================================================================
# Theme Loading Routes
# Note: Theme structure is: {"colors": {"primary": ..., "secondary": ...}, "branding": {"logo": ...}, ...}
# =============================================================================
@router.get("/theme-loading")
async def test_theme_loading(request: Request):
"""Test theme loading - full theme data."""
theme = getattr(request.state, "theme", None)
# Flatten theme for easier testing
if theme:
colors = theme.get("colors", {})
branding = theme.get("branding", {})
return {
"has_theme": True,
"theme_data": theme,
"primary_color": colors.get("primary"),
"secondary_color": colors.get("secondary"),
"logo_url": branding.get("logo"),
"favicon_url": branding.get("favicon"),
"custom_css": theme.get("custom_css"),
}
return {"has_theme": False, "theme_data": None}
@router.get("/theme-default")
async def test_theme_default(request: Request):
"""Test default theme for store without custom theme."""
theme = getattr(request.state, "theme", None)
if theme:
colors = theme.get("colors", {})
return {
"has_theme": True,
"theme_data": theme,
"primary_color": colors.get("primary"),
"secondary_color": colors.get("secondary"),
}
return {"has_theme": False, "theme_data": None}
@router.get("/theme-no-store")
async def test_theme_no_store(request: Request):
"""Test theme when no store is detected."""
store = getattr(request.state, "store", None)
theme = getattr(request.state, "theme", None)
return {
"has_theme": theme is not None,
"has_store": store is not None,
}
@router.get("/theme-fields")
async def test_theme_fields(request: Request):
"""Test theme contains all expected fields."""
theme = getattr(request.state, "theme", {}) or {}
colors = theme.get("colors", {})
branding = theme.get("branding", {})
return {
"primary_color": colors.get("primary"),
"secondary_color": colors.get("secondary"),
"logo_url": branding.get("logo"),
"favicon_url": branding.get("favicon"),
"custom_css": theme.get("custom_css"),
}
@router.get("/theme-structure")
async def test_theme_structure(request: Request):
"""Test theme structure."""
theme = getattr(request.state, "theme", {}) or {}
colors = theme.get("colors", {})
branding = theme.get("branding", {})
return {
"has_primary_color": "primary" in colors,
"has_secondary_color": "secondary" in colors,
"has_logo_url": "logo" in branding,
"has_favicon_url": "favicon" in branding,
"has_custom_css": "custom_css" in theme,
}
@router.get("/theme-partial")
async def test_theme_partial(request: Request):
"""Test partial theme handling."""
theme = getattr(request.state, "theme", {}) or {}
colors = theme.get("colors", {})
branding = theme.get("branding", {})
return {
"has_theme": bool(theme),
"primary_color": colors.get("primary", "default"),
"logo_url": branding.get("logo", "default"),
}
@router.get("/theme-consistency")
async def test_theme_consistency(request: Request):
"""Test theme consistency across requests."""
theme = getattr(request.state, "theme", {}) or {}
colors = theme.get("colors", {})
return {"theme_primary": colors.get("primary")}
@router.get("/theme-mutable")
async def test_theme_mutable(request: Request):
"""Test theme dict can be read."""
theme = getattr(request.state, "theme", {}) or {}
colors = theme.get("colors", {})
primary = colors.get("primary")
return {"can_read": primary is not None, "value": primary}
@router.get("/theme-store-dependency")
async def test_theme_store_dependency(request: Request):
"""Test theme depends on store middleware."""
store = getattr(request.state, "store", None)
theme = getattr(request.state, "theme", None)
return {
"has_store": store is not None,
"store_id": store.id if store else None,
"has_theme": theme is not None,
}
# =============================================================================
# Context Detection Routes
# =============================================================================
@router.get("/context-detection")
async def test_context_detection(request: Request):
"""Test context detection."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
return {
"context": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"store_detected": store is not None,
"clean_path": getattr(request.state, "clean_path", None),
}
# =============================================================================
# Middleware Order Routes
# =============================================================================
@router.get("/middleware-order")
async def test_middleware_order(request: Request):
"""Test middleware execution order."""
store = getattr(request.state, "store", None)
context_type = getattr(request.state, "context_type", None)
theme = getattr(request.state, "theme", None)
return {
"store_detected": store is not None,
"context": context_type.value if context_type else None,
"theme_loaded": theme is not None,
"clean_path": getattr(request.state, "clean_path", None),
"has_clean_path": hasattr(request.state, "clean_path"),
"has_context_type": context_type is not None,
}
@router.get("/execution-order")
async def test_execution_order(request: Request):
"""Test middleware execution order - detailed."""
store = getattr(request.state, "store", None)
context_type = getattr(request.state, "context_type", None)
theme = getattr(request.state, "theme", None)
colors = theme.get("colors", {}) if theme else {}
return {
"has_store": store is not None,
"has_clean_path": hasattr(request.state, "clean_path"),
"has_context_type": context_type is not None,
"has_theme": theme is not None,
"theme_primary_color": colors.get("primary"),
}
# =============================================================================
# API Context Test Router
# =============================================================================
api_router = APIRouter(prefix="/api/middleware-test")
@api_router.get("/context")
async def test_api_context(request: Request):
"""Test API context detection."""
context_type = getattr(request.state, "context_type", None)
return {
"context_type": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
}
@api_router.get("/nested-context")
async def test_nested_api_context(request: Request):
"""Test nested API path context."""
context_type = getattr(request.state, "context_type", None)
return {"context_type": context_type.value if context_type else None}
@api_router.get("/store-priority")
async def test_api_store_priority(request: Request):
"""Test API context priority over store."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
return {
"context_type": context_type.value if context_type else None,
"has_store": store is not None,
}
@api_router.get("/fallback-context")
async def test_fallback_context(request: Request):
"""Test fallback context."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
return {
"context_type": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"has_store": store is not None,
}
@api_router.get("/clean-path-context")
async def test_clean_path_context(request: Request):
"""Test clean path context detection."""
context_type = getattr(request.state, "context_type", None)
return {
"context_type": context_type.value if context_type else None,
"clean_path": getattr(request.state, "clean_path", None),
"original_path": request.url.path,
}
@api_router.get("/theme")
async def test_api_theme(request: Request):
"""Test theme in API context."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
theme = getattr(request.state, "theme", None)
return {
"context_type": context_type.value if context_type else None,
"has_store": store is not None,
"has_theme": theme is not None,
}
@api_router.get("/missing-store")
async def test_missing_store(request: Request):
"""Test missing store handling."""
store = getattr(request.state, "store", None)
context_type = getattr(request.state, "context_type", None)
return {
"has_store": store is not None,
"store": None, # Don't serialize
"context_type": context_type.value if context_type else None,
}
@api_router.get("/inactive-store")
async def test_inactive_store(request: Request):
"""Test inactive store handling."""
store = getattr(request.state, "store", None)
return {
"has_store": store is not None,
"store": None, # Don't serialize
}
@api_router.get("/admin-subdomain-context")
async def test_admin_subdomain_context(request: Request):
"""Test admin subdomain context."""
context_type = getattr(request.state, "context_type", None)
return {"context_type": context_type.value if context_type else None}
# =============================================================================
# Admin Context Test Router
# =============================================================================
admin_router = APIRouter(prefix="/admin/middleware-test")
@admin_router.get("/context")
async def test_admin_context(request: Request):
"""Test admin context detection."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
theme = getattr(request.state, "theme", None)
return {
"context_type": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"has_store": store is not None,
"has_theme": theme is not None,
}
@admin_router.get("/nested-context")
async def test_admin_nested_context(request: Request):
"""Test nested admin path context."""
context_type = getattr(request.state, "context_type", None)
return {"context_type": context_type.value if context_type else None}
@admin_router.get("/store-priority")
async def test_admin_store_priority(request: Request):
"""Test admin context priority over store."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
return {
"context_type": context_type.value if context_type else None,
"has_store": store is not None,
}
@admin_router.get("/no-theme")
async def test_admin_no_theme(request: Request):
"""Test admin context has no theme."""
context_type = getattr(request.state, "context_type", None)
theme = getattr(request.state, "theme", None)
return {
"context_type": context_type.value if context_type else None,
"has_theme": theme is not None,
}
# =============================================================================
# Store Dashboard Context Test Router
# =============================================================================
store_router = APIRouter(prefix="/store/middleware-test")
@store_router.get("/context")
async def test_store_dashboard_context(request: Request):
"""Test store dashboard context detection."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
return {
"context_type": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"has_store": store is not None,
"store_id": store.id if store else None,
"store_code": store.store_code if store else None,
}
@store_router.get("/nested-context")
async def test_store_nested_context(request: Request):
"""Test nested store dashboard path context."""
context_type = getattr(request.state, "context_type", None)
return {"context_type": context_type.value if context_type else None}
@store_router.get("/priority")
async def test_store_priority(request: Request):
"""Test store dashboard context priority."""
context_type = getattr(request.state, "context_type", None)
return {"context_type": context_type.value if context_type else None}
@store_router.get("/theme")
async def test_store_dashboard_theme(request: Request):
"""Test theme in store dashboard context."""
context_type = getattr(request.state, "context_type", None)
theme = getattr(request.state, "theme", None)
colors = theme.get("colors", {}) if theme else {}
return {
"context_type": context_type.value if context_type else None,
"has_theme": theme is not None,
"theme_secondary": colors.get("secondary"),
}
# =============================================================================
# Storefront Context Test Router
# =============================================================================
storefront_router = APIRouter(prefix="/storefront/middleware-test")
@storefront_router.get("/context")
async def test_storefront_context(request: Request):
"""Test storefront context detection."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
theme = getattr(request.state, "theme", None)
return {
"context_type": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"has_store": store is not None,
"store_id": store.id if store else None,
"has_theme": theme is not None,
}
@storefront_router.get("/custom-domain-context")
async def test_storefront_custom_domain_context(request: Request):
"""Test storefront context with custom domain."""
context_type = getattr(request.state, "context_type", None)
store = getattr(request.state, "store", None)
return {
"context_type": context_type.value if context_type else None,
"store_code": store.store_code if store else None,
"store_id": store.id if store else None,
}
@storefront_router.get("/theme")
async def test_storefront_theme(request: Request):
"""Test theme in storefront context."""
context_type = getattr(request.state, "context_type", None)
theme = getattr(request.state, "theme", None)
colors = theme.get("colors", {}) if theme else {}
return {
"context_type": context_type.value if context_type else None,
"has_theme": theme is not None,
"theme_primary": colors.get("primary"),
}