style: apply black and isort formatting across entire codebase
- Standardize quote style (single to double quotes) - Reorder and group imports alphabetically - Fix line breaks and indentation for consistency - Apply PEP 8 formatting standards Also updated Makefile to exclude both venv and .venv from code quality checks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5,8 +5,10 @@ Integration tests for request context detection end-to-end flow.
|
||||
These tests verify that context type (API, ADMIN, VENDOR_DASHBOARD, SHOP, FALLBACK)
|
||||
is correctly detected through real HTTP requests.
|
||||
"""
|
||||
import pytest
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from middleware.context import RequestContext
|
||||
|
||||
|
||||
@@ -23,13 +25,22 @@ class TestContextDetectionFlow:
|
||||
def test_api_path_detected_as_api_context(self, client):
|
||||
"""Test that /api/* paths are detected as API context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/api/test-api-context")
|
||||
async def test_api(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"context_enum": request.state.context_type.name if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"context_enum": (
|
||||
request.state.context_type.name
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
}
|
||||
|
||||
response = client.get("/api/test-api-context")
|
||||
@@ -42,12 +53,17 @@ class TestContextDetectionFlow:
|
||||
def test_nested_api_path_detected_as_api_context(self, client):
|
||||
"""Test that nested /api/ paths are detected as API context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/api/v1/vendor/products")
|
||||
async def test_nested_api(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
)
|
||||
}
|
||||
|
||||
response = client.get("/api/v1/vendor/products")
|
||||
@@ -63,13 +79,22 @@ class TestContextDetectionFlow:
|
||||
def test_admin_path_detected_as_admin_context(self, client):
|
||||
"""Test that /admin/* paths are detected as ADMIN context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/admin/test-admin-context")
|
||||
async def test_admin(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"context_enum": request.state.context_type.name if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"context_enum": (
|
||||
request.state.context_type.name
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
}
|
||||
|
||||
response = client.get("/admin/test-admin-context")
|
||||
@@ -82,19 +107,23 @@ class TestContextDetectionFlow:
|
||||
def test_admin_subdomain_detected_as_admin_context(self, client):
|
||||
"""Test that admin.* subdomain is detected as ADMIN context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/test-admin-subdomain-context")
|
||||
async def test_admin_subdomain(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
)
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/test-admin-subdomain-context",
|
||||
headers={"host": "admin.platform.com"}
|
||||
"/test-admin-subdomain-context", headers={"host": "admin.platform.com"}
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -104,12 +133,17 @@ class TestContextDetectionFlow:
|
||||
def test_nested_admin_path_detected_as_admin_context(self, client):
|
||||
"""Test that nested /admin/ paths are detected as ADMIN context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/admin/vendors/123/edit")
|
||||
async def test_nested_admin(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
)
|
||||
}
|
||||
|
||||
response = client.get("/admin/vendors/123/edit")
|
||||
@@ -125,21 +159,31 @@ class TestContextDetectionFlow:
|
||||
def test_vendor_dashboard_path_detected(self, client, vendor_with_subdomain):
|
||||
"""Test that /vendor/* paths are detected as VENDOR_DASHBOARD context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/vendor/test-vendor-dashboard")
|
||||
async def test_vendor_dashboard(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"context_enum": request.state.context_type.name if hasattr(request.state, 'context_type') else None,
|
||||
"has_vendor": hasattr(request.state, 'vendor') and request.state.vendor is not None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"context_enum": (
|
||||
request.state.context_type.name
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"has_vendor": hasattr(request.state, "vendor")
|
||||
and request.state.vendor is not None,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/vendor/test-vendor-dashboard",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -151,19 +195,24 @@ class TestContextDetectionFlow:
|
||||
def test_nested_vendor_dashboard_path_detected(self, client, vendor_with_subdomain):
|
||||
"""Test that nested /vendor/ paths are detected as VENDOR_DASHBOARD context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/vendor/products/123/edit")
|
||||
async def test_nested_vendor(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
)
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/vendor/products/123/edit",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -174,24 +223,36 @@ class TestContextDetectionFlow:
|
||||
# Shop Context Detection Tests
|
||||
# ========================================================================
|
||||
|
||||
def test_shop_path_with_vendor_detected_as_shop(self, client, vendor_with_subdomain):
|
||||
def test_shop_path_with_vendor_detected_as_shop(
|
||||
self, client, vendor_with_subdomain
|
||||
):
|
||||
"""Test that /shop/* paths with vendor are detected as SHOP context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/shop/test-shop-context")
|
||||
async def test_shop(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"context_enum": request.state.context_type.name if hasattr(request.state, 'context_type') else None,
|
||||
"has_vendor": hasattr(request.state, 'vendor') and request.state.vendor is not None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"context_enum": (
|
||||
request.state.context_type.name
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"has_vendor": hasattr(request.state, "vendor")
|
||||
and request.state.vendor is not None,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/shop/test-shop-context",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -200,23 +261,31 @@ class TestContextDetectionFlow:
|
||||
assert data["context_enum"] == "SHOP"
|
||||
assert data["has_vendor"] is True
|
||||
|
||||
def test_root_path_with_vendor_detected_as_shop(self, client, vendor_with_subdomain):
|
||||
def test_root_path_with_vendor_detected_as_shop(
|
||||
self, client, vendor_with_subdomain
|
||||
):
|
||||
"""Test that root path with vendor is detected as SHOP context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/test-root-shop")
|
||||
async def test_root_shop(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"has_vendor": hasattr(request.state, 'vendor') and request.state.vendor is not None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"has_vendor": hasattr(request.state, "vendor")
|
||||
and request.state.vendor is not None,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/test-root-shop",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -228,21 +297,27 @@ class TestContextDetectionFlow:
|
||||
def test_custom_domain_shop_detected(self, client, vendor_with_custom_domain):
|
||||
"""Test that custom domain shop is detected as SHOP context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/products")
|
||||
async def test_custom_domain_shop(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"vendor_code": request.state.vendor.code if hasattr(request.state, 'vendor') and request.state.vendor else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"vendor_code": (
|
||||
request.state.vendor.code
|
||||
if hasattr(request.state, "vendor") and request.state.vendor
|
||||
else None
|
||||
),
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/products",
|
||||
headers={"host": "customdomain.com"}
|
||||
)
|
||||
response = client.get("/products", headers={"host": "customdomain.com"})
|
||||
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
@@ -256,21 +331,30 @@ class TestContextDetectionFlow:
|
||||
def test_unknown_path_without_vendor_fallback_context(self, client):
|
||||
"""Test that unknown paths without vendor get FALLBACK context."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/test-fallback-context")
|
||||
async def test_fallback(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"context_enum": request.state.context_type.name if hasattr(request.state, 'context_type') else None,
|
||||
"has_vendor": hasattr(request.state, 'vendor') and request.state.vendor is not None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"context_enum": (
|
||||
request.state.context_type.name
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"has_vendor": hasattr(request.state, "vendor")
|
||||
and request.state.vendor is not None,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/test-fallback-context",
|
||||
headers={"host": "platform.com"}
|
||||
"/test-fallback-context", headers={"host": "platform.com"}
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -286,20 +370,26 @@ class TestContextDetectionFlow:
|
||||
def test_api_path_overrides_vendor_context(self, client, vendor_with_subdomain):
|
||||
"""Test that /api/* path sets API context even with vendor."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/api/test-api-priority")
|
||||
async def test_api_priority(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"has_vendor": hasattr(request.state, 'vendor') and request.state.vendor is not None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"has_vendor": hasattr(request.state, "vendor")
|
||||
and request.state.vendor is not None,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/api/test-api-priority",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -312,20 +402,26 @@ class TestContextDetectionFlow:
|
||||
def test_admin_path_overrides_vendor_context(self, client, vendor_with_subdomain):
|
||||
"""Test that /admin/* path sets ADMIN context even with vendor."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/admin/test-admin-priority")
|
||||
async def test_admin_priority(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"has_vendor": hasattr(request.state, 'vendor') and request.state.vendor is not None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"has_vendor": hasattr(request.state, "vendor")
|
||||
and request.state.vendor is not None,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/admin/test-admin-priority",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -333,22 +429,29 @@ class TestContextDetectionFlow:
|
||||
# Admin path should override vendor context
|
||||
assert data["context_type"] == "admin"
|
||||
|
||||
def test_vendor_dashboard_overrides_shop_context(self, client, vendor_with_subdomain):
|
||||
def test_vendor_dashboard_overrides_shop_context(
|
||||
self, client, vendor_with_subdomain
|
||||
):
|
||||
"""Test that /vendor/* path sets VENDOR_DASHBOARD, not SHOP."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/vendor/test-priority")
|
||||
async def test_vendor_priority(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
)
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/vendor/test-priority",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -363,21 +466,30 @@ class TestContextDetectionFlow:
|
||||
def test_context_uses_clean_path_for_detection(self, client, vendor_with_subdomain):
|
||||
"""Test that context detection uses clean_path, not original path."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/vendors/{vendor_code}/shop/products")
|
||||
async def test_clean_path_context(vendor_code: str, request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"clean_path": request.state.clean_path if hasattr(request.state, 'clean_path') else None,
|
||||
"original_path": request.url.path
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"clean_path": (
|
||||
request.state.clean_path
|
||||
if hasattr(request.state, "clean_path")
|
||||
else None
|
||||
),
|
||||
"original_path": request.url.path,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
f"/vendors/{vendor_with_subdomain.code}/shop/products",
|
||||
headers={"host": "localhost:8000"}
|
||||
headers={"host": "localhost:8000"},
|
||||
)
|
||||
|
||||
assert response.status_code == 200
|
||||
@@ -394,15 +506,20 @@ class TestContextDetectionFlow:
|
||||
def test_context_type_is_enum_instance(self, client):
|
||||
"""Test that context_type is a RequestContext enum instance."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/api/test-enum")
|
||||
async def test_enum(request: Request):
|
||||
context = request.state.context_type if hasattr(request.state, 'context_type') else None
|
||||
context = (
|
||||
request.state.context_type
|
||||
if hasattr(request.state, "context_type")
|
||||
else 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
|
||||
"enum_value": context.value if context else None,
|
||||
}
|
||||
|
||||
response = client.get("/api/test-enum")
|
||||
@@ -417,23 +534,30 @@ class TestContextDetectionFlow:
|
||||
# Edge Cases
|
||||
# ========================================================================
|
||||
|
||||
def test_empty_path_with_vendor_detected_as_shop(self, client, vendor_with_subdomain):
|
||||
def test_empty_path_with_vendor_detected_as_shop(
|
||||
self, client, vendor_with_subdomain
|
||||
):
|
||||
"""Test that empty/root path with vendor is detected as SHOP."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/")
|
||||
async def test_root(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None,
|
||||
"has_vendor": hasattr(request.state, 'vendor') and request.state.vendor is not None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
),
|
||||
"has_vendor": hasattr(request.state, "vendor")
|
||||
and request.state.vendor is not None,
|
||||
}
|
||||
|
||||
with patch('app.core.config.settings') as mock_settings:
|
||||
with patch("app.core.config.settings") as mock_settings:
|
||||
mock_settings.platform_domain = "platform.com"
|
||||
response = client.get(
|
||||
"/",
|
||||
headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
"/", headers={"host": f"{vendor_with_subdomain.subdomain}.platform.com"}
|
||||
)
|
||||
|
||||
assert response.status_code in [200, 404] # Might not have root handler
|
||||
@@ -445,13 +569,18 @@ class TestContextDetectionFlow:
|
||||
def test_case_insensitive_context_detection(self, client):
|
||||
"""Test that context detection is case insensitive for paths."""
|
||||
from fastapi import Request
|
||||
|
||||
from main import app
|
||||
|
||||
@app.get("/API/test-case")
|
||||
@app.get("/api/test-case")
|
||||
async def test_case(request: Request):
|
||||
return {
|
||||
"context_type": request.state.context_type.value if hasattr(request.state, 'context_type') else None
|
||||
"context_type": (
|
||||
request.state.context_type.value
|
||||
if hasattr(request.state, "context_type")
|
||||
else None
|
||||
)
|
||||
}
|
||||
|
||||
# Test uppercase
|
||||
|
||||
Reference in New Issue
Block a user