Spaces:
Sleeping
Sleeping
File size: 4,455 Bytes
c62301e | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | """Tests for cache management API endpoints."""
from unittest.mock import AsyncMock, MagicMock, patch
import pytest
from fastapi.testclient import TestClient
@pytest.fixture
def mock_user():
"""Create a mock user for auth dependency override."""
from app.core import models
user = MagicMock(spec=models.User)
user.id = 1
return user
@pytest.fixture
def client(mock_user):
"""Test client with auth dependency overridden."""
from app.main import app
from app.routers.auth import get_current_user
# Override auth to return mock user
def _override_user():
return mock_user
app.dependency_overrides[get_current_user] = _override_user
yield TestClient(app)
app.dependency_overrides.pop(get_current_user, None)
@pytest.fixture
def mock_cache_health_ok():
"""Patch get_cache().get_cache_health to return healthy status."""
with patch("app.routers.cache.get_cache") as mock_get_cache:
mock_cache = MagicMock()
# Methods called with await need to be AsyncMock
mock_cache.get_cache_health = AsyncMock()
mock_cache.get_cache_health.return_value = {
"status": "ok",
"keys_tracked": 5,
"ttl_seconds": 300,
}
mock_cache.invalidate_user_cache = AsyncMock()
mock_cache.invalidate_user_cache.return_value = 3
mock_get_cache.return_value = mock_cache
yield mock_cache
@pytest.fixture
def mock_cache_degraded():
"""Patch get_cache().get_cache_health to return degraded status."""
with patch("app.routers.cache.get_cache") as mock_get_cache:
mock_cache = MagicMock()
mock_cache.get_cache_health = AsyncMock()
mock_cache.get_cache_health.return_value = {
"status": "degraded",
"keys_tracked": 0,
"ttl_seconds": 300,
}
mock_cache.invalidate_user_cache = AsyncMock()
mock_cache.invalidate_user_cache.return_value = 0
mock_get_cache.return_value = mock_cache
yield mock_cache
class TestCacheInvalidateEndpoint:
"""Tests for POST /api/v1/cache/invalidate."""
def test_invalidate_returns_ok(self, client, mock_cache_health_ok):
"""Invalidate should return 200 with keys_cleared count."""
response = client.post("/api/v1/cache/invalidate")
assert response.status_code == 200
data = response.json()
assert data["status"] == "ok"
assert data["keys_cleared"] == 3
def test_invalidate_degraded(self, client, mock_cache_degraded):
"""Invalidate should return degraded status when Redis unavailable."""
response = client.post("/api/v1/cache/invalidate")
assert response.status_code == 200
data = response.json()
assert data["status"] == "degraded"
assert data["keys_cleared"] == 0
def test_invalidate_requires_auth(self):
"""Invalidate should return 401 without auth token."""
from app.main import app
client = TestClient(app)
response = client.post(
"/api/v1/cache/invalidate",
headers={"Authorization": "Bearer invalid-token"},
)
# Should be 401 or 403 when unauthenticated
assert response.status_code in (401, 403)
class TestCacheHealthEndpoint:
"""Tests for GET /api/v1/cache/health."""
def test_health_ok(self, client, mock_cache_health_ok):
"""Health endpoint should return cache status."""
response = client.get("/api/v1/cache/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "ok"
assert data["keys_tracked"] == 5
assert data["ttl_seconds"] == 300
def test_health_degraded(self, client, mock_cache_degraded):
"""Health endpoint should return degraded when Redis unavailable."""
response = client.get("/api/v1/cache/health")
assert response.status_code == 200
data = response.json()
assert data["status"] == "degraded"
assert data["keys_tracked"] == 0
def test_health_requires_auth(self):
"""Health endpoint should return 401 without auth token."""
from app.main import app
client = TestClient(app)
response = client.get(
"/api/v1/cache/health",
headers={"Authorization": "Bearer invalid-token"},
)
assert response.status_code in (401, 403)
|