Coverage for tests\test_post_api_projects.py: 100.00%
87 statements
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-22 23:23 +0100
« prev ^ index » next coverage.py v7.4.3, created at 2024-03-22 23:23 +0100
1# -*- coding: utf-8 -*-
3"""
4* Name: interactive-clustering-gui/tests/test_post_api_projects.py
5* Description: Unittests for `app` module on the `POST /api/projects` route.
6* Author: Erwan Schild
7* Created: 22/02/2022
8* Licence: CeCILL (https://cecill.info/licences.fr.html)
9"""
11# ==============================================================================
12# IMPORT PYTHON DEPENDENCIES
13# ==============================================================================
15import json
16import os
17from pathlib import Path
18from typing import Any, Dict
20import pytest
22from cognitivefactory.interactive_clustering_gui.models.states import ICGUIStates
24# ==============================================================================
25# test_ko_empty_project_name
26# ==============================================================================
29@pytest.mark.asyncio()
30async def test_ko_empty_project_name(async_client):
31 """
32 Test the `POST /api/projects` route with empty project_name.
34 Arguments:
35 async_client: Fixture providing an HTTP client, declared in `conftest.py`.
36 """
37 # Assert HTTP client is created.
38 assert async_client
40 # Assert route `POST /api/projects` works.
41 with open(Path(__file__).parent / "dummies" / "dummy_24.csv", "rb") as dataset_fileobject:
42 response_post = await async_client.post(
43 url="/api/projects",
44 params={
45 "project_name": " \n ",
46 },
47 files={
48 "dataset_file": (
49 "dummy_24.csv",
50 dataset_fileobject,
51 "text/csv",
52 ),
53 },
54 )
55 assert response_post.status_code == 400
56 assert response_post.json() == {
57 "detail": "The project name ' \n ' is invalid.",
58 }
60 # Assert route `GET /api/projects` is kept empty.
61 response_get = await async_client.get(url="/api/projects")
62 assert response_get.status_code == 200
63 assert response_get.json() == [] # noqa: WPS520
66# ==============================================================================
67# test_ko_bad_csv
68# ==============================================================================
71@pytest.mark.asyncio()
72async def test_ko_bad_csv(async_client):
73 """
74 Test the `POST /api/projects` route with bad .csv dataset.
76 Arguments:
77 async_client: Fixture providing an HTTP client, declared in `conftest.py`.
78 """
79 # Assert HTTP client is created.
80 assert async_client
82 # Assert route `POST /api/projects` works.
83 with open(Path(__file__).parent / "dummies" / "dummy_24.xlsx", "rb") as dataset_fileobject:
84 response_post = await async_client.post(
85 url="/api/projects",
86 params={
87 "project_name": "unittests ! with bad .CSV",
88 },
89 files={
90 "dataset_file": (
91 "dummy_24.xlsx",
92 dataset_fileobject,
93 "text/csv",
94 ),
95 },
96 )
97 assert response_post.status_code == 400
98 assert response_post.json() == {
99 "detail": "The dataset file is invalid. `.csv` file, with `;` separator, must contain a list of texts in the first column, with no header.",
100 }
102 # Assert route `GET /api/projects` is kept empty.
103 response_get = await async_client.get(url="/api/projects")
104 assert response_get.status_code == 200
105 assert response_get.json() == [] # noqa: WPS520
108# ==============================================================================
109# test_ko_bad_xlsx
110# ==============================================================================
113@pytest.mark.asyncio()
114async def test_ko_bad_xlsx(async_client):
115 """
116 Test the `POST /api/projects` route with bad .xlsx dataset.
118 Arguments:
119 async_client: Fixture providing an HTTP client, declared in `conftest.py`.
120 """
121 # Assert HTTP client is created.
122 assert async_client
124 # Assert route `POST /api/projects` works.
125 with open(Path(__file__).parent / "dummies" / "dummy_24.csv", "rb") as dataset_fileobject:
126 response_post = await async_client.post(
127 url="/api/projects",
128 params={
129 "project_name": "unittests ! with bad .XLSX",
130 },
131 files={
132 "dataset_file": (
133 "dummy_24.csv",
134 dataset_fileobject,
135 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
136 ),
137 },
138 )
139 assert response_post.status_code == 400
140 assert response_post.json() == {
141 "detail": "The dataset file is invalid. `.xlsx` file must contain a list of texts in the first column, with no header.",
142 }
144 # Assert route `GET /api/projects` is kept empty.
145 response_get = await async_client.get(url="/api/projects")
146 assert response_get.status_code == 200
147 assert response_get.json() == [] # noqa: WPS520
150# ==============================================================================
151# test_ko_dataset_type
152# ==============================================================================
155@pytest.mark.asyncio()
156async def test_ko_dataset_type(async_client):
157 """
158 Test the `POST /api/projects` route with bad dataset type.
160 Arguments:
161 async_client: Fixture providing an HTTP client, declared in `conftest.py`.
162 """
163 # Assert HTTP client is created.
164 assert async_client
166 # Assert route `POST /api/projects` works.
167 with open(Path(__file__).parent / "dummies" / "dummy_24.txt", "rb") as dataset_fileobject:
168 response_post = await async_client.post(
169 url="/api/projects",
170 params={
171 "project_name": "unittests ! with bad .XLSX",
172 },
173 files={
174 "dataset_file": (
175 "dummy_24.txt",
176 dataset_fileobject,
177 "text/plain",
178 ),
179 },
180 )
181 assert response_post.status_code == 400
182 assert response_post.json() == {
183 "detail": "The file type 'text/plain' is not supported. Please use '.csv' (`;` separator) or '.xlsx' file.",
184 }
186 # Assert route `GET /api/projects` is kept empty.
187 response_get = await async_client.get(url="/api/projects")
188 assert response_get.status_code == 200
189 assert response_get.json() == [] # noqa: WPS520
192# ==============================================================================
193# test_ok_csv
194# ==============================================================================
197@pytest.mark.asyncio()
198async def test_ok_csv(async_client, tmp_path):
199 """
200 Test the `POST /api/projects` route with .csv dataset.
202 Arguments:
203 async_client: Fixture providing an HTTP client, declared in `conftest.py`.
204 tmp_path: The temporary path given for this test, declared in `conftest.py`.
205 """
206 # Assert HTTP client is created.
207 assert async_client
209 # Assert route `POST /api/projects` works.
210 with open(Path(__file__).parent / "dummies" / "dummy_24.csv", "rb") as dataset_fileobject:
211 response_post = await async_client.post(
212 url="/api/projects",
213 params={
214 "project_name": "unittests ! with .CSV",
215 },
216 files={
217 "dataset_file": (
218 "dummy_24.csv",
219 dataset_fileobject,
220 "text/csv",
221 ),
222 },
223 )
224 assert response_post.status_code == 201
225 assert list(response_post.json().keys()) == ["project_id", "detail"]
226 created_project_id: str = response_post.json()["project_id"]
228 # Assert route `GET /api/projects` works and contains the created project.
229 response_get = await async_client.get(url="/api/projects")
230 assert response_get.status_code == 200
231 assert created_project_id in response_get.json()
233 # Assert created project has needed stored files.
234 assert sorted(os.listdir(tmp_path / created_project_id)) == [
235 "clustering.json",
236 "constraints.json",
237 "metadata.json",
238 "modelization.json",
239 "sampling.json",
240 "settings.json",
241 "status.json",
242 "texts.json",
243 ]
245 # Case of `metadata.json`.
246 with open(tmp_path / created_project_id / "metadata.json", "r") as metadata_fileobject:
247 project_metadata: Dict[str, Any] = json.load(metadata_fileobject)
248 assert project_metadata["project_id"] == created_project_id
249 assert project_metadata["project_name"] == "unittests ! with .CSV"
250 assert "creation_timestamp" in project_metadata.keys()
252 # Case of `status.json`.
253 with open(tmp_path / created_project_id / "status.json", "r") as status_fileobject:
254 project_status: Dict[str, Any] = json.load(status_fileobject)
255 assert project_status == {
256 "iteration_id": 0,
257 "state": ICGUIStates.INITIALIZATION_WITHOUT_MODELIZATION,
258 "task": None,
259 }
262# ==============================================================================
263# test_ok_xlsx
264# ==============================================================================
267@pytest.mark.asyncio()
268async def test_ok_xlsx(async_client, tmp_path):
269 """
270 Test the `POST /api/projects` route with .xlsx dataset.
272 Arguments:
273 async_client: Fixture providing an HTTP client, declared in `conftest.py`.
274 tmp_path: The temporary path given for this test, declared in `conftest.py`.
275 """
276 # Assert HTTP client is created.
277 assert async_client
279 # Assert route `POST /api/projects` works.
280 with open(Path(__file__).parent / "dummies" / "dummy_24.xlsx", "rb") as dataset_fileobject:
281 response_post = await async_client.post(
282 url="/api/projects",
283 params={
284 "project_name": "unittests ! with .XLSX",
285 },
286 files={
287 "dataset_file": (
288 "dummy_24.xlsx",
289 dataset_fileobject,
290 "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
291 ),
292 },
293 )
294 assert response_post.status_code == 201
295 assert list(response_post.json().keys()) == ["project_id", "detail"]
296 created_project_id: str = response_post.json()["project_id"]
298 # Assert route `GET /api/projects` works and contains the created project.
299 response_get = await async_client.get(url="/api/projects")
300 assert response_get.status_code == 200
301 assert created_project_id in response_get.json()
303 # Assert created project has needed stored files.
304 assert sorted(os.listdir(tmp_path / created_project_id)) == [
305 "clustering.json",
306 "constraints.json",
307 "metadata.json",
308 "modelization.json",
309 "sampling.json",
310 "settings.json",
311 "status.json",
312 "texts.json",
313 ]
315 # Case of `metadata.json`.
316 with open(tmp_path / created_project_id / "metadata.json", "r") as metadata_fileobject:
317 project_metadata: Dict[str, Any] = json.load(metadata_fileobject)
318 assert project_metadata["project_id"] == created_project_id
319 assert project_metadata["project_name"] == "unittests ! with .XLSX"
320 assert "creation_timestamp" in project_metadata.keys()
322 # Case of `status.json`.
323 with open(tmp_path / created_project_id / "status.json", "r") as status_fileobject:
324 project_status: Dict[str, Any] = json.load(status_fileobject)
325 assert project_status == {
326 "iteration_id": 0,
327 "state": ICGUIStates.INITIALIZATION_WITHOUT_MODELIZATION,
328 "task": None,
329 }