"""Integration tests for DataBus provider chains. Tests cache layers, circuit breakers, provider fallbacks. Uses mocked external APIs to avoid real API calls. """ import pytest class TestDataBusCache: """Test L1 (memory) and L2 (Redis) cache layers.""" @pytest.mark.integration async def test_l1_cache_hit_returns_data(self): """L1 memory cache should return cached data on second fetch.""" pass # TODO: mock databus.fetch() with cache @pytest.mark.integration async def test_l2_redis_fallback_on_l1_miss(self): """L2 Redis should serve when L1 misses.""" pass @pytest.mark.integration async def test_stale_while_revalidate_returns_stale(self): """SWR should return stale data while refreshing in background.""" pass class TestCircuitBreakers: """Test provider circuit breakers — 3 failures → open → half-open → closed.""" @pytest.mark.integration async def test_circuit_opens_after_three_failures(self): """Circuit should open after 3 consecutive provider failures.""" pass @pytest.mark.integration async def test_half_open_allows_one_probe(self): """After timeout, half-open state should allow one probe request.""" pass @pytest.mark.integration async def test_closed_after_successful_probe(self): """Successful probe in half-open should close the circuit.""" pass class TestProviderFallback: """Test provider chain fallback — first fails, second succeeds.""" @pytest.mark.integration async def test_fallback_to_secondary_provider(self): """When primary fails, secondary provider should be tried.""" pass @pytest.mark.integration async def test_all_providers_fail_returns_none(self): """When all providers fail, databus should return None.""" pass class TestDataBusSmoke: """Smoke tests for all 78 DataBus provider chains.""" CHAINS = [ "token_price", "market_overview", "trending", "fear_greed", "wallet_labels", "entity_intel", "scanner", "rag_search", "wallet_tokens", "token_metadata", "token_security", ] @pytest.mark.integration @pytest.mark.parametrize("chain", CHAINS) async def test_chain_exists_in_providers(self, chain): """Every chain should exist in build_provider_chains().""" from app.databus.providers import build_provider_chains chains = build_provider_chains() assert chain in chains, f"Chain '{chain}' missing from provider chains"