Coverage for tests\test_api.py: 100%
86 statements
« prev ^ index » next coverage.py v7.10.1, created at 2025-10-19 21:13 +0800
« prev ^ index » next coverage.py v7.10.1, created at 2025-10-19 21:13 +0800
1import pytest
2from src.utility.config import Config
3from src.utility.endpoints import Endpoint
4from tests.conftest import get_json_val
7def test_api_metadata(client_nc) -> None:
8 resp = client_nc.get("/openapi.json")
9 resp_data = resp.json()
11 assert get_json_val(resp_data, "$.openapi") == "3.1.0"
12 assert get_json_val(resp_data, "$.info.title") == "MarkuAPI"
13 assert get_json_val(resp_data, "$.info.summary") == "Web scraper API for Filmarks Animes, Filmarks Dramas, and Filmarks Movies."
14 assert get_json_val(resp_data, "$.info.contact.name") == "e0406370"
15 assert get_json_val(resp_data, "$.info.contact.url") == "https://github.com/e0406370/markuapi"
16 assert get_json_val(resp_data, "$.info.version") == "1.1.1"
17 assert get_json_val(resp_data, "$.tags[0].name") == "anime"
18 assert get_json_val(resp_data, "$.tags[0].description") == "Endpoints for retrieving data from **[Filmarks Animes (フィルマークス・アニメ)](https://filmarks.com/animes)**"
19 assert get_json_val(resp_data, "$.tags[1].name") == "drama"
20 assert get_json_val(resp_data, "$.tags[1].description") == "Endpoints for retrieving data from **[Filmarks Dramas (フィルマークス・ドラマ)](https://filmarks.com/dramas)**"
21 assert get_json_val(resp_data, "$.tags[2].name") == "movie"
22 assert get_json_val(resp_data, "$.tags[2].description") == "Endpoints for retrieving data from **[Filmarks Movies (フィルマークス・映画)](https://filmarks.com)**"
25def test_api_routes(client_nc) -> None:
26 defined_routes = {
27 "/search/animes",
28 "/animes/{anime_series_id}/{anime_season_id}",
29 "/animes/{anime_series_id}/{anime_season_id}/reviews",
30 "/animes/{anime_series_id}/{anime_season_id}/reviews/{review_id}",
31 "/list-anime/trend",
32 "/list-anime/vod/{vod_name}",
33 "/list-anime/year/{year_series}s",
34 "/list-anime/year/{year}",
35 "/list-anime/year/{year}/{season_id}",
36 "/list-anime/company/{company_id}",
37 "/list-anime/tag/{tag}",
38 "/list-anime/person/{person_id}",
39 "/search/dramas",
40 "/dramas/{drama_series_id}/{drama_season_id}",
41 "/dramas/{drama_series_id}/{drama_season_id}/reviews",
42 "/dramas/{drama_series_id}/{drama_season_id}/reviews/{review_id}",
43 "/list-drama/trend",
44 "/list-drama/vod/{vod_name}",
45 "/list-drama/year/{year_series}s",
46 "/list-drama/year/{year}",
47 "/list-drama/country/{country_id}",
48 "/list-drama/genre/{genre_id}",
49 "/list-drama/tag/{tag}",
50 "/list-drama/person/{person_id}",
51 "/search/movies",
52 "/movies/{movie_id}",
53 "/movies/{movie_id}/reviews",
54 "/movies/{movie_id}/reviews/{review_id}",
55 "/list-movie/now",
56 "/list-movie/coming-soon",
57 "/list-movie/opening-this-week",
58 "/list-movie/trend",
59 "/list-movie/vod/{vod_name}",
60 "/list-movie/award/{award_id}",
61 "/list-movie/year/{year_series}s",
62 "/list-movie/year/{year}",
63 "/list-movie/country/{country_id}",
64 "/list-movie/genre/{genre_id}",
65 "/list-movie/distributor/{distributor_id}",
66 "/list-movie/series/{series_id}",
67 "/list-movie/tag/{tag}",
68 "/list-movie/person/{person_id}",
69 "/",
70 }
71 special_routes = {
72 "/openapi.json",
73 "/docs",
74 "/docs/oauth2-redirect",
75 "/redoc",
76 }
77 seen_routes = set()
79 for route in client_nc.app.routes:
80 if route.path not in special_routes:
81 assert route.path in defined_routes
82 assert route.path not in seen_routes
83 seen_routes.add(route.path)
85 assert len(seen_routes) == len(defined_routes)
86 assert len(seen_routes) == len(Endpoint) + 1
89def test_api_index(client_nc) -> None:
90 resp = client_nc.get("/")
91 resp_data = resp.json()
93 assert resp.headers["content-type"] == "application/json"
94 assert resp.status_code == 200
95 assert get_json_val(resp_data, "$.detail") == "Web scraper API for Filmarks Animes, Filmarks Dramas, and Filmarks Movies."
98def test_api_unknown(client_nc) -> None:
99 resp = client_nc.get("/unknown")
100 resp_data = resp.json()
102 assert resp.status_code == 404
103 assert get_json_val(resp_data, "$.detail") == "Not Found"
106@pytest.mark.parametrize("path", [
107 "/search/animes?q=デジモン",
108 "/animes/2592/3304",
109 "/animes/2592/3304/reviews",
110 "/animes/1533/2046/reviews/292787",
111 "/list-anime/trend",
112 "/list-anime/vod/prime_video",
113 "/list-anime/year/2020s",
114 "/list-anime/year/2025",
115 "/list-anime/year/2019/1",
116 "/list-anime/company/41",
117 "/list-anime/tag/駄作",
118 "/list-anime/person/274563",
119 "/search/dramas?q=あなたの番です",
120 "/dramas/6055/8586",
121 "/dramas/6055/8586/reviews",
122 "/dramas/2767/4530/reviews/622799",
123 "/list-drama/trend",
124 "/list-drama/vod/prime_video",
125 "/list-drama/year/2020s",
126 "/list-drama/year/2025",
127 "/list-drama/country/144",
128 "/list-drama/genre/9",
129 "/list-drama/tag/駄作",
130 "/list-drama/person/25499",
131 "/search/movies?q=ハリーポッター",
132 "/movies/14348",
133 "/movies/14348/reviews",
134 "/movies/22767/reviews/230",
135 "/list-movie/now",
136 "/list-movie/coming-soon",
137 "/list-movie/opening-this-week",
138 "/list-movie/trend",
139 "/list-movie/vod/prime_video",
140 "/list-movie/award/19",
141 "/list-movie/year/2010s",
142 "/list-movie/year/2001",
143 "/list-movie/country/5",
144 "/list-movie/genre/903",
145 "/list-movie/distributor/503",
146 "/list-movie/series/1",
147 "/list-movie/tag/洋画",
148 "/list-movie/person/93709",
149])
150def test_api_without_cache(client_nc, path) -> None:
151 resp_1 = client_nc.get(path)
152 resp_1_data = resp_1.json()
153 resp_1_scrape_date = get_json_val(resp_1_data, "$.scrape_date")
155 resp_2 = client_nc.get(path)
156 resp_2_data = resp_2.json()
157 resp_2_scrape_date = get_json_val(resp_2_data, "$.scrape_date")
159 assert resp_1.status_code == resp_2.status_code == 200
160 assert resp_1_data != resp_2_data
161 assert resp_1_scrape_date != resp_2_scrape_date
164@pytest.mark.skipif(not Config.REDIS_ENABLE_CACHE, reason="requires Redis")
165@pytest.mark.parametrize("path", [
166 "/search/animes?q=デジモン",
167 "/animes/2592/3304",
168 "/animes/2592/3304/reviews",
169 "/animes/1533/2046/reviews/292787",
170 "/list-anime/trend",
171 "/list-anime/vod/prime_video",
172 "/list-anime/year/2020s",
173 "/list-anime/year/2025",
174 "/list-anime/year/2019/1",
175 "/list-anime/company/41",
176 "/list-anime/tag/駄作",
177 "/list-anime/person/274563",
178 "/search/dramas?q=あなたの番です",
179 "/dramas/6055/8586",
180 "/dramas/6055/8586/reviews",
181 "/dramas/2767/4530/reviews/622799",
182 "/list-drama/trend",
183 "/list-drama/vod/prime_video",
184 "/list-drama/year/2020s",
185 "/list-drama/year/2025",
186 "/list-drama/country/144",
187 "/list-drama/genre/9",
188 "/list-drama/tag/駄作",
189 "/list-drama/person/25499",
190 "/search/movies?q=ハリーポッター",
191 "/movies/14348",
192 "/movies/14348/reviews",
193 "/movies/22767/reviews/230",
194 "/list-movie/now",
195 "/list-movie/coming-soon",
196 "/list-movie/opening-this-week",
197 "/list-movie/trend",
198 "/list-movie/vod/prime_video",
199 "/list-movie/award/19",
200 "/list-movie/year/2010s",
201 "/list-movie/year/2001",
202 "/list-movie/country/5",
203 "/list-movie/genre/903",
204 "/list-movie/distributor/503",
205 "/list-movie/series/1",
206 "/list-movie/tag/洋画",
207 "/list-movie/person/93709",
208])
209def test_api_with_cache(client_c, path) -> None:
210 resp_1 = client_c.get(path)
211 resp_1_data = resp_1.json()
212 resp_1_scrape_date = get_json_val(resp_1_data, "$.scrape_date")
214 resp_2 = client_c.get(path)
215 resp_2_data = resp_2.json()
216 resp_2_scrape_date = get_json_val(resp_2_data, "$.scrape_date")
218 assert resp_1.status_code == resp_2.status_code == 200
219 assert resp_1_data == resp_2_data
220 assert resp_1_scrape_date == resp_2_scrape_date
223@pytest.mark.parametrize("path", [
224 "/search/animes?q=デジモン",
225 "/animes/2592/3304",
226 "/animes/2592/3304/reviews",
227 "/animes/1533/2046/reviews/292787",
228 "/list-anime/trend",
229 "/list-anime/vod/prime_video",
230 "/list-anime/year/2020s",
231 "/list-anime/year/2025",
232 "/list-anime/year/2019/1",
233 "/list-anime/company/41",
234 "/list-anime/tag/駄作",
235 "/list-anime/person/274563",
236 "/search/dramas?q=あなたの番です",
237 "/dramas/6055/8586",
238 "/dramas/6055/8586/reviews",
239 "/dramas/2767/4530/reviews/622799",
240 "/list-drama/trend",
241 "/list-drama/vod/prime_video",
242 "/list-drama/year/2020s",
243 "/list-drama/year/2025",
244 "/list-drama/country/144",
245 "/list-drama/genre/9",
246 "/list-drama/tag/駄作",
247 "/list-drama/person/25499",
248 "/search/movies?q=ハリーポッター",
249 "/movies/14348",
250 "/movies/14348/reviews",
251 "/movies/22767/reviews/230",
252 "/list-movie/now",
253 "/list-movie/coming-soon",
254 "/list-movie/opening-this-week",
255 "/list-movie/trend",
256 "/list-movie/vod/prime_video",
257 "/list-movie/award/19",
258 "/list-movie/year/2010s",
259 "/list-movie/year/2001",
260 "/list-movie/country/5",
261 "/list-movie/genre/903",
262 "/list-movie/distributor/503",
263 "/list-movie/series/1",
264 "/list-movie/tag/洋画",
265 "/list-movie/person/93709",
266])
267def test_api_with_cache_connection_error(client_c_conn_err, path) -> None:
268 resp_1 = client_c_conn_err.get(path)
269 resp_1_data = resp_1.json()
270 resp_1_scrape_date = get_json_val(resp_1_data, "$.scrape_date")
272 resp_2 = client_c_conn_err.get(path)
273 resp_2_data = resp_2.json()
274 resp_2_scrape_date = get_json_val(resp_2_data, "$.scrape_date")
276 assert resp_1.status_code == resp_2.status_code == 200
277 assert resp_1_data != resp_2_data
278 assert resp_1_scrape_date != resp_2_scrape_date
281@pytest.mark.parametrize("path", [
282 "/search/animes?q=デジモン",
283 "/animes/2592/3304",
284 "/animes/2592/3304/reviews",
285 "/animes/1533/2046/reviews/292787",
286 "/list-anime/trend",
287 "/list-anime/vod/prime_video",
288 "/list-anime/year/2020s",
289 "/list-anime/year/2025",
290 "/list-anime/year/2019/1",
291 "/list-anime/company/41",
292 "/list-anime/tag/駄作",
293 "/list-anime/person/274563",
294 "/search/dramas?q=あなたの番です",
295 "/dramas/6055/8586",
296 "/dramas/6055/8586/reviews",
297 "/dramas/2767/4530/reviews/622799",
298 "/list-drama/trend",
299 "/list-drama/vod/prime_video",
300 "/list-drama/year/2020s",
301 "/list-drama/year/2025",
302 "/list-drama/country/144",
303 "/list-drama/genre/9",
304 "/list-drama/tag/駄作",
305 "/list-drama/person/25499",
306 "/search/movies?q=ハリーポッター",
307 "/movies/14348",
308 "/movies/14348/reviews",
309 "/movies/22767/reviews/230",
310 "/list-movie/now",
311 "/list-movie/coming-soon",
312 "/list-movie/opening-this-week",
313 "/list-movie/trend",
314 "/list-movie/vod/prime_video",
315 "/list-movie/award/19",
316 "/list-movie/year/2010s",
317 "/list-movie/year/2001",
318 "/list-movie/country/5",
319 "/list-movie/genre/903",
320 "/list-movie/distributor/503",
321 "/list-movie/series/1",
322 "/list-movie/tag/洋画",
323 "/list-movie/person/93709",
324])
325def test_api_with_cache_server_error(client_c_serv_err, path) -> None:
326 resp_1 = client_c_serv_err.get(path)
327 resp_1_data = resp_1.json()
328 resp_1_scrape_date = get_json_val(resp_1_data, "$.scrape_date")
330 resp_2 = client_c_serv_err.get(path)
331 resp_2_data = resp_2.json()
332 resp_2_scrape_date = get_json_val(resp_2_data, "$.scrape_date")
334 assert resp_1.status_code == resp_2.status_code == 200
335 assert resp_1_data != resp_2_data
336 assert resp_1_scrape_date != resp_2_scrape_date