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

1import pytest 

2from src.utility.config import Config 

3from src.utility.endpoints import Endpoint 

4from tests.conftest import get_json_val 

5 

6 

7def test_api_metadata(client_nc) -> None: 

8 resp = client_nc.get("/openapi.json") 

9 resp_data = resp.json() 

10 

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)**" 

23 

24 

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() 

78 

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) 

84 

85 assert len(seen_routes) == len(defined_routes) 

86 assert len(seen_routes) == len(Endpoint) + 1 

87 

88 

89def test_api_index(client_nc) -> None: 

90 resp = client_nc.get("/") 

91 resp_data = resp.json() 

92 

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." 

96 

97 

98def test_api_unknown(client_nc) -> None: 

99 resp = client_nc.get("/unknown") 

100 resp_data = resp.json() 

101 

102 assert resp.status_code == 404 

103 assert get_json_val(resp_data, "$.detail") == "Not Found" 

104 

105 

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") 

154 

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") 

158 

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 

162 

163 

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") 

213 

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") 

217 

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 

221 

222 

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") 

271 

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") 

275 

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 

279 

280 

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") 

329 

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") 

333 

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