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>
This commit is contained in:
110
tests/integration/middleware/README.md
Normal file
110
tests/integration/middleware/README.md
Normal file
@@ -0,0 +1,110 @@
|
||||
# Middleware Integration Tests
|
||||
|
||||
## Overview
|
||||
|
||||
These tests verify that the middleware stack (VendorContextMiddleware, ThemeContextMiddleware, ContextMiddleware) works correctly through real HTTP requests.
|
||||
|
||||
## Test Status
|
||||
|
||||
| Test File | Status | Tests |
|
||||
|-----------|--------|-------|
|
||||
| `test_vendor_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.vendor_context.get_db", override_get_db):
|
||||
with patch("middleware.theme_context.get_db", override_get_db):
|
||||
with patch("middleware.vendor_context.settings") as mock_settings:
|
||||
mock_settings.platform_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 `testvendor.platform.com` work correctly
|
||||
|
||||
## Vendor Dashboard Context Testing
|
||||
|
||||
Vendor dashboard context detection (`/vendor/*` paths → `VENDOR_DASHBOARD` context) is tested via **unit tests** rather than integration tests because:
|
||||
|
||||
1. The `/vendor/{vendor_code}/{slug}` catch-all route in `main.py` intercepts `/vendor/middleware-test/*` paths
|
||||
2. Unit tests in `tests/unit/middleware/test_context.py` provide comprehensive coverage:
|
||||
- `test_detect_vendor_dashboard_context`
|
||||
- `test_detect_vendor_dashboard_context_direct_path`
|
||||
- `test_vendor_dashboard_priority_over_shop`
|
||||
- `test_middleware_sets_vendor_dashboard_context`
|
||||
|
||||
## Testing Patterns
|
||||
|
||||
### Subdomain Detection
|
||||
|
||||
Use hosts ending in `.platform.com`:
|
||||
|
||||
```python
|
||||
response = client.get(
|
||||
"/middleware-test/subdomain-detection",
|
||||
headers={"host": "myvendor.platform.com"}
|
||||
)
|
||||
```
|
||||
|
||||
### Custom Domain Detection
|
||||
|
||||
Custom domains require `is_verified=True` in the `VendorDomain` fixture:
|
||||
|
||||
```python
|
||||
domain = VendorDomain(
|
||||
vendor_id=vendor.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
|
||||
```
|
||||
Reference in New Issue
Block a user