"""jti_store — 영속(SQLite) 일회성 토큰 jti 저장소 단위 테스트.""" import time import pytest from app import jti_store @pytest.fixture(autouse=True) def _tmp_jti_db(tmp_path, monkeypatch): monkeypatch.setattr(jti_store, "JTI_DB_PATH", str(tmp_path / "jti.db")) def test_consume_new_jti_returns_true(): assert jti_store.consume("new-jti", int(time.time()) + 600) is True def test_consume_duplicate_jti_returns_false(): """이미 사용된 jti 재consume → False (replay 차단). 파일 기반이라 재시작에도 생존.""" exp = int(time.time()) + 600 assert jti_store.consume("dup-jti", exp) is True assert jti_store.consume("dup-jti", exp) is False def test_expired_jti_cleaned_and_reusable(): """만료된 jti 항목은 정리되어 테이블이 무한 증식하지 않음. (만료 토큰 자체는 auth의 TTL 검사가 먼저 거부하므로 실사용엔 영향 없음.)""" past = int(time.time()) - 10 assert jti_store.consume("exp-jti", past) is True # 만료시각으로 마킹 future = int(time.time()) + 600 # 다음 consume이 만료 항목을 정리 → 같은 jti 재INSERT 성공 assert jti_store.consume("exp-jti", future) is True