Coverage for src/tests/api/v1/trainings/test_endpoints.py: 96%

104 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2024-01-01 00:00 +0000

1"""Module for testing the trainings endpoints.""" 

2 

3from typing import Any 

4 

5import pytest 

6 

7from fastapi import status 

8from fastapi.testclient import TestClient 

9from kwai_core.domain.value_objects.period import Period 

10from kwai_core.domain.value_objects.timestamp import Timestamp 

11from kwai_core.domain.value_objects.unique_id import UniqueId 

12 

13 

14pytestmark = pytest.mark.api 

15 

16 

17def _find(resource_list: list[dict[str, Any]], id_: str): 

18 """Search for a resource with the given id.""" 

19 for resource in resource_list: 

20 if resource["id"] == id_: 

21 return resource 

22 return None 

23 

24 

25async def test_get_trainings(secure_client: TestClient, make_training_in_db): 

26 """Test get trainings api.""" 

27 training = await make_training_in_db() 

28 

29 response = secure_client.get("/api/v1/trainings") 

30 assert response.status_code == status.HTTP_200_OK 

31 

32 json = response.json() 

33 assert "meta" in json, "There should be a meta object in the response" 

34 assert "data" in json, "There should be a data list in the response" 

35 assert len(json["data"]) > 0, "There should be at least one training" 

36 

37 training_resource = _find(json["data"], str(training.id)) 

38 assert training_resource is not None, f"Training with id {training.id} should exist" 

39 

40 

41async def test_get_trainings_filter_year_month( 

42 secure_client: TestClient, make_training_in_db, make_training 

43): 

44 """Test get trainings api with filter on year/month.""" 

45 training = await make_training_in_db( 

46 make_training( 

47 period=Period( 

48 start_date=Timestamp.create_from_string("2023-01-02 19:00:00"), 

49 end_date=Timestamp.create_from_string("2023-01-02 20:00:00"), 

50 ) 

51 ) 

52 ) 

53 response = secure_client.get( 

54 "/api/v1/trainings", params={"filter[year]": 2023, "filter[month]": 1} 

55 ) 

56 assert response.status_code == status.HTTP_200_OK 

57 

58 json = response.json() 

59 assert "meta" in json, "There should be a meta object in the response" 

60 assert "data" in json, "There should be a data list in the response" 

61 assert len(json["data"]) > 0, "There should be at least one training" 

62 

63 training_resource = _find(json["data"], str(training.id)) 

64 assert training_resource is not None, f"Training with id {training.id} should exist" 

65 

66 

67async def test_get_trainings_filter_start_end( 

68 secure_client: TestClient, make_training_in_db, make_training 

69): 

70 """Test get trainings api with a filter on start and end date.""" 

71 training = await make_training_in_db( 

72 make_training( 

73 period=Period( 

74 start_date=Timestamp.create_from_string("2023-01-02 19:00:00"), 

75 end_date=Timestamp.create_from_string("2023-01-02 20:00:00"), 

76 ) 

77 ) 

78 ) 

79 response = secure_client.get( 

80 "/api/v1/trainings", 

81 params={ 

82 "filter[start]": "2023-01-01 00:00:00", 

83 "filter[end]": "2023-01-31 00:00:00", 

84 }, 

85 ) 

86 assert response.status_code == status.HTTP_200_OK 

87 

88 json = response.json() 

89 assert "meta" in json, "There should be a meta object in the response" 

90 assert "data" in json, "There should be a data list in the response" 

91 assert len(json["data"]) > 0, "There should be at least one training" 

92 

93 training_resource = _find(json["data"], str(training.id)) 

94 assert training_resource is not None, f"Training with id {training.id} should exist" 

95 

96 

97def test_get_trainings_filter_coach(secure_client: TestClient): 

98 """Test get trainings api with a filter for a coach.""" 

99 response = secure_client.get( 

100 "/api/v1/trainings", 

101 params={"filter[coach]": UniqueId.generate()}, 

102 ) 

103 assert response.status_code in [status.HTTP_200_OK, status.HTTP_404_NOT_FOUND] 

104 

105 json = response.json() 

106 if response.status_code == status.HTTP_200_OK: 

107 assert "meta" in json, "There should be a meta object in the response" 

108 assert "data" in json, "There should be a data list in the response" 

109 else: 

110 assert "detail" in json 

111 

112 

