Merge branch 'pr-402'
# Conflicts: # backend/app.py
This commit is contained in:
@@ -130,7 +130,9 @@ from api.seo_dashboard import (
|
||||
analyze_urls_ai,
|
||||
AnalyzeURLsRequest,
|
||||
get_analyzed_pages,
|
||||
get_semantic_health, # Phase 2B: Semantic health monitoring
|
||||
get_semantic_health,
|
||||
get_semantic_cache_stats,
|
||||
get_sif_indexing_health,
|
||||
get_onboarding_task_health,
|
||||
)
|
||||
|
||||
@@ -350,6 +352,15 @@ async def semantic_cache_stats_endpoint(current_user: dict = Depends(get_current
|
||||
"""
|
||||
return await get_semantic_cache_stats(current_user)
|
||||
|
||||
|
||||
@app.get("/api/seo-dashboard/sif-health")
|
||||
async def sif_indexing_health_endpoint(current_user: dict = Depends(get_current_user)):
|
||||
"""
|
||||
Get SIF indexing health summary for the current user.
|
||||
Used by the Semantic Indexing Status widget on the dashboard.
|
||||
"""
|
||||
return await get_sif_indexing_health(current_user)
|
||||
|
||||
# Comprehensive SEO Analysis endpoints
|
||||
@app.post("/api/seo-dashboard/analyze-comprehensive")
|
||||
async def analyze_seo_comprehensive_endpoint(request: SEOAnalysisRequest):
|
||||
|
||||
@@ -130,7 +130,8 @@ from api.seo_dashboard import (
|
||||
AnalyzeURLsRequest,
|
||||
get_analyzed_pages,
|
||||
get_semantic_health,
|
||||
get_sif_indexing_health
|
||||
get_semantic_cache_stats,
|
||||
get_sif_indexing_health,
|
||||
)
|
||||
|
||||
# Initialize FastAPI app
|
||||
|
||||
56
backend/tests/test_seo_dashboard_routes_smoke.py
Normal file
56
backend/tests/test_seo_dashboard_routes_smoke.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""Smoke tests for SEO dashboard route registration in FastAPI app entrypoints."""
|
||||
|
||||
import importlib
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
||||
|
||||
def _install_environment_defaults() -> None:
|
||||
"""Set minimal environment defaults needed for importing app entrypoints in tests."""
|
||||
os.environ.setdefault("STRIPE_MODE", "test")
|
||||
os.environ.setdefault(
|
||||
"STRIPE_PLAN_PRICE_MAPPING_TEST",
|
||||
'{"free":{"monthly":"price_test_free"},"basic":{"monthly":"price_test_basic"},"pro":{"monthly":"price_test_pro"}}',
|
||||
)
|
||||
|
||||
|
||||
def _install_dependency_stubs() -> None:
|
||||
"""Install lightweight stubs for optional heavy dependencies used during import."""
|
||||
if "spacy" not in sys.modules:
|
||||
spacy_stub = types.ModuleType("spacy")
|
||||
spacy_stub.load = lambda _model: object()
|
||||
sys.modules["spacy"] = spacy_stub
|
||||
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[2]
|
||||
BACKEND_ROOT = REPO_ROOT / "backend"
|
||||
if str(BACKEND_ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(BACKEND_ROOT))
|
||||
|
||||
TARGET_PATHS = {
|
||||
"/api/seo-dashboard/cache-stats",
|
||||
"/api/seo-dashboard/sif-health",
|
||||
}
|
||||
|
||||
ENTRYPOINT_MODULES = ("backend.app", "backend.main")
|
||||
|
||||
|
||||
@pytest.mark.parametrize("module_name", ENTRYPOINT_MODULES)
|
||||
def test_seo_dashboard_routes_registered(module_name: str) -> None:
|
||||
"""Verify module import succeeds and required SEO dashboard routes are registered."""
|
||||
_install_environment_defaults()
|
||||
_install_dependency_stubs()
|
||||
module = importlib.import_module(module_name)
|
||||
fastapi_app = module.app
|
||||
|
||||
registered_paths = {route.path for route in fastapi_app.routes}
|
||||
|
||||
missing_paths = TARGET_PATHS - registered_paths
|
||||
assert not missing_paths, (
|
||||
f"{module_name} is missing required SEO dashboard route(s): "
|
||||
f"{sorted(missing_paths)}"
|
||||
)
|
||||
Reference in New Issue
Block a user