1515from dstack ._internal .server .services .permissions import DefaultPermissions
1616from dstack ._internal .server .services .projects import add_project_member
1717from dstack ._internal .server .testing .common import (
18+ create_export ,
1819 create_fleet ,
1920 create_project ,
2021 create_repo ,
@@ -33,14 +34,6 @@ async def test_returns_40x_if_not_authenticated(self, test_db, client: AsyncClie
3334 response = await client .post ("/api/projects/list" )
3435 assert response .status_code in [401 , 403 ]
3536
36- @pytest .mark .asyncio
37- @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
38- async def test_list_only_no_fleets_returns_40x_if_not_authenticated (
39- self , test_db , client : AsyncClient
40- ):
41- response = await client .post ("/api/projects/list_only_no_fleets" )
42- assert response .status_code in [401 , 403 ]
43-
4437 @pytest .mark .asyncio
4538 @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
4639 async def test_returns_empty_list (self , test_db , session : AsyncSession , client : AsyncClient ):
@@ -391,6 +384,14 @@ async def test_returns_total_count(self, test_db, session: AsyncSession, client:
391384
392385
393386class TestListOnlyNoFleets :
387+ @pytest .mark .asyncio
388+ @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
389+ async def test_list_only_no_fleets_returns_40x_if_not_authenticated (
390+ self , test_db , client : AsyncClient
391+ ):
392+ response = await client .post ("/api/projects/list_only_no_fleets" )
393+ assert response .status_code in [401 , 403 ]
394+
394395 @pytest .mark .asyncio
395396 @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
396397 async def test_only_no_fleets_returns_projects_without_active_fleets (
@@ -556,6 +557,48 @@ async def test_only_no_fleets_empty_result(
556557 projects = response .json ()
557558 assert len (projects ) == 0
558559
560+ @pytest .mark .asyncio
561+ @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
562+ async def test_only_no_fleets_not_includes_project_with_imported_fleets (
563+ self , test_db , session : AsyncSession , client : AsyncClient
564+ ):
565+ user = await create_user (session = session , global_role = GlobalRole .USER )
566+ exporter_project = await create_project (
567+ session = session , owner = user , name = "exporter_project"
568+ )
569+ await add_project_member (
570+ session = session , project = exporter_project , user = user , project_role = ProjectRole .USER
571+ )
572+ fleet = await create_fleet (session = session , project = exporter_project )
573+ importer_project = await create_project (
574+ session = session , owner = user , name = "importer_project"
575+ )
576+ await add_project_member (
577+ session = session , project = importer_project , user = user , project_role = ProjectRole .USER
578+ )
579+ await create_export (
580+ session = session ,
581+ exporter_project = exporter_project ,
582+ importer_projects = [importer_project ],
583+ exported_fleets = [fleet ],
584+ )
585+ project_no_fleets = await create_project (
586+ session = session , owner = user , name = "project_no_fleets"
587+ )
588+ await add_project_member (
589+ session = session , project = project_no_fleets , user = user , project_role = ProjectRole .USER
590+ )
591+
592+ response = await client .post (
593+ "/api/projects/list_only_no_fleets" ,
594+ headers = get_auth_headers (user .token ),
595+ )
596+ assert response .status_code == 200
597+ projects = response .json ()
598+
599+ assert len (projects ) == 1
600+ assert projects [0 ]["project_name" ] == "project_no_fleets"
601+
559602 @pytest .mark .asyncio
560603 @pytest .mark .parametrize ("test_db" , ["sqlite" , "postgres" ], indirect = True )
561604 async def test_only_no_fleets_respects_user_permissions (
0 commit comments