113async def test_get_trainings_filter_active( 

114 secure_client: TestClient, make_training_in_db, make_training 

115): 

116 """Test get trainings api with a filter for active trainings.""" 

117 training = await make_training_in_db(make_training(active=False)) 

118 response = secure_client.get( 

119 "/api/v1/trainings", 

120 params={"filter[active]": "false"}, 

121 ) 

122 assert response.status_code in [status.HTTP_200_OK] 

123 

124 json = response.json() 

125 assert "meta" in json, "There should be a meta object in the response" 

126 assert "data" in json, "There should be a data list in the response" 

127 assert len(json["data"]) > 0, "There should be at least one training" 

128 

129 training_resource = _find(json["data"], str(training.id)) 

130 assert training_resource is not None, f"Training with id {training.id} should exist" 

131 

132 

133def test_get_trainings_filter_training_schedule(secure_client: TestClient): 

134 """Test get trainings api with a filter for a training schedule.""" 

135 response = secure_client.get( 

136 "/api/v1/trainings", 

137 params={"filter[schedule]": "1"}, 

138 ) 

139 assert response.status_code in [status.HTTP_200_OK, status.HTTP_404_NOT_FOUND] 

140 

141 json = response.json() 

142 if response.status_code == status.HTTP_200_OK: 

143 assert "meta" in json, "There should be a meta object in the response" 

144 assert "data" in json, "There should be a data list in the response" 

145 else: 

146 assert "detail" in json 

147 

148 

149async def test_get_training(secure_client: TestClient, make_training_in_db): 

150 """Test /api/v1/trainings/{training_id}.""" 

151 training = await make_training_in_db() 

152 response = secure_client.get(f"/api/v1/trainings/{training.id}") 

153 assert response.status_code == status.HTTP_200_OK 

154 

155 json = response.json() 

156 assert "data" in json, "There should be data in the response" 

157 

158 training_resource = json["data"] 

159 assert training_resource is not None, f"Training with id {training.id} should exist" 

160 

161 

162def test_create_training(secure_client: TestClient): 

163 """Test POST /api/v1/trainings.""" 

164 payload = { 

165 "data": { 

166 "type": "trainings", 

167 "attributes": { 

168 "texts": [ 

169 { 

170 "locale": "en", 

171 "format": "md", 

172 "title": "U13 Training", 

173 "summary": "", 

174 "original_summary": "Training for U13", 

175 "original_content": "", 

176 "content": "", 

177 } 

178 ], 

179 "event": { 

180 "start_date": "2023-02-02 19:00:00", 

181 "end_date": "2023-02-02 20:00:00", 

182 "active": True, 

183 "cancelled": False, 

184 "location": "", 

185 }, 

186 "remark": "", 

187 }, 

188 "relationships": { 

189 "coaches": {"data": []}, 

190 "teams": {"data": []}, 

191 "schedule": {"data": None}, 

192 }, 

193 } 

194 } 

195 response = secure_client.post("/api/v1/trainings", json=payload) 

196 assert response.status_code == status.HTTP_201_CREATED, response.json() 

197 

198 

199async def test_create_training_with_schedule( 

200 secure_client: TestClient, make_training_schedule_in_db 

201): 

202 """Test POST /api/v1/trainings.""" 

203 training_schedule = await make_training_schedule_in_db() 

204 

205 payload = { 

206 "data": { 

207 "type": "trainings", 

208 "attributes": { 

209 "texts": [ 

210 { 

211 "locale": "en", 

212 "format": "md", 

213 "title": "U13 Training", 

214 "summary": "", 

215 "original_summary": "Training for U13", 

216 "original_content": "", 

217 "content": "", 

218 } 

219 ], 

220 "event": { 

221 "start_date": "2023-02-02 19:00:00", 

222 "end_date": "2023-02-02 20:00:00", 

223 "active": True, 

224 "cancelled": False, 

225 "location": "", 

226 }, 

227 "remark": "", 

228 }, 

229 "relationships": { 

230 "coaches": {"data": []}, 

231 "teams": {"data": []}, 

232 "schedule": { 

233 "data": { 

234 "id": str(training_schedule.id), 

235 "type": "training_schedules", 

236 } 

237 }, 

238 }, 

239 } 

240 } 

241 response = secure_client.post("/api/v1/trainings", json=payload) 

242 assert response.status_code == status.HTTP_201_CREATED, response.json() 

243 

244 

