"""Unit tests for cloud access store (cluster_id, env, deploy_type) -> CloudAccessEntry.""" import pytest from src.models.cloud_access import CloudAccessEntry, S3Access from src.utils import cloud_access_store @pytest.fixture(autouse=True) def reset_cloud_access_store(monkeypatch): """Isolate tests by replacing the module-level store with a fresh dict.""" store = {} monkeypatch.setattr(cloud_access_store, "_store", store) yield store def _minimal_entry(**kwargs) -> CloudAccessEntry: """Build a CloudAccessEntry with only the given fields (rest default None).""" return CloudAccessEntry(**kwargs) def _s3_access(provider: str = "aws", **kwargs) -> S3Access: defaults: dict = {"provider": provider, "secret_access_key": "sk"} defaults.update(kwargs) return S3Access(**defaults) class TestGetEntry: """get_entry returns cached CloudAccessEntry or None.""" def test_returns_none_when_key_missing(self): assert cloud_access_store.get_entry("c", "dev", "starter") is None def test_returns_stored_value_after_set(self): entry = _minimal_entry(metrics_url="https://metrics.example.com") cloud_access_store.set_entry("c", "dev", "starter", entry) assert cloud_access_store.get_entry("c", "dev", "starter") is entry def test_returns_correct_entry_for_different_keys(self): a = _minimal_entry(metrics_url="https://a.example.com") b = _minimal_entry(metrics_url="https://b.example.com") cloud_access_store.set_entry("c1", "dev", "starter", a) cloud_access_store.set_entry("c2", "dev", "starter", b) assert cloud_access_store.get_entry("c1", "dev", "starter") is a assert cloud_access_store.get_entry("c2", "dev", "starter") is b class TestSetEntry: """set_entry stores CloudAccessEntry by key tuple.""" def test_overwrites_same_key(self): first = _minimal_entry(metrics_url="https://first.example.com") second = _minimal_entry(metrics_url="https://second.example.com") cloud_access_store.set_entry("c", "dev", "starter", first) cloud_access_store.set_entry("c", "dev", "starter", second) assert cloud_access_store.get_entry("c", "dev", "starter") is second class TestKeyNormalization: """cluster_id, env, and deploy_type are normalized for cache keys.""" def test_keys_stripped_on_set(self): entry = _minimal_entry(metrics_url="https://m.example.com") cloud_access_store.set_entry(" c ", " DEV ", " STARTER ", entry) assert cloud_access_store.get_entry("c", "dev", "starter") is entry def test_lookup_with_whitespace_matches_stored(self): entry = _minimal_entry(metrics_url="https://m.example.com") cloud_access_store.set_entry("c", "dev", "starter", entry) assert cloud_access_store.get_entry(" c ", " dev ", " starter ") is entry class TestSetMetricsResolution: """set_metrics_resolution creates or merges metrics_url and metrics_token.""" def test_creates_new_entry_when_key_missing(self): cloud_access_store.set_metrics_resolution( "c", "dev", "starter", "https://metrics.example.com", token="secret" ) entry = cloud_access_store.get_entry("c", "dev", "starter") assert entry is not None assert entry.metrics_url == "https://metrics.example.com" assert entry.metrics_token == "secret" assert entry.s3_access is None assert entry.logs_url is None assert entry.s3_url is None def test_creates_new_entry_without_token(self): cloud_access_store.set_metrics_resolution("c", "dev", "starter", "https://m.example.com") entry = cloud_access_store.get_entry("c", "dev", "starter") assert entry is not None assert entry.metrics_url == "https://m.example.com" assert entry.metrics_token is None def test_merges_preserves_s3_access_logs_url_s3_url(self): s3 = _s3_access(provider="aws") cloud_access_store.set_entry( "c", "dev", "starter", _minimal_entry( s3_access=s3, metrics_url="https://old.example.com", logs_url="https://logs.example.com", s3_url="https://s3.example.com", ), ) cloud_access_store.set_metrics_resolution( "c", "dev", "starter", "https://new.example.com", token="newtoken" ) entry = cloud_access_store.get_entry("c", "dev", "starter") assert entry is not None assert entry.metrics_url == "https://new.example.com" assert entry.metrics_token == "newtoken" assert entry.s3_access is s3 assert entry.logs_url == "https://logs.example.com" assert entry.s3_url == "https://s3.example.com" class TestDeleteEntry: """delete_entry removes entry and returns True if it existed.""" def test_returns_false_when_key_missing(self): assert cloud_access_store.delete_entry("c", "dev", "starter") is False def test_returns_true_when_entry_existed(self): entry = _minimal_entry(metrics_url="https://m.example.com") cloud_access_store.set_entry("c", "dev", "starter", entry) assert cloud_access_store.delete_entry("c", "dev", "starter") is True def test_get_returns_none_after_delete(self): entry = _minimal_entry(metrics_url="https://m.example.com") cloud_access_store.set_entry("c", "dev", "starter", entry) cloud_access_store.delete_entry("c", "dev", "starter") assert cloud_access_store.get_entry("c", "dev", "starter") is None class TestListKeys: """list_keys returns all (cluster_id, env, deploy_type) keys sorted.""" def test_empty_store_returns_empty_list(self): assert cloud_access_store.list_keys() == [] def test_returns_sorted_keys(self): e = _minimal_entry(metrics_url="https://m.example.com") cloud_access_store.set_entry("c2", "dev", "starter", e) cloud_access_store.set_entry("c1", "prod", "premium", e) assert cloud_access_store.list_keys() == [ ("c1", "prod", "premium"), ("c2", "dev", "starter"), ] def test_single_key(self): e = _minimal_entry(metrics_url="https://m.example.com") cloud_access_store.set_entry("c", "dev", "starter", e) assert cloud_access_store.list_keys() == [("c", "dev", "starter")]