Coverage for tests\test_put_api_projects.py: 100.00%

178 statements  

« prev     ^ index     » next       coverage.py v7.4.3, created at 2024-03-22 23:23 +0100

1# -*- coding: utf-8 -*- 

2 

3""" 

4* Name: interactive-clustering-gui/tests/test_put_api_projects.py 

5* Description: Unittests for `app` module on the `PUT /api/projects` route. 

6* Author: Erwan Schild 

7* Created: 22/02/2022 

8* Licence: CeCILL (https://cecill.info/licences.fr.html) 

9""" 

10 

11# ============================================================================== 

12# IMPORT PYTHON DEPENDENCIES 

13# ============================================================================== 

14 

15from pathlib import Path 

16 

17import pytest 

18 

19# ============================================================================== 

20# test_ko_archive_type 

21# ============================================================================== 

22 

23 

24@pytest.mark.asyncio() 

25async def test_ko_archive_type(async_client): 

26 """ 

27 Test the `PUT /api/projects` route with bad archive type. 

28 

29 Arguments: 

30 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

31 """ 

32 # Assert HTTP client is created. 

33 assert async_client 

34 

35 # Assert route `PUT /api/projects` works. 

36 with open(Path(__file__).parent / "dummies" / "dummy_24.xlsx", "rb") as archive_fileobject: 

37 response_put = await async_client.put( 

38 url="/api/projects", 

39 files={ 

40 "project_archive": ( 

41 "dummy_24.xlsx", 

42 archive_fileobject, 

43 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", 

44 ), 

45 }, 

46 ) 

47 assert response_put.status_code == 400 

48 assert response_put.json() == { 

49 "detail": "The file type 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' is not supported. Please use '.zip' file.", 

50 } 

51 

52 # Assert route `GET /api/projects` is kept empty. 

53 response_get = await async_client.get(url="/api/projects") 

54 assert response_get.status_code == 200 

55 assert response_get.json() == [] # noqa: WPS520 

56 

57 

58# ============================================================================== 

59# test_ko_bad_archive 

60# ============================================================================== 

61 

62 

63@pytest.mark.asyncio() 

64async def test_ko_bad_archive(async_client): 

65 """ 

66 Test the `PUT /api/projects` route with bad archive type. 

67 

68 Arguments: 

69 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

70 """ 

71 # Assert HTTP client is created. 

72 assert async_client 

73 

74 # Assert route `PUT /api/projects` works. 

75 with open(Path(__file__).parent / "dummies" / "archive-ERROR_bad_archive.zip", "rb") as archive_fileobject: 

76 response_put = await async_client.put( 

77 url="/api/projects", 

78 files={ 

79 "project_archive": ( 

80 "archive-ERROR_bad_archive.zip", 

81 archive_fileobject, 

82 "application/x-zip-compressed", 

83 ), 

84 }, 

85 ) 

86 assert response_put.status_code == 400 

87 assert response_put.json() == { 

88 "detail": "An error occurs in project import. Project archive is probably invalid.", 

89 } 

90 

91 # Assert route `GET /api/projects` is kept empty. 

92 response_get = await async_client.get(url="/api/projects") 

93 assert response_get.status_code == 200 

94 assert response_get.json() == [] # noqa: WPS520 

95 

96 

97# ============================================================================== 

98# test_ko_missing_files 

99# ============================================================================== 

100 

101 

102@pytest.mark.asyncio() 

103async def test_ko_missing_files(async_client): 

104 """ 

105 Test the `PUT /api/projects` route with missing file in archive. 

106 

107 Arguments: 

108 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

109 """ 

110 # Assert HTTP client is created. 

111 assert async_client 

112 

113 # Assert route `PUT /api/projects` works. 

114 with open(Path(__file__).parent / "dummies" / "archive-ERROR_missing_files.zip", "rb") as archive_fileobject: 

