Some checks failed
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>
111 lines
3.3 KiB
Markdown
111 lines
3.3 KiB
Markdown
# Middleware Integration Tests
|
|
|
|
## Overview
|
|
|
|
These tests verify that the middleware stack (StoreContextMiddleware, ThemeContextMiddleware, ContextMiddleware) works correctly through real HTTP requests.
|
|
|
|
## Test Status
|
|
|
|
| Test File | Status | Tests |
|
|
|-----------|--------|-------|
|
|
| `test_store_context_flow.py` | ✅ Passing | 9 tests |
|
|
| `test_theme_loading_flow.py` | ✅ Passing | 14 tests |
|
|
| `test_middleware_stack.py` | ✅ Passing | 10 tests |
|
|
| `test_context_detection_flow.py` | ✅ Passing | 12 tests |
|
|
|
|
**Total: 45 passing integration tests**
|
|
|
|
## Architecture
|
|
|
|
### Pre-registered Test Routes
|
|
|
|
All test routes are defined in `middleware_test_routes.py` and registered at module load time. This avoids conflicts with catch-all routes in `main.py`.
|
|
|
|
Routes are organized by prefix:
|
|
- `/middleware-test/*` - General middleware testing
|
|
- `/api/middleware-test/*` - API context testing
|
|
- `/admin/middleware-test/*` - Admin context testing
|
|
- `/shop/middleware-test/*` - Shop context testing
|
|
|
|
### Test Fixtures (`conftest.py`)
|
|
|
|
The `client` fixture patches middleware dependencies for proper test isolation:
|
|
|
|
```python
|
|
@pytest.fixture
|
|
def client(db):
|
|
with patch("middleware.store_context.get_db", override_get_db):
|
|
with patch("middleware.theme_context.get_db", override_get_db):
|
|
with patch("middleware.store_context.settings") as mock_settings:
|
|
mock_settings.main_domain = "platform.com"
|
|
client = TestClient(app)
|
|
yield client
|
|
```
|
|
|
|
This ensures:
|
|
1. **Database isolation**: Middleware uses the test database session
|
|
2. **Subdomain detection**: `platform.com` is used so hosts like `teststore.platform.com` work correctly
|
|
|
|
## Store Dashboard Context Testing
|
|
|
|
Store dashboard context detection (`/store/*` paths → `STORE_DASHBOARD` context) is tested via **unit tests** rather than integration tests because:
|
|
|
|
1. The `/store/{store_code}/{slug}` catch-all route in `main.py` intercepts `/store/middleware-test/*` paths
|
|
2. Unit tests in `tests/unit/middleware/test_context.py` provide comprehensive coverage:
|
|
- `test_detect_store_dashboard_context`
|
|
- `test_detect_store_dashboard_context_direct_path`
|
|
- `test_store_dashboard_priority_over_shop`
|
|
- `test_middleware_sets_store_dashboard_context`
|
|
|
|
## Testing Patterns
|
|
|
|
### Subdomain Detection
|
|
|
|
Use hosts ending in `.platform.com`:
|
|
|
|
```python
|
|
response = client.get(
|
|
"/middleware-test/subdomain-detection",
|
|
headers={"host": "mystore.platform.com"}
|
|
)
|
|
```
|
|
|
|
### Custom Domain Detection
|
|
|
|
Custom domains require `is_verified=True` in the `StoreDomain` fixture:
|
|
|
|
```python
|
|
domain = StoreDomain(
|
|
store_id=store.id,
|
|
domain="customdomain.com",
|
|
is_active=True,
|
|
is_primary=True,
|
|
is_verified=True # Required for detection
|
|
)
|
|
```
|
|
|
|
### Context Type Verification
|
|
|
|
Routes return context information for assertions:
|
|
|
|
```python
|
|
response = client.get("/api/middleware-test/context")
|
|
data = response.json()
|
|
assert data["context_type"] == "api"
|
|
assert data["context_enum"] == "API"
|
|
```
|
|
|
|
### Theme Structure
|
|
|
|
Theme data uses nested structure:
|
|
- `theme["colors"]["primary"]` - Primary color
|
|
- `theme["branding"]["logo"]` - Logo URL
|
|
- `theme["custom_css"]` - Custom CSS
|
|
|
|
Test routes flatten this for easier assertions:
|
|
|
|
```python
|
|
data = response.json()
|
|
assert data["primary_color"] == "#FF5733" # Flattened from colors.primary
|
|
```
|