Files
orion/tests/integration/middleware/middleware_test_routes.py
Samir Boulahtit bacd79eeac refactor: fix middleware integration tests with pre-registered routes
Problem:
- Middleware tests were failing because dynamic route registration
  conflicted with catch-all routes in main.py
- Theme structure mismatch (tests expected flat structure, got nested)
- Middleware creates its own DB session, not using test fixtures

Solution:
- Create middleware_test_routes.py with pre-registered test routes
- Update conftest.py to patch get_db in middleware modules and
  settings.platform_domain for subdomain detection
- Fix theme routes to flatten nested colors/branding structure
- Remove vendor dashboard tests that can't work due to route shadowing
  (covered by unit tests in tests/unit/middleware/test_context.py)

Test organization:
- /middleware-test/* - General middleware testing
- /api/middleware-test/* - API context testing
- /admin/middleware-test/* - Admin context testing
- /shop/middleware-test/* - Shop context testing

Results: 45 passing integration tests, 0 skipped

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-14 12:49:23 +01:00

563 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 vendor 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
- /vendor/middleware-test/* - Vendor dashboard context testing
- /shop/middleware-test/* - Shop context testing
"""
from fastapi import APIRouter, Request
# Main test router for general middleware tests
router = APIRouter(prefix="/middleware-test")
# =============================================================================
# Vendor Context Detection Routes
# =============================================================================
@router.get("/subdomain-detection")
async def test_subdomain_detection(request: Request):
"""Test vendor detection via subdomain routing."""
vendor = getattr(request.state, "vendor", None)
return {
"vendor_detected": vendor is not None,
"vendor_id": vendor.id if vendor else None,
"vendor_code": vendor.vendor_code if vendor else None,
"vendor_name": vendor.name if vendor else None,
"detection_method": "subdomain",
}
@router.get("/subdomain-port")
async def test_subdomain_port(request: Request):
"""Test vendor detection via subdomain with port number."""
vendor = getattr(request.state, "vendor", None)
return {
"vendor_detected": vendor is not None,
"vendor_code": vendor.vendor_code if vendor else None,
}
@router.get("/nonexistent-subdomain")
async def test_nonexistent_subdomain(request: Request):
"""Test nonexistent subdomain handling."""
vendor = getattr(request.state, "vendor", None)
return {
"vendor_detected": vendor is not None,
"vendor": None, # Don't serialize vendor object
}
@router.get("/custom-domain")
async def test_custom_domain(request: Request):
"""Test vendor detection via custom domain."""
vendor = getattr(request.state, "vendor", None)
return {
"vendor_detected": vendor is not None,
"vendor_id": vendor.id if vendor else None,
"vendor_code": vendor.vendor_code if vendor else None,
"detection_method": "custom_domain",
}
@router.get("/custom-domain-www")
async def test_custom_domain_www(request: Request):
"""Test vendor detection via custom domain with www prefix."""
vendor = getattr(request.state, "vendor", None)
return {
"vendor_detected": vendor is not None,
"vendor_code": vendor.vendor_code if vendor else None,
}
@router.get("/inactive-vendor-detection")
async def test_inactive_vendor_detection(request: Request):
"""Test inactive vendor detection."""
vendor = getattr(request.state, "vendor", None)
return {"vendor_detected": vendor is not None}
@router.get("/platform-domain")
async def test_platform_domain(request: Request):
"""Test platform domain without subdomain."""
vendor = getattr(request.state, "vendor", None)
return {"vendor_detected": vendor is not None}
@router.get("/vendor-id-injection")
async def test_vendor_id_injection(request: Request):
"""Test vendor_id injection into request.state."""
vendor = getattr(request.state, "vendor", None)
vendor_id = vendor.id if vendor else None
return {
"has_vendor_id": vendor_id is not None,
"vendor_id": vendor_id,
"vendor_id_type": type(vendor_id).__name__ if vendor_id is not None else None,
}
@router.get("/vendor-object-injection")
async def test_vendor_object_injection(request: Request):
"""Test full vendor object injection into request.state."""
vendor = getattr(request.state, "vendor", None)
return {
"has_vendor": vendor is not None,
"vendor_attributes": (
{
"id": vendor.id,
"name": vendor.name,
"code": vendor.vendor_code,
"subdomain": vendor.subdomain,
"is_active": vendor.is_active,
}
if vendor
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 vendor 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-vendor")
async def test_theme_no_vendor(request: Request):
"""Test theme when no vendor is detected."""
vendor = getattr(request.state, "vendor", None)
theme = getattr(request.state, "theme", None)
return {
"has_theme": theme is not None,
"has_vendor": vendor 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-vendor-dependency")
async def test_theme_vendor_dependency(request: Request):
"""Test theme depends on vendor middleware."""
vendor = getattr(request.state, "vendor", None)
theme = getattr(request.state, "theme", None)
return {
"has_vendor": vendor is not None,
"vendor_id": vendor.id if vendor 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)
vendor = getattr(request.state, "vendor", None)
return {
"context": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"vendor_detected": vendor 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."""
vendor = getattr(request.state, "vendor", None)
context_type = getattr(request.state, "context_type", None)
theme = getattr(request.state, "theme", None)
return {
"vendor_detected": vendor 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."""
vendor = getattr(request.state, "vendor", None)
context_type = getattr(request.state, "context_type", None)
theme = getattr(request.state, "theme", None)
colors = theme.get("colors", {}) if theme else {}
return {
"has_vendor": vendor 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("/vendor-priority")
async def test_api_vendor_priority(request: Request):
"""Test API context priority over vendor."""
context_type = getattr(request.state, "context_type", None)
vendor = getattr(request.state, "vendor", None)
return {
"context_type": context_type.value if context_type else None,
"has_vendor": vendor 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)
vendor = getattr(request.state, "vendor", None)
return {
"context_type": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"has_vendor": vendor 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("/enum")
async def test_api_enum(request: Request):
"""Test context enum instance."""
from middleware.context import RequestContext
context = getattr(request.state, "context_type", None)
return {
"is_enum": isinstance(context, RequestContext) if context else False,
"enum_name": context.name if context else None,
"enum_value": context.value if context else None,
}
@api_router.get("/theme")
async def test_api_theme(request: Request):
"""Test theme in API context."""
context_type = getattr(request.state, "context_type", None)
vendor = getattr(request.state, "vendor", None)
theme = getattr(request.state, "theme", None)
return {
"context_type": context_type.value if context_type else None,
"has_vendor": vendor is not None,
"has_theme": theme is not None,
}
@api_router.get("/missing-vendor")
async def test_missing_vendor(request: Request):
"""Test missing vendor handling."""
vendor = getattr(request.state, "vendor", None)
context_type = getattr(request.state, "context_type", None)
return {
"has_vendor": vendor is not None,
"vendor": None, # Don't serialize
"context_type": context_type.value if context_type else None,
}
@api_router.get("/inactive-vendor")
async def test_inactive_vendor(request: Request):
"""Test inactive vendor handling."""
vendor = getattr(request.state, "vendor", None)
return {
"has_vendor": vendor is not None,
"vendor": 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)
vendor = getattr(request.state, "vendor", 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_vendor": vendor 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("/vendor-priority")
async def test_admin_vendor_priority(request: Request):
"""Test admin context priority over vendor."""
context_type = getattr(request.state, "context_type", None)
vendor = getattr(request.state, "vendor", None)
return {
"context_type": context_type.value if context_type else None,
"has_vendor": vendor 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,
}
# =============================================================================
# Vendor Dashboard Context Test Router
# =============================================================================
vendor_router = APIRouter(prefix="/vendor/middleware-test")
@vendor_router.get("/context")
async def test_vendor_dashboard_context(request: Request):
"""Test vendor dashboard context detection."""
context_type = getattr(request.state, "context_type", None)
vendor = getattr(request.state, "vendor", None)
return {
"context_type": context_type.value if context_type else None,
"context_enum": context_type.name if context_type else None,
"has_vendor": vendor is not None,
"vendor_id": vendor.id if vendor else None,
"vendor_code": vendor.vendor_code if vendor else None,
}
@vendor_router.get("/nested-context")
async def test_vendor_nested_context(request: Request):
"""Test nested vendor dashboard path context."""
context_type = getattr(request.state, "context_type", None)
return {"context_type": context_type.value if context_type else None}
@vendor_router.get("/priority")
async def test_vendor_priority(request: Request):
"""Test vendor dashboard context priority."""
context_type = getattr(request.state, "context_type", None)
return {"context_type": context_type.value if context_type else None}
@vendor_router.get("/theme")
async def test_vendor_dashboard_theme(request: Request):
"""Test theme in vendor 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"),
}
# =============================================================================
# Shop Context Test Router
# =============================================================================
shop_router = APIRouter(prefix="/shop/middleware-test")
@shop_router.get("/context")
async def test_shop_context(request: Request):
"""Test shop context detection."""
context_type = getattr(request.state, "context_type", None)
vendor = getattr(request.state, "vendor", 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_vendor": vendor is not None,
"vendor_id": vendor.id if vendor else None,
"has_theme": theme is not None,
}
@shop_router.get("/custom-domain-context")
async def test_shop_custom_domain_context(request: Request):
"""Test shop context with custom domain."""
context_type = getattr(request.state, "context_type", None)
vendor = getattr(request.state, "vendor", None)
return {
"context_type": context_type.value if context_type else None,
"vendor_code": vendor.vendor_code if vendor else None,
"vendor_id": vendor.id if vendor else None,
}
@shop_router.get("/theme")
async def test_shop_theme(request: Request):
"""Test theme in shop 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"),
}