"""Frontend data dependency tests — verify every page's API calls return valid data. Each test function represents one frontend page and calls all the API endpoints that page depends on. For each endpoint we assert: • HTTP 200 • Response is non-empty (list has items, or dict has expected keys) Uses ``query_client``, ``registry_client``, ``trading_client``, and ``seed_ids`` fixtures from conftest.py. """ import pytest pytestmark = pytest.mark.asyncio # --------------------------------------------------------------------------- # 1 Home # --------------------------------------------------------------------------- class TestHomePage: """Home page depends on: companies, pipeline health, ingestion summary, recommendations.""" async def test_home_page_deps(self, query_client, seed_ids): # /api/companies resp = await query_client.get("/api/companies") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # /api/ops/pipeline/health resp = await query_client.get("/api/ops/pipeline/health") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "document_stages" in data # /api/ops/ingestion/summary resp = await query_client.get("/api/ops/ingestion/summary") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "total_runs" in data # /api/recommendations resp = await query_client.get("/api/recommendations") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 2 Companies # --------------------------------------------------------------------------- class TestCompaniesPage: """Companies list page depends on: companies (query API).""" async def test_companies_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/companies") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 5 # --------------------------------------------------------------------------- # 3 CompanyDetail # --------------------------------------------------------------------------- class TestCompanyDetailPage: """CompanyDetail depends on: company, sources, trends, recommendations, competitors (registry), exposure (registry), macro-impacts.""" async def test_company_detail_page_deps( self, query_client, registry_client, seed_ids, ): company_id = seed_ids["companies"]["AAPL"] # /api/companies/{id} resp = await query_client.get(f"/api/companies/{company_id}") assert resp.status_code == 200 data = resp.json() assert data["ticker"] == "AAPL" # /api/companies/{id}/sources resp = await query_client.get(f"/api/companies/{company_id}/sources") assert resp.status_code == 200 assert isinstance(resp.json(), list) # /api/trends?ticker=AAPL resp = await query_client.get("/api/trends", params={"ticker": "AAPL"}) assert resp.status_code == 200 assert isinstance(resp.json(), list) # /api/recommendations?ticker=AAPL resp = await query_client.get("/api/recommendations", params={"ticker": "AAPL"}) assert resp.status_code == 200 assert isinstance(resp.json(), list) # /companies/{id}/competitors (registry — no /api/ prefix) resp = await registry_client.get(f"/companies/{company_id}/competitors") assert resp.status_code == 200 assert isinstance(resp.json(), list) # /companies/{id}/exposure (registry — no /api/ prefix) resp = await registry_client.get(f"/companies/{company_id}/exposure") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "company_id" in data # /api/companies/AAPL/macro-impacts (query API via /api/macro/impacts/AAPL) resp = await query_client.get("/api/macro/impacts/AAPL") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) # --------------------------------------------------------------------------- # 4 Documents # --------------------------------------------------------------------------- class TestDocumentsPage: """Documents list page depends on: documents.""" async def test_documents_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/documents") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 5 DocumentDetail # --------------------------------------------------------------------------- class TestDocumentDetailPage: """DocumentDetail depends on: documents/{id}.""" async def test_document_detail_page_deps(self, query_client, seed_ids): doc_id = seed_ids["documents"]["DOC_01"] resp = await query_client.get(f"/api/documents/{doc_id}") assert resp.status_code == 200 data = resp.json() assert data["id"] == doc_id assert "title" in data # --------------------------------------------------------------------------- # 6 Trends # --------------------------------------------------------------------------- class TestTrendsPage: """Trends list page depends on: trends.""" async def test_trends_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/trends") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 7 TrendDetail # --------------------------------------------------------------------------- class TestTrendDetailPage: """TrendDetail depends on: trends/{id}, trends/{id}/projection.""" async def test_trend_detail_page_deps(self, query_client, seed_ids): trend_id = seed_ids["trends"]["TREND_01"] # /api/trends/{id} resp = await query_client.get(f"/api/trends/{trend_id}") assert resp.status_code == 200 data = resp.json() assert data["id"] == trend_id assert "trend_direction" in data # /api/trends/{id}/projection resp = await query_client.get(f"/api/trends/{trend_id}/projection") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) assert "projected_direction" in data # --------------------------------------------------------------------------- # 8 Recommendations # --------------------------------------------------------------------------- class TestRecommendationsPage: """Recommendations list page depends on: recommendations.""" async def test_recommendations_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/recommendations") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 9 RecommendationDetail # --------------------------------------------------------------------------- class TestRecommendationDetailPage: """RecommendationDetail depends on: recommendations/{id}.""" async def test_recommendation_detail_page_deps(self, query_client, seed_ids): rec_id = seed_ids["recommendations"]["REC_01"] resp = await query_client.get(f"/api/recommendations/{rec_id}") assert resp.status_code == 200 data = resp.json() assert data["id"] == rec_id assert "ticker" in data assert "evidence" in data # --------------------------------------------------------------------------- # 10 Orders # --------------------------------------------------------------------------- class TestOrdersPage: """Orders list page depends on: orders.""" async def test_orders_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/orders") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 11 OrderDetail # --------------------------------------------------------------------------- class TestOrderDetailPage: """OrderDetail depends on: orders/{id}.""" async def test_order_detail_page_deps(self, query_client, seed_ids): order_id = seed_ids["orders"]["ORDER_01"] resp = await query_client.get(f"/api/orders/{order_id}") assert resp.status_code == 200 data = resp.json() assert data["id"] == order_id assert "events" in data # --------------------------------------------------------------------------- # 12 Positions # --------------------------------------------------------------------------- class TestPositionsPage: """Positions page depends on: positions.""" async def test_positions_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/positions") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 13 GlobalEvents # --------------------------------------------------------------------------- class TestGlobalEventsPage: """GlobalEvents page depends on: macro/events.""" async def test_global_events_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/macro/events") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 14 GlobalEventDetail # --------------------------------------------------------------------------- class TestGlobalEventDetailPage: """GlobalEventDetail depends on: macro/events/{id}.""" async def test_global_event_detail_page_deps(self, query_client, seed_ids): event_id = seed_ids["global_events"]["EVT_01"] resp = await query_client.get(f"/api/macro/events/{event_id}") assert resp.status_code == 200 data = resp.json() assert data["id"] == event_id assert "summary" in data assert "impacts" in data # --------------------------------------------------------------------------- # 15 OpsPipeline # --------------------------------------------------------------------------- class TestOpsPipelinePage: """OpsPipeline page depends on: ops/pipeline/health.""" async def test_ops_pipeline_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/ops/pipeline/health") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "document_stages" in data # --------------------------------------------------------------------------- # 16 OpsIngestion # --------------------------------------------------------------------------- class TestOpsIngestionPage: """OpsIngestion page depends on: ingestion summary + throughput.""" async def test_ops_ingestion_page_deps(self, query_client, seed_ids): # /api/ops/ingestion/summary resp = await query_client.get("/api/ops/ingestion/summary") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "total_runs" in data # /api/ops/ingestion/throughput resp = await query_client.get("/api/ops/ingestion/throughput") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) # --------------------------------------------------------------------------- # 17 OpsCoverage # --------------------------------------------------------------------------- class TestOpsCoveragePage: """OpsCoverage page depends on: ops/sources/coverage-gaps.""" async def test_ops_coverage_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/ops/sources/coverage-gaps") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) assert "missing_source_types" in data assert "stale_sources" in data # --------------------------------------------------------------------------- # 18 Agents # --------------------------------------------------------------------------- class TestAgentsPage: """Agents page depends on: agents.""" async def test_agents_page_deps(self, query_client, seed_ids): resp = await query_client.get("/api/agents") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) and len(data) >= 1 # --------------------------------------------------------------------------- # 19 TradingEngine # --------------------------------------------------------------------------- class TestTradingEnginePage: """TradingEngine page depends on: trading status, metrics, decisions.""" async def test_trading_engine_page_deps(self, trading_client, seed_ids): # /api/trading/status resp = await trading_client.get("/api/trading/status") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "enabled" in data # /api/trading/metrics resp = await trading_client.get("/api/trading/metrics") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "total_portfolio_value" in data # /api/trading/decisions resp = await trading_client.get("/api/trading/decisions") assert resp.status_code == 200 data = resp.json() assert isinstance(data, list) # --------------------------------------------------------------------------- # 20 Trading # --------------------------------------------------------------------------- class TestTradingPage: """Trading page depends on: trading status.""" async def test_trading_page_deps(self, trading_client, seed_ids): resp = await trading_client.get("/api/trading/status") assert resp.status_code == 200 data = resp.json() assert isinstance(data, dict) and "enabled" in data # --------------------------------------------------------------------------- # 21 Watchlists # --------------------------------------------------------------------------- class TestWatchlistsPage: """Watchlists page depends on: /watchlists (registry client).""" async def test_watchlists_page_deps(self, registry_client, seed_ids): resp = await registry_client.get("/watchlists") assert resp.status_code == 200 data = resp.json() # Watchlists may be empty — just verify 200 + list type assert isinstance(data, list)