feat(infra): add Redis service and client for Phase 0 [FASE-0.1]

Add Redis 7 to Docker Compose with healthcheck and persistence, separate logical DBs for blacklist and cache, singleton redis client helpers, and unit tests with fakeredis.
This commit is contained in:
2026-05-18 13:18:45 +02:00
parent 821c4ac5ec
commit 9b70655b7e
6 changed files with 118 additions and 17 deletions

View File

@@ -0,0 +1,61 @@
"""Redis URL helpers and blacklist DB wiring (FASE 0.1)."""
import time
import uuid
from unittest.mock import MagicMock
import pytest
from app.config import settings
from app.infrastructure import redis_client as rc
@pytest.fixture
def fakeredis():
import fakeredis as fr
return fr.FakeRedis(decode_responses=True)
def test_redis_url_with_db_replaces_index():
assert (
rc._redis_url_with_db("redis://localhost:6379/0", 2)
== "redis://localhost:6379/2"
)
def test_get_redis_blacklist_uses_configured_db(monkeypatch):
monkeypatch.setattr(rc, "_clients", {})
captured: list[str] = []
def fake_from_url(url, **kwargs):
captured.append(url)
m = MagicMock()
m.setex = MagicMock()
return m
monkeypatch.setattr("redis.from_url", fake_from_url)
monkeypatch.setattr(settings, "REDIS_URL", "redis://redis:6379/0")
monkeypatch.setattr(settings, "REDIS_TOKEN_BLACKLIST_DB", 9)
c = rc.get_redis_blacklist()
c.setex("k", 10, "v")
assert captured == ["redis://redis:6379/9"]
c.setex.assert_called_once_with("k", 10, "v")
def test_redis_set_get_ttl(fakeredis, monkeypatch):
"""Integration-style check against FakeRedis (no real server)."""
monkeypatch.setattr(rc, "_clients", {})
monkeypatch.setattr(
"app.infrastructure.redis_client.get_redis_blacklist",
lambda: fakeredis,
)
from app.auth import blacklist_token, is_token_blacklisted
jti = str(uuid.uuid4())
exp = time.time() + 3600
blacklist_token(jti, exp)
assert is_token_blacklisted(jti) is True
ttl = fakeredis.ttl(f"blacklist:{jti}")
assert 0 < ttl <= 3600