Skip to content

Commit 48d2677

Browse files
add final tests
1 parent abdef4c commit 48d2677

File tree

4 files changed

+167
-28
lines changed

4 files changed

+167
-28
lines changed

services/web/server/src/simcore_service_webserver/folders/_trash_service.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@ async def batch_delete_folders_with_content_in_root_workspace_as_admin(
358358
shared_workspace_id=workspace_id, # <-- Workspace filter
359359
offset=page_params.offset,
360360
limit=page_params.limit,
361-
order_by=OrderBy(field=IDStr("id")),
361+
order_by=OrderBy(field=IDStr("folder_id")),
362362
)
363363
# BATCH delete
364364
for folder in folders_for_deletion:

services/web/server/src/simcore_service_webserver/trash/_service.py

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -181,54 +181,52 @@ async def safe_delete_expired_trash_as_admin(app: web.Application) -> None:
181181
delete_until,
182182
):
183183
try:
184-
185-
await folders_trash_service.batch_delete_trashed_folders_as_admin(
184+
deleted_workspace_ids = await workspaces_trash_service.batch_delete_trashed_workspaces_as_admin(
186185
app,
187186
trashed_before=delete_until,
188-
product_name=product_name,
189187
fail_fast=False,
190188
)
191189

190+
_logger.info(
191+
"Deleted %d trashed workspaces", len(deleted_workspace_ids)
192+
)
193+
192194
except Exception as exc: # pylint: disable=broad-exception-caught
193195
_logger.warning(
194196
**create_troubleshotting_log_kwargs(
195-
"Error batch deleting expired trashed folders as admin.",
197+
"Error batch deleting expired workspaces as admin.",
196198
error=exc,
197199
error_context=ctx,
198200
)
199201
)
200202

201203
try:
202-
203-
deleted_project_ids = (
204-
await projects_trash_service.batch_delete_trashed_projects_as_admin(
205-
app,
206-
trashed_before=delete_until,
207-
fail_fast=False,
208-
)
204+
await folders_trash_service.batch_delete_trashed_folders_as_admin(
205+
app,
206+
trashed_before=delete_until,
207+
product_name=product_name,
208+
fail_fast=False,
209209
)
210210

211-
_logger.info("Deleted %d trashed projects", len(deleted_project_ids))
212-
213211
except Exception as exc: # pylint: disable=broad-exception-caught
214212
_logger.warning(
215213
**create_troubleshotting_log_kwargs(
216-
"Error batch deleting expired projects as admin.",
214+
"Error batch deleting expired trashed folders as admin.",
217215
error=exc,
218216
error_context=ctx,
219217
)
220218
)
221219

222220
try:
223-
deleted_workspace_ids = await workspaces_trash_service.batch_delete_trashed_workspaces_as_admin(
224-
app,
225-
trashed_before=delete_until,
226-
fail_fast=False,
221+
deleted_project_ids = (
222+
await projects_trash_service.batch_delete_trashed_projects_as_admin(
223+
app,
224+
trashed_before=delete_until,
225+
fail_fast=False,
226+
)
227227
)
228228

229-
_logger.info(
230-
"Deleted %d trashed workspaces", len(deleted_workspace_ids)
231-
)
229+
_logger.info("Deleted %d trashed projects", len(deleted_project_ids))
232230

233231
except Exception as exc: # pylint: disable=broad-exception-caught
234232
_logger.warning(

services/web/server/src/simcore_service_webserver/workspaces/_trash_service.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,10 @@ async def batch_delete_trashed_workspaces_as_admin(
339339
assert trashed_workspace.trashed # nosec
340340
deleted_workspace_ids.append(trashed_workspace.workspace_id)
341341

342+
workspace_db_get = await _workspaces_repository.get_workspace_db_get(
343+
app, workspace_id=trashed_workspace.workspace_id
344+
)
345+
342346
try:
343347
await batch_delete_projects_in_root_workspace_as_admin(
344348
app, workspace_id=trashed_workspace.workspace_id, fail_fast=False
@@ -349,10 +353,6 @@ async def batch_delete_trashed_workspaces_as_admin(
349353
errors.append((trashed_workspace.workspace_id, err))
350354

351355
try:
352-
workspace_db_get = await _workspaces_repository.get_workspace_db_get(
353-
app, workspace_id=trashed_workspace.workspace_id
354-
)
355-
356356
await batch_delete_folders_with_content_in_root_workspace_as_admin(
357357
app,
358358
workspace_id=trashed_workspace.workspace_id,
@@ -364,6 +364,17 @@ async def batch_delete_trashed_workspaces_as_admin(
364364
raise
365365
errors.append((trashed_workspace.workspace_id, err))
366366

367+
try:
368+
await _workspaces_repository.delete_workspace(
369+
app,
370+
workspace_id=trashed_workspace.workspace_id,
371+
product_name=workspace_db_get.product_name,
372+
)
373+
except Exception as err: # pylint: disable=broad-exception-caught
374+
if fail_fast:
375+
raise
376+
errors.append((trashed_workspace.workspace_id, err))
377+
367378
if errors:
368379
raise WorkspaceBatchDeleteError(
369380
errors=errors,

services/web/server/tests/unit/with_dbs/03/trash/test_trash_service.py

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ async def test_trash_service__delete_expired_trash(
8787

8888
# UNDER TEST: Run delete_expired_trash
8989
await trash_service.safe_delete_expired_trash_as_admin(client.app)
90-
9190
# ASSERT: logged_user tries to get the project and expects 404
9291
resp = await client.get(f"/v0/projects/{user_project_id}")
9392
await assert_status(resp, status.HTTP_404_NOT_FOUND)
@@ -98,7 +97,7 @@ async def test_trash_service__delete_expired_trash(
9897
await assert_status(resp, status.HTTP_404_NOT_FOUND)
9998

10099

101-
async def test_trash_nested_folders_and_projects(
100+
async def test_trash_service__delete_expired_trash_for_nested_folders_and_projects(
102101
client: TestClient,
103102
logged_user: UserInfoDict,
104103
user_project: ProjectDict,
@@ -191,3 +190,134 @@ async def test_trash_nested_folders_and_projects(
191190

192191
resp = await client.get(f"/v0/projects/{other_user_project['uuid']}")
193192
await assert_status(resp, status.HTTP_404_NOT_FOUND)
193+
194+
195+
async def test_trash_service__delete_expired_trash_for_workspace(
196+
client: TestClient,
197+
logged_user: UserInfoDict,
198+
user_project: ProjectDict,
199+
other_user: UserInfoDict,
200+
other_user_project: ProjectDict,
201+
mocked_catalog: None,
202+
mocked_director_v2: None,
203+
mocked_dynamic_services_interface: dict[str, MagicMock],
204+
):
205+
assert client.app
206+
assert logged_user["id"] != other_user["id"]
207+
208+
async with switch_client_session_to(client, logged_user):
209+
# CREATE folders hierarchy for logged_user
210+
resp = await client.post("/v0/folders", json={"name": "Root Folder"})
211+
data, _ = await assert_status(resp, status.HTTP_201_CREATED)
212+
logged_user_root_folder = data
213+
214+
resp = await client.post(
215+
"/v0/folders",
216+
json={
217+
"name": "Sub Folder",
218+
"parentFolderId": logged_user_root_folder["folderId"],
219+
},
220+
)
221+
data, _ = await assert_status(resp, status.HTTP_201_CREATED)
222+
logged_user_sub_folder = data
223+
224+
# MOVE project to subfolder
225+
resp = await client.put(
226+
f"/v0/projects/{user_project['uuid']}/folders/{logged_user_sub_folder['folderId']}"
227+
)
228+
await assert_status(resp, status.HTTP_204_NO_CONTENT)
229+
230+
# CREATE workspace
231+
resp = await client.post("/v0/workspaces", json={"name": "My Workspace"})
232+
data, _ = await assert_status(resp, status.HTTP_201_CREATED)
233+
logged_user_workspace = data
234+
235+
# MOVE root folder with content to workspace
236+
url = client.app.router["move_folder_to_workspace"].url_for(
237+
folder_id=f"{logged_user_root_folder['folderId']}",
238+
workspace_id=f"{logged_user_workspace['workspaceId']}",
239+
)
240+
resp = await client.post(f"{url}")
241+
await assert_status(resp, status.HTTP_204_NO_CONTENT)
242+
243+
# TRASH workspace
244+
resp = await client.post(
245+
f"/v0/workspaces/{logged_user_workspace['workspaceId']}:trash"
246+
)
247+
await assert_status(resp, status.HTTP_204_NO_CONTENT)
248+
249+
async with switch_client_session_to(client, other_user):
250+
# CREATE folders hierarchy for other_user
251+
resp = await client.post("/v0/folders", json={"name": "Root Folder"})
252+
data, _ = await assert_status(resp, status.HTTP_201_CREATED)
253+
other_user_root_folder = data
254+
255+
resp = await client.post(
256+
"/v0/folders",
257+
json={
258+
"name": "Sub Folder (other)",
259+
"parentFolderId": other_user_root_folder["folderId"],
260+
},
261+
)
262+
data, _ = await assert_status(resp, status.HTTP_201_CREATED)
263+
other_user_sub_folder = data
264+
265+
# MOVE project to subfolder
266+
resp = await client.put(
267+
f"/v0/projects/{other_user_project['uuid']}/folders/{other_user_sub_folder['folderId']}"
268+
)
269+
await assert_status(resp, status.HTTP_204_NO_CONTENT)
270+
271+
# CREATE workspace
272+
resp = await client.post(
273+
"/v0/workspaces", json={"name": "Other User Workspace"}
274+
)
275+
data, _ = await assert_status(resp, status.HTTP_201_CREATED)
276+
other_user_workspace = data
277+
278+
# MOVE Folder to workspace
279+
url = client.app.router["move_folder_to_workspace"].url_for(
280+
folder_id=f"{other_user_root_folder['folderId']}",
281+
workspace_id=f"{other_user_workspace['workspaceId']}",
282+
)
283+
resp = await client.post(f"{url}")
284+
await assert_status(resp, status.HTTP_204_NO_CONTENT)
285+
286+
# TRASH workspace
287+
resp = await client.post(
288+
f"/v0/workspaces/{other_user_workspace['workspaceId']}:trash"
289+
)
290+
await assert_status(resp, status.HTTP_204_NO_CONTENT)
291+
292+
# UNDER TEST
293+
await trash_service.safe_delete_expired_trash_as_admin(client.app)
294+
295+
async with switch_client_session_to(client, logged_user):
296+
# Verify logged_user's resources are gone
297+
resp = await client.get(
298+
f"/v0/workspaces/{logged_user_workspace['workspaceId']}"
299+
)
300+
await assert_status(resp, status.HTTP_403_FORBIDDEN)
301+
302+
resp = await client.get(f"/v0/folders/{logged_user_root_folder['folderId']}")
303+
await assert_status(resp, status.HTTP_403_FORBIDDEN)
304+
305+
resp = await client.get(f"/v0/folders/{logged_user_sub_folder['folderId']}")
306+
await assert_status(resp, status.HTTP_403_FORBIDDEN)
307+
308+
resp = await client.get(f"/v0/projects/{user_project['uuid']}")
309+
await assert_status(resp, status.HTTP_404_NOT_FOUND)
310+
311+
# Verify other_user's resources are gone
312+
async with switch_client_session_to(client, other_user):
313+
resp = await client.get(f"/v0/workspaces/{other_user_workspace['workspaceId']}")
314+
await assert_status(resp, status.HTTP_403_FORBIDDEN)
315+
316+
resp = await client.get(f"/v0/folders/{other_user_root_folder['folderId']}")
317+
await assert_status(resp, status.HTTP_403_FORBIDDEN)
318+
319+
resp = await client.get(f"/v0/folders/{other_user_sub_folder['folderId']}")
320+
await assert_status(resp, status.HTTP_403_FORBIDDEN)
321+
322+
resp = await client.get(f"/v0/projects/{other_user_project['uuid']}")
323+
await assert_status(resp, status.HTTP_404_NOT_FOUND)

0 commit comments

Comments
 (0)