115 response_put = await async_client.put( 

116 url="/api/projects", 

117 files={ 

118 "project_archive": ( 

119 "archive-ERROR_missing_files.zip", 

120 archive_fileobject, 

121 "application/x-zip-compressed", 

122 ), 

123 }, 

124 ) 

125 assert response_put.status_code == 400 

126 assert response_put.json() == { 

127 "detail": "The project archive file doesn't contains the following files: ['metadata.json', 'status.json', 'settings.json', 'sampling.json', 'clustering.json', 'modelization.json'].", 

128 } 

129 

130 # Assert route `GET /api/projects` is kept empty. 

131 response_get = await async_client.get(url="/api/projects") 

132 assert response_get.status_code == 200 

133 assert response_get.json() == [] # noqa: WPS520 

134 

135 

136# ============================================================================== 

137# test_ko_metadata_missing_project_name 

138# ============================================================================== 

139 

140 

141@pytest.mark.asyncio() 

142async def test_ko_metadata_missing_project_name(async_client): 

143 """ 

144 Test the `PUT /api/projects` route with missing project name metadata in archive. 

145 

146 Arguments: 

147 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

148 """ 

149 # Assert HTTP client is created. 

150 assert async_client 

151 

152 # Assert route `PUT /api/projects` works. 

153 with open( 

154 Path(__file__).parent / "dummies" / "archive-ERROR_metadata_missing_project_name.zip", "rb" 

155 ) as archive_fileobject: 

156 response_put = await async_client.put( 

157 url="/api/projects", 

158 files={ 

159 "project_archive": ( 

160 "archive-ERROR_metadata_missing_project_name.zip", 

161 archive_fileobject, 

162 "application/x-zip-compressed", 

163 ), 

164 }, 

165 ) 

166 assert response_put.status_code == 400 

167 assert response_put.json() == { 

168 "detail": "The project archive file has an invalid `metadata.json` file.", 

169 } 

170 

171 # Assert route `GET /api/projects` is kept empty. 

172 response_get = await async_client.get(url="/api/projects") 

173 assert response_get.status_code == 200 

174 assert response_get.json() == [] # noqa: WPS520 

175 

176 

177# ============================================================================== 

178# test_ko_metadata_bad_project_name 

179# ============================================================================== 

180 

181 

182@pytest.mark.asyncio() 

183async def test_ko_metadata_bad_project_name(async_client): 

184 """ 

185 Test the `PUT /api/projects` route with bad project name metadata in archive. 

186 

187 Arguments: 

188 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

189 """ 

190 # Assert HTTP client is created. 

191 assert async_client 

192 

193 # Assert route `PUT /api/projects` works. 

194 with open( 

195 Path(__file__).parent / "dummies" / "archive-ERROR_metadata_bad_project_name.zip", "rb" 

196 ) as archive_fileobject: 

197 response_put = await async_client.put( 

198 url="/api/projects", 

199 files={ 

200 "project_archive": ( 

201 "archive-ERROR_metadata_bad_project_name.zip", 

202 archive_fileobject, 

203 "application/x-zip-compressed", 

204 ), 

205 }, 

206 ) 

207 assert response_put.status_code == 400 

208 assert response_put.json() == { 

209 "detail": "The project archive file has an invalid `metadata.json` file.", 

210 } 

211 

212 # Assert route `GET /api/projects` is kept empty. 

213 response_get = await async_client.get(url="/api/projects") 

214 assert response_get.status_code == 200 

215 assert response_get.json() == [] # noqa: WPS520 

216 

217 

218# ============================================================================== 

219# test_ko_metadata_missing_creation_timestamp 

220# ============================================================================== 

221 

222 

223@pytest.mark.asyncio() 

224async def test_ko_metadata_missing_creation_timestamp(async_client): 

225 """ 

226 Test the `PUT /api/projects` route with missing creation timestamp metadata in archive. 

227 

228 Arguments: 

229 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

230 """ 

231 # Assert HTTP client is created. 

232 assert async_client 

