-
-
Notifications
You must be signed in to change notification settings - Fork 206
Expand file tree
/
Copy pathtest_decorator.py
More file actions
160 lines (126 loc) · 5.89 KB
/
Copy pathtest_decorator.py
File metadata and controls
160 lines (126 loc) · 5.89 KB
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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
import time
from http import HTTPStatus
from typing import Any, Generator
from unittest.mock import patch
import pendulum
import pytest
from starlette.testclient import TestClient
from examples.in_memory.main import app
from fastapi_cache import FastAPICache
from fastapi_cache.backends.inmemory import InMemoryBackend
@pytest.fixture
def cache_unavailable():
# Mock cache to simulate unavailability by raising an exception in the cache retrieval method
with patch("fastapi_cache.backends.inmemory.InMemoryBackend.get") as mock_cache_get:
mock_cache_get.side_effect = Exception("Simulated cache failure")
yield
@pytest.fixture(autouse=True)
def _init_cache() -> Generator[Any, Any, None]: # pyright: ignore[reportUnusedFunction]
FastAPICache.init(InMemoryBackend())
yield
FastAPICache.reset()
def test_datetime() -> None:
with TestClient(app) as client:
response = client.get("/datetime")
assert response.headers.get("X-FastAPI-Cache") == "MISS"
now = response.json().get("now")
now_ = pendulum.parse(now)
response = client.get("/datetime")
assert response.headers.get("X-FastAPI-Cache") == "HIT"
now = response.json().get("now")
assert pendulum.parse(now) == now_
time.sleep(3)
response = client.get("/datetime")
assert response.headers.get("X-FastAPI-Cache") == "MISS"
now = response.json().get("now")
now = pendulum.parse(now)
assert now != now_
def test_date() -> None:
"""Test path function without request or response arguments."""
with TestClient(app) as client:
response = client.get("/date")
assert response.headers.get("X-FastAPI-Cache") == "MISS"
assert pendulum.parse(response.json()) == pendulum.today()
# do it again to test cache
response = client.get("/date")
assert response.headers.get("X-FastAPI-Cache") == "HIT"
assert pendulum.parse(response.json()) == pendulum.today()
# now test with cache disabled, as that's a separate code path
FastAPICache._enable = False # pyright: ignore[reportPrivateUsage]
response = client.get("/date")
assert "X-FastAPI-Cache" not in response.headers
assert pendulum.parse(response.json()) == pendulum.today()
FastAPICache._enable = True # pyright: ignore[reportPrivateUsage]
def test_sync() -> None:
"""Ensure that sync function support works."""
with TestClient(app) as client:
response = client.get("/sync-me")
assert response.json() == 42
def test_cache_response_obj() -> None:
with TestClient(app) as client:
cache_response = client.get("cache_response_obj")
assert cache_response.json() == {"a": 1}
get_cache_response = client.get("cache_response_obj")
assert get_cache_response.json() == {"a": 1}
assert get_cache_response.headers.get("cache-control")
assert get_cache_response.headers.get("etag")
def test_kwargs() -> None:
with TestClient(app) as client:
name = "Jon"
response = client.get("/kwargs", params={"name": name})
assert "X-FastAPI-Cache" not in response.headers
assert response.json() == {"name": name}
def test_method() -> None:
with TestClient(app) as client:
response = client.get("/method")
assert response.json() == 17
def test_pydantic_model() -> None:
with TestClient(app) as client:
r1 = client.get("/pydantic_instance")
assert r1.headers.get("X-FastAPI-Cache") == "MISS"
r2 = client.get("/pydantic_instance")
assert r2.headers.get("X-FastAPI-Cache") == "HIT"
assert r1.json() == r2.json()
def test_non_get() -> None:
with TestClient(app) as client:
response = client.put("/cached_put")
assert response.status_code == HTTPStatus.METHOD_NOT_ALLOWED
assert "X-FastAPI-Cache" not in response.headers
assert response.json() != {"value": 1}
response = client.put("/cached_put")
assert response.status_code == HTTPStatus.METHOD_NOT_ALLOWED
assert "X-FastAPI-Cache" not in response.headers
assert response.json() != {"value": 2}
def test_alternate_injected_namespace() -> None:
with TestClient(app) as client:
response = client.get("/namespaced_injection")
assert response.headers.get("X-FastAPI-Cache") == "MISS"
assert response.json() == {"__fastapi_cache_request": 42, "__fastapi_cache_response": 17}
def test_cache_control() -> None:
with TestClient(app) as client:
response = client.get("/cached_put")
assert response.json() == {"value": 1}
# HIT
response = client.get("/cached_put")
assert response.json() == {"value": 1}
# no-cache
response = client.get("/cached_put", headers={"Cache-Control": "no-cache"})
assert response.json() == {"value": 2}
response = client.get("/cached_put")
assert response.json() == {"value": 2}
# no-store
response = client.get("/cached_put", headers={"Cache-Control": "no-store"})
assert response.json() == {"value": 3}
response = client.get("/cached_put")
assert response.json() == {"value": 2}
####################CACHE UNAVAILABLE TESTS####################
def test_cache_failure():
with TestClient(app) as client:
# Simulate cache failure with continue_on_error=False
response = client.get("/cache_failure_example")
assert response.status_code == 503 # Expect a 503 error due to cache failure
assert response.json() == {"detail": "Cache initialization failed."}
# Now test with continue_on_error=True (should continue without caching)
response = client.get("/cache_failure_example?continue_on_error=true")
assert response.status_code == 200 # Expect success even with cache failure
assert response.json() == {"message": "This should simulate a cache failure."}