245async def test_create_training_with_coaches( 

246 secure_client: TestClient, make_coach_in_db 

247): 

248 """Test POST /api/v1/trainings with coaches.""" 

249 coach = await make_coach_in_db() 

250 payload = { 

251 "data": { 

252 "type": "trainings", 

253 "attributes": { 

254 "texts": [ 

255 { 

256 "locale": "en", 

257 "format": "md", 

258 "title": "U13 Training", 

259 "summary": "", 

260 "original_summary": "Training for U13", 

261 "original_content": "", 

262 "content": "", 

263 } 

264 ], 

265 "event": { 

266 "start_date": "2023-02-02 19:00:00", 

267 "end_date": "2023-02-02 20:00:00", 

268 "active": True, 

269 "cancelled": False, 

270 "location": "", 

271 }, 

272 "remark": "", 

273 }, 

274 "relationships": { 

275 "coaches": {"data": [{"type": "training_coaches"}]}, 

276 "teams": {"data": []}, 

277 "schedule": {"data": None}, 

278 }, 

279 }, 

280 "included": [ 

281 { 

282 "type": "training_coaches", 

283 "attributes": { 

284 "head": False, 

285 "name": "Jigoro Kano", 

286 "payed": False, 

287 "present": False, 

288 "remark": "", 

289 }, 

290 "relationships": { 

291 "coach": { 

292 "data": { 

293 "type": "coaches", 

294 "id": str(coach.uuid), 

295 } 

296 } 

297 }, 

298 } 

299 ], 

300 } 

301 response = secure_client.post("/api/v1/trainings", json=payload) 

302 assert response.status_code == status.HTTP_201_CREATED, response.json() 

303 

304 

305def test_create_training_with_teams(secure_client: TestClient): 

306 """Test POST /api/v1/trainings with teams.""" 

307 payload = { 

308 "data": { 

309 "type": "trainings", 

310 "attributes": { 

311 "texts": [ 

312 { 

313 "locale": "en", 

314 "format": "md", 

315 "title": "U13 Training", 

316 "summary": "", 

317 "original_summary": "Training for U13", 

318 "original_content": "", 

319 "content": "", 

320 } 

321 ], 

322 "event": { 

323 "start_date": "2023-02-02 19:00:00", 

324 "end_date": "2023-02-02 20:00:00", 

325 "active": True, 

326 "cancelled": False, 

327 "location": "", 

328 }, 

329 "remark": "", 

330 }, 

331 "relationships": { 

332 "coaches": {"data": []}, 

333 "teams": {"data": [{"type": "teams", "id": "1"}]}, 

334 "schedule": {"data": None}, 

335 }, 

336 } 

337 } 

338 response = secure_client.post("/api/v1/trainings", json=payload) 

339 assert response.status_code == status.HTTP_201_CREATED, response.json() 

340 

341 

342async def test_update_training(secure_client: TestClient, make_training_in_db): 

343 """Test PATCH /api/v1/trainings.""" 

344 training_entity = await make_training_in_db() 

345 payload = { 

346 "data": { 

347 "type": "trainings", 

348 "id": str(training_entity.id), 

349 "attributes": { 

350 "texts": [ 

351 { 

352 "locale": "en", 

353 "format": "md", 

354 "title": "U13 Training", 

355 "summary": "", 

356 "original_summary": "Training for U13", 

357 "original_content": "", 

358 "content": "", 

359 } 

360 ], 

361 "event": { 

362 "start_date": "2023-02-02 19:00:00", 

363 "end_date": "2023-02-02 20:00:00", 

364 "active": True, 

365 "cancelled": False, 

366 "location": "", 

367 }, 

368 "remark": "Updated!", 

369 }, 

370 "relationships": { 

371 "coaches": {"data": []}, 

372 "teams": {"data": []}, 

373 "schedule": {"data": None}, 

374 }, 

375 } 

376 } 

377 response = secure_client.patch( 

378 f"/api/v1/trainings/{training_entity.id}", json=payload 

379 ) 

380 assert response.status_code == status.HTTP_200_OK, response.json() 

381 

382 

383async def test_delete_training(secure_client: TestClient, make_training_in_db): 

384 """Test DELETE /api/v1/trainings/{id}.""" 

385 training_entity = await make_training_in_db() 

386 response = secure_client.delete(f"/api/v1/trainings/{training_entity.id}") 

387 assert response.status_code == status.HTTP_200_OK, response.json()