233 

234 # Assert route `PUT /api/projects` works. 

235 with open( 

236 Path(__file__).parent / "dummies" / "archive-ERROR_metadata_missing_creation_timestamp.zip", "rb" 

237 ) as archive_fileobject: 

238 response_put = await async_client.put( 

239 url="/api/projects", 

240 files={ 

241 "project_archive": ( 

242 "archive-ERROR_metadata_missing_creation_timestamp.zip", 

243 archive_fileobject, 

244 "application/x-zip-compressed", 

245 ), 

246 }, 

247 ) 

248 assert response_put.status_code == 400 

249 assert response_put.json() == { 

250 "detail": "The project archive file has an invalid `metadata.json` file.", 

251 } 

252 

253 # Assert route `GET /api/projects` is kept empty. 

254 response_get = await async_client.get(url="/api/projects") 

255 assert response_get.status_code == 200 

256 assert response_get.json() == [] # noqa: WPS520 

257 

258 

259# ============================================================================== 

260# test_ko_metadata_bad_creation_timestamp 

261# ============================================================================== 

262 

263 

264@pytest.mark.asyncio() 

265async def test_ko_metadata_bad_creation_timestamp(async_client): 

266 """ 

267 Test the `PUT /api/projects` route with bad creation timestamp metadata in archive. 

268 

269 Arguments: 

270 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

271 """ 

272 # Assert HTTP client is created. 

273 assert async_client 

274 

275 # Assert route `PUT /api/projects` works. 

276 with open( 

277 Path(__file__).parent / "dummies" / "archive-ERROR_metadata_bad_creation_timestamp.zip", "rb" 

278 ) as archive_fileobject: 

279 response_put = await async_client.put( 

280 url="/api/projects", 

281 files={ 

282 "project_archive": ( 

283 "archive-ERROR_metadata_bad_creation_timestamp.zip", 

284 archive_fileobject, 

285 "application/x-zip-compressed", 

286 ), 

287 }, 

288 ) 

289 assert response_put.status_code == 400 

290 assert response_put.json() == { 

291 "detail": "The project archive file has an invalid `metadata.json` file.", 

292 } 

293 

294 # Assert route `GET /api/projects` is kept empty. 

295 response_get = await async_client.get(url="/api/projects") 

296 assert response_get.status_code == 200 

297 assert response_get.json() == [] # noqa: WPS520 

298 

299 

300# ============================================================================== 

301# test_ko_status_missing_state 

302# ============================================================================== 

303 

304 

305@pytest.mark.asyncio() 

306async def test_ko_status_missing_state(async_client): 

307 """ 

308 Test the `PUT /api/projects` route with missing state status in archive. 

309 

310 Arguments: 

311 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

312 """ 

313 # Assert HTTP client is created. 

314 assert async_client 

315 

316 # Assert route `PUT /api/projects` works. 

317 with open(Path(__file__).parent / "dummies" / "archive-ERROR_status_missing_state.zip", "rb") as archive_fileobject: 

318 response_put = await async_client.put( 

319 url="/api/projects", 

320 files={ 

321 "project_archive": ( 

322 "archive-ERROR_status_missing_state.zip", 

323 archive_fileobject, 

324 "application/x-zip-compressed", 

325 ), 

326 }, 

327 ) 

328 assert response_put.status_code == 400 

329 assert response_put.json() == { 

330 "detail": "The project archive file has an invalid `status.json` file (see key `state`).", 

331 } 

332 

333 # Assert route `GET /api/projects` is kept empty. 

334 response_get = await async_client.get(url="/api/projects") 

335 assert response_get.status_code == 200 

336 assert response_get.json() == [] # noqa: WPS520 

337 

338 

339# ============================================================================== 

340# test_ko_status_bad_state 

341# ============================================================================== 

342 

343 

344@pytest.mark.asyncio() 

345async def test_ko_status_bad_state(async_client): 

