Files
stonks-oracle/tests/integration/test_cross_service_roundtrip.py
T
Celes Renata 898f89926d feat: beta API integration test suite — 85 new tests across 6 modules
Extends integration test coverage from 108 to 193 tests for the beta gate.

New test modules:
- test_query_api_extended.py (33 tests): documents, evidence, macro/competitive, ops/admin, agents, analytics
- test_registry_write_paths.py (16 tests): write paths, validation, duplicates, competitor/exposure CRUD
- test_risk_approval_lifecycle.py (8 tests): evaluation edge cases, full approval lifecycle
- test_trading_extended.py (12 tests): config round-trips, decision filtering, override validation
- test_cross_service_roundtrip.py (4 tests): cross-service data consistency
- test_error_handling.py (12 tests): 404s, 422s, empty states, health checks

Seed script extended with watchlists, approvals, lockouts, notifications,
ingestion runs, saved queries, and daily risk snapshots.
2026-04-20 02:34:19 +00:00

160 lines
5.8 KiB
Python

"""Integration tests for cross-service data consistency.
These tests validate round-trip behavior: writing data via one service
and reading it back via another (or the same service on a different path).
They catch data propagation issues and schema drift between services.
"""
import pytest
pytestmark = pytest.mark.asyncio
# ---------------------------------------------------------------------------
# Cross-Service: Company creation via Registry → read via Query API
# ---------------------------------------------------------------------------
class TestCrossServiceCompanyRoundTrip:
"""Write company via registry, verify visibility in query API."""
async def test_create_company_via_registry_read_via_query(
self, registry_client, query_client,
):
"""Create company via registry, read via query API."""
payload = {
"ticker": "XRND",
"legal_name": "Cross Round Trip Corp",
"exchange": "NYSE",
"sector": "Technology",
"industry": "Software",
"market_cap_bucket": "small",
}
create_resp = await registry_client.post("/companies", json=payload)
assert create_resp.status_code == 201
# Read via query API
query_resp = await query_client.get("/api/companies")
assert query_resp.status_code == 200
tickers = {c["ticker"] for c in query_resp.json()}
assert "XRND" in tickers
# ---------------------------------------------------------------------------
# Cross-Service: Exposure profile round-trip via Registry
# ---------------------------------------------------------------------------
class TestCrossServiceExposureRoundTrip:
"""PUT exposure via registry, GET via registry on a different path."""
async def test_exposure_round_trip(self, registry_client, seed_ids):
"""PUT exposure via registry → GET via registry."""
company_id = seed_ids["companies"]["MSFT"]
payload = {
"geographic_revenue_mix": {
"North America": 0.55,
"Europe": 0.25,
"Asia": 0.20,
},
"supply_chain_regions": ["North America", "Europe"],
"key_input_commodities": [],
"regulatory_jurisdictions": ["US", "EU"],
"market_position_tier": "global_leader",
"export_dependency_pct": 0.35,
"source": "manual",
"confidence": 0.85,
}
put_resp = await registry_client.put(
f"/companies/{company_id}/exposure", json=payload,
)
assert put_resp.status_code == 200
# Read back
get_resp = await registry_client.get(
f"/companies/{company_id}/exposure",
)
assert get_resp.status_code == 200
data = get_resp.json()
assert data["geographic_revenue_mix"]["North America"] == 0.55
assert data["market_position_tier"] == "global_leader"
assert "supply_chain_regions" in data
# ---------------------------------------------------------------------------
# Cross-Service: Competitor relationship bidirectional visibility
# ---------------------------------------------------------------------------
class TestCrossServiceCompetitorBidirectional:
"""Competitor relationships visible from both sides."""
async def test_competitor_bidirectional_visibility(
self, registry_client, seed_ids,
):
"""Competitor visible from both sides."""
aapl_id = seed_ids["companies"]["AAPL"]
msft_id = seed_ids["companies"]["MSFT"]
# Check from AAPL side
resp_a = await registry_client.get(
f"/companies/{aapl_id}/competitors",
)
assert resp_a.status_code == 200
a_partners = set()
for rel in resp_a.json():
if rel["company_a_id"] == aapl_id:
a_partners.add(rel["company_b_id"])
else:
a_partners.add(rel["company_a_id"])
assert msft_id in a_partners
# Check from MSFT side
resp_b = await registry_client.get(
f"/companies/{msft_id}/competitors",
)
assert resp_b.status_code == 200
b_partners = set()
for rel in resp_b.json():
if rel["company_a_id"] == msft_id:
b_partners.add(rel["company_b_id"])
else:
b_partners.add(rel["company_a_id"])
assert aapl_id in b_partners
# ---------------------------------------------------------------------------
# Cross-Service: Risk evaluation schema matches query API recommendations
# ---------------------------------------------------------------------------
class TestCrossServiceRiskEvaluationSchema:
"""Risk evaluation schema matches what query API returns for recommendations."""
async def test_risk_evaluation_matches_recommendation(
self, risk_client, query_client, seed_ids,
):
"""Risk evaluation schema matches what query API returns for recommendations."""
# Evaluate via risk engine
eval_resp = await risk_client.post("/evaluate", json={
"order": {
"ticker": "AAPL",
"action": "buy",
"quantity": 10,
"estimated_value": 1855.00,
"confidence": 0.85,
},
})
assert eval_resp.status_code == 200
eval_data = eval_resp.json()
assert "evaluation_id" in eval_data
assert "eligible" in eval_data
assert "checks" in eval_data
# Query recommendation with risk evaluation
rec_id = seed_ids["recommendations"]["REC_01"]
rec_resp = await query_client.get(f"/api/recommendations/{rec_id}")
assert rec_resp.status_code == 200
rec_data = rec_resp.json()
assert "risk_evaluation" in rec_data