@@ -498,3 +498,157 @@ async def test_trash_empty_workspace(
498498
499499 page = Page [WorkspaceGet ].model_validate (await resp .json ())
500500 assert page .meta .total == 0
501+
502+
503+ async def test_trash_subfolder (
504+ client : TestClient ,
505+ logged_user : UserInfoDict ,
506+ user_project : ProjectDict ,
507+ mocked_catalog : None ,
508+ mocked_dynamic_services_interface : dict [str , MagicMock ],
509+ ):
510+ assert client .app
511+
512+ # setup --------------------------------
513+ #
514+ # - /Folder
515+ # - /SubFolder
516+
517+ # CREATE a folder
518+ resp = await client .post ("/v0/folders" , json = {"name" : "Folder" })
519+ data , _ = await assert_status (resp , status .HTTP_201_CREATED )
520+ folder = FolderGet .model_validate (data )
521+
522+ # CREATE a SUB-folder
523+ resp = await client .post (
524+ "/v0/folders" ,
525+ json = {"name" : "SubFolder1" , "parentFolderId" : folder .folder_id },
526+ )
527+ data , _ = await assert_status (resp , status .HTTP_201_CREATED )
528+ subfolder = FolderGet .model_validate (data )
529+
530+ # -------------------------------------
531+
532+ # TRASH subfolder
533+ resp = await client .post (f"/v0/folders/{ subfolder .folder_id } :trash" )
534+ await assert_status (resp , status .HTTP_204_NO_CONTENT )
535+
536+ # LIST BIN (i.e. use full-depth search)
537+ url = client .app .router ["list_folders_full_search" ].url_for ()
538+ assert f"{ url } " == "/v0/folders:search"
539+
540+ resp = await client .get (
541+ "/v0/folders:search" , params = {"filters" : '{"trashed": true}' }
542+ )
543+ await assert_status (resp , status .HTTP_200_OK )
544+ page = Page [FolderGet ].model_validate (await resp .json ())
545+ assert page .meta .total == 1
546+ assert page .data [0 ].folder_id == subfolder .folder_id
547+
548+ # LIST (NOT full-depth)
549+ resp = await client .get (
550+ "/v0/folders" ,
551+ params = {"filters" : '{"trashed": true}' },
552+ )
553+ data , _ = await assert_status (resp , status .HTTP_200_OK )
554+ assert len (data ) == 0
555+
556+ resp = await client .get (
557+ "/v0/folders" ,
558+ params = {"filters" : '{"trashed": true}' , "folder_id" : f"{ folder .folder_id } " },
559+ )
560+ data , _ = await assert_status (resp , status .HTTP_200_OK )
561+ assert len (data ) == 1
562+ assert data [0 ]["folderId" ] == subfolder .folder_id
563+
564+ # UNTRASH
565+ resp = await client .post (f"/v0/folders/{ subfolder .folder_id } :untrash" )
566+ await assert_status (resp , status .HTTP_204_NO_CONTENT )
567+
568+ resp = await client .get (
569+ "/v0/folders:search" , params = {"filters" : '{"trashed": true}' }
570+ )
571+ await assert_status (resp , status .HTTP_200_OK )
572+ page = Page [FolderGet ].model_validate (await resp .json ())
573+ assert page .meta .total == 0
574+
575+
576+ async def test_trash_project_in_subfolder (
577+ client : TestClient ,
578+ logged_user : UserInfoDict ,
579+ user_project : ProjectDict ,
580+ mocked_catalog : None ,
581+ mocked_dynamic_services_interface : dict [str , MagicMock ],
582+ ):
583+ assert client .app
584+
585+ # setup --------------------------------
586+ #
587+ # - /Folder
588+ # - /SubFolder
589+ # - user_project
590+ #
591+
592+ # CREATE a folder
593+ resp = await client .post ("/v0/folders" , json = {"name" : "Folder" })
594+ data , _ = await assert_status (resp , status .HTTP_201_CREATED )
595+ folder = FolderGet .model_validate (data )
596+
597+ # CREATE a SUB-folder
598+ resp = await client .post (
599+ "/v0/folders" ,
600+ json = {"name" : "SubFolder1" , "parentFolderId" : folder .folder_id },
601+ )
602+ data , _ = await assert_status (resp , status .HTTP_201_CREATED )
603+ subfolder = FolderGet .model_validate (data )
604+
605+ # MOVE project to SUB-folder
606+ project_uuid = UUID (user_project ["uuid" ])
607+ resp = await client .put (
608+ f"/v0/projects/{ project_uuid } /folders/{ subfolder .folder_id } "
609+ )
610+ await assert_status (resp , status .HTTP_204_NO_CONTENT )
611+ # -------------------------------------
612+
613+ # TRASH project
614+ resp = await client .post (f"/v0/projects/{ project_uuid } :trash" )
615+ await assert_status (resp , status .HTTP_204_NO_CONTENT )
616+
617+ # LIST BIN (i.e. use full-depth search)
618+ url = client .app .router ["list_projects_full_search" ].url_for ()
619+ assert f"{ url } " == "/v0/projects:search"
620+
621+ resp = await client .get (
622+ "/v0/projects:search" , params = {"filters" : '{"trashed": true}' }
623+ )
624+ await assert_status (resp , status .HTTP_200_OK )
625+ page = Page [ProjectGet ].model_validate (await resp .json ())
626+ assert page .meta .total == 1
627+ assert page .data [0 ].folder_id == subfolder .folder_id
628+
629+ # LIST (NOT full-depth)
630+ resp = await client .get (
631+ "/v0/projects" ,
632+ params = {"filters" : '{"trashed": true}' },
633+ )
634+ data , _ = await assert_status (resp , status .HTTP_200_OK )
635+ assert len (data ) == 0
636+
637+ resp = await client .get (
638+ "/v0/projectsh" ,
639+ params = {"filters" : '{"trashed": true}' , "folder_id" : f"{ subfolder .folder_id } " },
640+ )
641+ data , _ = await assert_status (resp , status .HTTP_200_OK )
642+ assert len (data ) == 1
643+ assert data [0 ]["uuid" ] == project_uuid
644+
645+ # UNTRASH
646+ resp = await client .post (f"/v0/projects/{ project_uuid } :untrash" )
647+ await assert_status (resp , status .HTTP_204_NO_CONTENT )
648+
649+ resp = await client .get (
650+ "/v0/projects:search" , params = {"filters" : '{"trashed": true}' }
651+ )
652+ await assert_status (resp , status .HTTP_200_OK )
653+ page = Page [ProjectGet ].model_validate (await resp .json ())
654+ assert page .meta .total == 0
0 commit comments