346 """ 

347 Test the `PUT /api/projects` route with bad state status in archive. 

348 

349 Arguments: 

350 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

351 """ 

352 # Assert HTTP client is created. 

353 assert async_client 

354 

355 # Assert route `PUT /api/projects` works. 

356 with open(Path(__file__).parent / "dummies" / "archive-ERROR_status_bad_state.zip", "rb") as archive_fileobject: 

357 response_put = await async_client.put( 

358 url="/api/projects", 

359 files={ 

360 "project_archive": ( 

361 "archive-ERROR_status_bad_state.zip", 

362 archive_fileobject, 

363 "application/x-zip-compressed", 

364 ), 

365 }, 

366 ) 

367 assert response_put.status_code == 400 

368 assert response_put.json() == { 

369 "detail": "The project archive file has an invalid `status.json` file (see key `state`).", 

370 } 

371 

372 # Assert route `GET /api/projects` is kept empty. 

373 response_get = await async_client.get(url="/api/projects") 

374 assert response_get.status_code == 200 

375 assert response_get.json() == [] # noqa: WPS520 

376 

377 

378# ============================================================================== 

379# test_ok_during_initialization 

380# ============================================================================== 

381 

382 

383@pytest.mark.asyncio() 

384async def test_ok_during_initialization(async_client): 

385 """ 

386 Test the `PUT /api/projects` route with project during initialization step. 

387 

388 Arguments: 

389 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

390 """ 

391 # Assert HTTP client is created. 

392 assert async_client 

393 

394 # Assert route `PUT /api/projects` works. 

395 with open( 

396 Path(__file__).parent / "dummies" / "archive-0a_INITIALIZATION_WITHOUT_MODELIZATION.zip", "rb" 

397 ) as archive_fileobject: 

398 response_put = await async_client.put( 

399 url="/api/projects", 

400 files={ 

401 "project_archive": ( 

402 "archive-0a_INITIALIZATION_WITHOUT_MODELIZATION.zip", 

403 archive_fileobject, 

404 "application/x-zip-compressed", 

405 ), 

406 }, 

407 ) 

408 assert response_put.status_code == 201 

409 assert list(response_put.json().keys()) == ["project_id", "detail"] 

410 imported_project_id: str = response_put.json()["project_id"] 

411 assert response_put.json() == { 

412 "project_id": imported_project_id, 

413 "detail": ( 

414 "The project with name 'unittests' has been imported. It has the id '" + str(imported_project_id) + "'." 

415 ), 

416 } 

417 

418 # Assert route `GET /api/projects` works and contains the created project. 

419 response_get = await async_client.get(url="/api/projects") 

420 assert response_get.status_code == 200 

421 assert imported_project_id in response_get.json() 

422 

423 # TODO: assert content. 

424 

425 # Assert route `GET /api/projects/{project_id}/status` is correct. 

426 response_get_status = await async_client.get(url="/api/projects/" + imported_project_id + "/status") 

427 assert response_get_status.status_code == 200 

428 assert response_get_status.json()["status"]["iteration_id"] == 0 

429 assert response_get_status.json()["status"]["state"] == "INITIALIZATION_WITHOUT_MODELIZATION" 

430 assert response_get_status.json()["status"]["task"] is None 

431 

432 

433# ============================================================================== 

434# test_ok_during_sampling 

435# ============================================================================== 

436 

437 

438@pytest.mark.asyncio() 

439async def test_ok_during_sampling(async_client): 

440 """ 

441 Test the `PUT /api/projects` route with project during sampling step. 

442 

443 Arguments: 

444 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

445 """ 

446 # Assert HTTP client is created. 

447 assert async_client 

448 

449 # Assert route `PUT /api/projects` works. 

450 with open(Path(__file__).parent / "dummies" / "archive-1b_SAMPLING_PENDING.zip", "rb") as archive_fileobject: 

