from datetime import datetime, timedelta, timezone from app.chis.session_store import ChisSession, RedisChisSessionStore class FakeRedis: def __init__(self): self.values = {} self.setex_calls = [] self.deleted = [] def setex(self, key, ttl_seconds, value): self.values[key] = value self.setex_calls.append((key, ttl_seconds, value)) def get(self, key): return self.values.get(key) def delete(self, key): self.deleted.append(key) self.values.pop(key, None) def fixed_now(): return datetime(2026, 7, 5, 8, 0, tzinfo=timezone.utc) def make_session(expires_at=None): return ChisSession( base_url="http://chis.example.test/chis", uid="u001", role_id="role-2", manage_unit="unit-1", cookies={"JSESSIONID": "abc123", "sessionId1": "abc123"}, login_at=fixed_now(), expires_at=expires_at or fixed_now() + timedelta(hours=2), last_validated_at=fixed_now() + timedelta(minutes=5), ) def test_session_store_saves_session_with_ttl_and_reads_it_back(): redis = FakeRedis() store = RedisChisSessionStore(redis_client=redis, now=fixed_now) session = make_session() store.save("account-a", session) loaded = store.get("account-a") assert redis.setex_calls[0][0] == "chis:session:account-a" assert redis.setex_calls[0][1] == 7200 assert loaded == session assert "abc123" in redis.setex_calls[0][2] assert "password" not in redis.setex_calls[0][2].lower() def test_session_store_deletes_and_ignores_expired_session(): redis = FakeRedis() store = RedisChisSessionStore(redis_client=redis, now=fixed_now) expired = make_session(expires_at=fixed_now() - timedelta(seconds=1)) redis.values["chis:session:account-a"] = store.dumps(expired) assert store.get("account-a") is None assert redis.deleted == ["chis:session:account-a"] def test_session_store_deletes_session_by_account_ref(): redis = FakeRedis() store = RedisChisSessionStore(redis_client=redis, now=fixed_now) store.delete("account-a") assert redis.deleted == ["chis:session:account-a"]