"""Unit tests for the recently-revoked denylist (U2 / U3).""" from __future__ import annotations import time from agentkit.server.auth.denylist import ( InMemoryRecentlyRevoked, hash_token, ) def test_add_then_contains_within_ttl(): cache: InMemoryRecentlyRevoked = InMemoryRecentlyRevoked() h = hash_token("token-a") cache.add(h, ttl_seconds=10) assert cache.contains(h) is True def test_contains_returns_false_after_ttl_expires(): cache: InMemoryRecentlyRevoked = InMemoryRecentlyRevoked() h = hash_token("token-b") cache.add(h, ttl_seconds=0) # TTL=0 → expires immediately (or very soon) time.sleep(0.05) assert cache.contains(h) is False def test_evicts_oldest_when_overflowed(): cache: InMemoryRecentlyRevoked = InMemoryRecentlyRevoked(max_entries=2) cache.add("a", ttl_seconds=10) cache.add("b", ttl_seconds=10) cache.add("c", ttl_seconds=10) # pushes 'a' out (LRU eviction) assert cache.contains("a") is False assert cache.contains("b") is True assert cache.contains("c") is True def test_re_add_refreshes_ttl_and_lru_position(): cache: InMemoryRecentlyRevoked = InMemoryRecentlyRevoked(max_entries=2) cache.add("a", ttl_seconds=10) cache.add("b", ttl_seconds=10) cache.add("a", ttl_seconds=10) # re-add: should now be MRU cache.add("c", ttl_seconds=10) # evicts oldest, which is 'b' now assert cache.contains("a") is True assert cache.contains("b") is False assert cache.contains("c") is True def test_clear_drops_all_entries(): cache: InMemoryRecentlyRevoked = InMemoryRecentlyRevoked() cache.add("a", ttl_seconds=10) cache.add("b", ttl_seconds=10) cache.clear() assert cache.contains("a") is False assert cache.contains("b") is False def test_hash_token_is_stable_and_sha256_hex(): h1 = hash_token("xyz") h2 = hash_token("xyz") assert h1 == h2 assert len(h1) == 64 assert all(c in "0123456789abcdef" for c in h1)