451 response_put = await async_client.put( 

452 url="/api/projects", 

453 files={ 

454 "project_archive": ( 

455 "archive-1b_SAMPLING_PENDING.zip", 

456 archive_fileobject, 

457 "application/x-zip-compressed", 

458 ), 

459 }, 

460 ) 

461 assert response_put.status_code == 201 

462 assert list(response_put.json().keys()) == ["project_id", "detail"] 

463 imported_project_id: str = response_put.json()["project_id"] 

464 assert response_put.json() == { 

465 "project_id": imported_project_id, 

466 "detail": ( 

467 "The project with name 'unittests' has been imported. It has the id '" + str(imported_project_id) + "'." 

468 ), 

469 } 

470 

471 # Assert route `GET /api/projects` works and contains the created project. 

472 response_get = await async_client.get(url="/api/projects") 

473 assert response_get.status_code == 200 

474 assert imported_project_id in response_get.json() 

475 

476 # TODO: assert content. 

477 

478 # Assert route `GET /api/projects/{project_id}/status` is correct. 

479 response_get_status = await async_client.get(url="/api/projects/" + imported_project_id + "/status") 

480 assert response_get_status.status_code == 200 

481 assert response_get_status.json()["status"]["iteration_id"] == 1 

482 assert response_get_status.json()["status"]["state"] == "IMPORT_AT_SAMPLING_STEP_WITHOUT_MODELIZATION" 

483 assert response_get_status.json()["status"]["task"] is None 

484 

485 

486# ============================================================================== 

487# test_ok_during_annotation 

488# ============================================================================== 

489 

490 

491@pytest.mark.asyncio() 

492async def test_ok_during_annotation(async_client): 

493 """ 

494 Test the `PUT /api/projects` route with project during annotation step. 

495 

496 Arguments: 

497 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

498 """ 

499 # Assert HTTP client is created. 

500 assert async_client 

501 

502 # Assert route `PUT /api/projects` works. 

503 with open( 

504 Path(__file__).parent / "dummies" / "archive-1d_ANNOTATION_WITH_UPTODATE_MODELIZATION.zip", "rb" 

505 ) as archive_fileobject: 

506 response_put = await async_client.put( 

507 url="/api/projects", 

508 files={ 

509 "project_archive": ( 

510 "archive-1d_ANNOTATION_WITH_UPTODATE_MODELIZATION.zip", 

511 archive_fileobject, 

512 "application/x-zip-compressed", 

513 ), 

514 }, 

515 ) 

516 assert response_put.status_code == 201 

517 assert list(response_put.json().keys()) == ["project_id", "detail"] 

518 imported_project_id: str = response_put.json()["project_id"] 

519 assert response_put.json() == { 

520 "project_id": imported_project_id, 

521 "detail": ( 

522 "The project with name 'unittests' has been imported. It has the id '" + str(imported_project_id) + "'." 

523 ), 

524 } 

525 

526 # Assert route `GET /api/projects` works and contains the created project. 

527 response_get = await async_client.get(url="/api/projects") 

528 assert response_get.status_code == 200 

529 assert imported_project_id in response_get.json() 

530 

531 # TODO: assert content. 

532 

533 # Assert route `GET /api/projects/{project_id}/status` is correct. 

534 response_get_status = await async_client.get(url="/api/projects/" + imported_project_id + "/status") 

535 assert response_get_status.status_code == 200 

536 assert response_get_status.json()["status"]["iteration_id"] == 1 

537 assert response_get_status.json()["status"]["state"] == "IMPORT_AT_ANNOTATION_STEP_WITHOUT_MODELIZATION" 

538 assert response_get_status.json()["status"]["task"] is None 

539 

540 

541# ============================================================================== 

542# test_ok_during_clustering 

543# ============================================================================== 

544 

545 

546@pytest.mark.asyncio() 

547async def test_ok_during_clustering(async_client): 

548 """ 

549 Test the `PUT /api/projects` route with project during clustering step. 

550 

551 Arguments: 

552 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

553 """ 

554 # Assert HTTP client is created. 

555 assert async_client 

556 

557 # Assert route `PUT /api/projects` works. 

558 with open(Path(__file__).parent / "dummies" / "archive-1o_CLUSTERING_WORKING.zip", "rb") as archive_fileobject: 

559 response_put = await async_client.put( 

560 url="/api/projects", 

561 files={ 

562 "project_archive": ( 

563 "archive-1o_CLUSTERING_WORKING.zip", 

564 archive_fileobject, 

565 "application/x-zip-compressed", 

566 ), 

567 }, 

568 ) 

569 assert response_put.status_code == 201 

570 assert list(response_put.json().keys()) == ["project_id", "detail"] 

571 imported_project_id: str = response_put.json()["project_id"] 

572 assert response_put.json() == { 

573 "project_id": imported_project_id, 

574 "detail": ( 

575 "The project with name 'unittests' has been imported. It has the id '" + str(imported_project_id) + "'." 

576 ), 

577 } 

578 

579 # Assert route `GET /api/projects` works and contains the created project. 

580 response_get = await async_client.get(url="/api/projects") 

581 assert response_get.status_code == 200 

582 assert imported_project_id in response_get.json() 

583 

584 # TODO: assert content. 

585 

586 # Assert route `GET /api/projects/{project_id}/status` is correct. 

587 response_get_status = await async_client.get(url="/api/projects/" + imported_project_id + "/status") 

588 assert response_get_status.status_code == 200 

589 assert response_get_status.json()["status"]["iteration_id"] == 1 

590 assert response_get_status.json()["status"]["state"] == "IMPORT_AT_CLUSTERING_STEP_WITHOUT_MODELIZATION" 

591 assert response_get_status.json()["status"]["task"] is None 

592 

593 

594# ============================================================================== 

595# test_ok_during_iteration_end 

596# ============================================================================== 

597 

598 

599@pytest.mark.asyncio() 

600async def test_ok_during_iteration_end(async_client): 

601 """ 

602 Test the `PUT /api/projects` route with project during iteration end step. 

603 

604 Arguments: 

605 async_client: Fixture providing an HTTP client, declared in `conftest.py`. 

606 """ 

607 # Assert HTTP client is created. 

608 assert async_client 

609 

610 # Assert route `PUT /api/projects` works. 

611 with open(Path(__file__).parent / "dummies" / "archive-1p_ITERATION_END.zip", "rb") as archive_fileobject: 

612 response_put = await async_client.put( 

613 url="/api/projects", 

614 files={ 

615 "project_archive": ( 

616 "archive-1p_ITERATION_END.zip", 

617 archive_fileobject, 

618 "application/x-zip-compressed", 

619 ), 

620 }, 

621 ) 

622 assert response_put.status_code == 201 

623 assert list(response_put.json().keys()) == ["project_id", "detail"] 

624 imported_project_id: str = response_put.json()["project_id"] 

625 assert response_put.json() == { 

626 "project_id": imported_project_id, 

627 "detail": ( 

628 "The project with name 'unittests' has been imported. It has the id '" + str(imported_project_id) + "'." 

629 ), 

630 } 

631 

632 # Assert route `GET /api/projects` works and contains the created project. 

633 response_get = await async_client.get(url="/api/projects") 

634 assert response_get.status_code == 200 

635 assert imported_project_id in response_get.json() 

636 

637 # TODO: assert content. 

638 

639 # Assert route `GET /api/projects/{project_id}/status` is correct. 

640 response_get_status = await async_client.get(url="/api/projects/" + imported_project_id + "/status") 

641 assert response_get_status.status_code == 200 

642 assert response_get_status.json()["status"]["iteration_id"] == 1 

643 assert response_get_status.json()["status"]["state"] == "IMPORT_AT_ITERATION_END_WITHOUT_MODELIZATION" 

644 assert response_get_status.json()["status"]["task"] is None