Skip to content

Commit 8cb0e44

Browse files
committed
fixes tests
1 parent 4a6a684 commit 8cb0e44

File tree

3 files changed

+48
-38
lines changed

3 files changed

+48
-38
lines changed

api/specs/web-server/_projects.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,10 @@ class _ProjectCreateHeaderParams(BaseModel):
6767
@router.post(
6868
"/projects",
6969
response_model=Envelope[TaskGet],
70-
description="Creates a new project or copies an existing one",
71-
status_code=status.HTTP_201_CREATED,
70+
description="Creates a new project or copies an existing one. "
71+
"NOTE: implemented as a long running task, "
72+
"i.e. requires polling `status_href` (HTTP_200_OK) to get status and `result_href` (HTTP_201_CREATED) to get created project",
73+
status_code=status.HTTP_202_ACCEPTED,
7274
)
7375
async def create_project(
7476
_h: Annotated[_ProjectCreateHeaderParams, Depends()],

packages/models-library/src/models_library/projects_access.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ class AccessRights(BaseModel):
2525
read: bool = Field(..., description="has read access")
2626
write: bool = Field(..., description="has write access")
2727
delete: bool = Field(..., description="has deletion rights")
28+
2829
model_config = ConfigDict(extra="forbid")
2930

3031

services/web/server/tests/unit/with_dbs/02/test_projects_crud_handlers.py

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
from models_library.api_schemas_directorv2.dynamic_services import (
1919
GetProjectInactivityResponse,
2020
)
21-
from models_library.api_schemas_webserver.projects import ProjectCreateNew
2221
from models_library.products import ProductName
2322
from models_library.projects_state import ProjectState
2423
from pydantic import TypeAdapter
@@ -416,65 +415,73 @@ async def test_get_project(
416415
# POST --------
417416

418417

418+
@pytest.mark.parametrize(*standard_role_response())
419+
async def test_new_project(
420+
mock_dynamic_scheduler: None,
421+
client: TestClient,
422+
logged_user: UserInfoDict,
423+
primary_group,
424+
expected: ExpectedResponse,
425+
request_create_project: Callable[..., Awaitable[ProjectDict]],
426+
storage_subsystem_mock,
427+
project_db_cleaner,
428+
):
429+
await request_create_project(
430+
client, expected.accepted, expected.created, logged_user, primary_group
431+
)
432+
433+
419434
@pytest.mark.parametrize(
420435
"user_role",
421436
[UserRole.USER],
422437
)
423-
async def test_create_get_patch_project_icon(
438+
async def test_create_get_and_patch_project_ui_field(
439+
mock_dynamic_scheduler: None,
440+
storage_subsystem_mock,
424441
client: TestClient,
425442
logged_user: UserInfoDict,
426443
primary_group: dict[str, str],
444+
request_create_project: Callable[..., Awaitable[ProjectDict]],
445+
catalog_subsystem_mock: Callable[[list[ProjectDict]], None],
446+
project_db_cleaner,
427447
):
428-
# Step 1: Create a new project with a specific ui.icon
429-
project_data = ProjectCreateNew.model_validate(
430-
{
431-
"name": "Test Project",
432-
"description": "A project to test ui.icon",
433-
"ui": {"icon": "http://example.com/icon.png"},
434-
"workbench": {},
435-
"acess_rights": primary_group,
436-
}
437-
).model_dump(mode="json", exclude_defaults=True, by_alias=True)
438-
439-
url = client.app.router["create_project"].url_for()
440-
resp = await client.post(f"{url}", json=project_data)
441-
new_project, _ = await assert_status(resp, status.HTTP_201_CREATED)
442-
assert new_project
448+
assert client.app
449+
450+
gid = logged_user["primary_gid"]
451+
assert primary_group["gid"] == gid
443452

453+
# Step 1: Create project (long running task)
454+
new_project = await request_create_project(
455+
client,
456+
status.HTTP_202_ACCEPTED,
457+
status.HTTP_201_CREATED,
458+
logged_user,
459+
primary_group,
460+
)
444461
project_id = new_project["uuid"]
445462

463+
catalog_subsystem_mock([new_project])
464+
446465
# Step 2: Get the project and check the ui.icon
447466
url = client.app.router["get_project"].url_for(project_id=project_id)
448467
resp = await client.get(f"{url}")
449468
got_project, _ = await assert_status(resp, status.HTTP_200_OK)
450-
assert got_project["ui"]["icon"] == "http://example.com/icon.png"
469+
assert got_project["ui"] == {}
451470

452471
# Step 3: Patch the project to set ui.icon to null
453-
patch_data = {"ui": {"icon": None}}
454-
url = client.app.router["update_project"].url_for(project_id=project_id)
472+
patch_data = {"ui": {"icon": "http://example.com/icon.png"}}
473+
url = client.app.router["patch_project"].url_for(project_id=project_id)
455474
resp = await client.patch(f"{url}", json=patch_data)
456475
await assert_status(resp, status.HTTP_204_NO_CONTENT)
457476

458477
# Step 4: Get the project again and check the ui.icon is now null
459478
resp = await client.get(f"{url}")
460479
got_project, _ = await assert_status(resp, status.HTTP_200_OK)
461-
assert got_project["ui"]["icon"] is None
462-
480+
assert got_project["ui"]["icon"] == "http://example.com/icon.png"
463481

464-
@pytest.mark.parametrize(*standard_role_response())
465-
async def test_new_project(
466-
mock_dynamic_scheduler: None,
467-
client: TestClient,
468-
logged_user: UserInfoDict,
469-
primary_group,
470-
expected: ExpectedResponse,
471-
storage_subsystem_mock,
472-
project_db_cleaner,
473-
request_create_project: Callable[..., Awaitable[ProjectDict]],
474-
):
475-
await request_create_project(
476-
client, expected.accepted, expected.created, logged_user, primary_group
477-
)
482+
# Step 5: Delete project
483+
resp = await client.delete(f"{url}")
484+
await assert_status(resp, status.HTTP_204_NO_CONTENT)
478485

479486

480487
@pytest.mark.parametrize(*standard_user_role_response())

0 commit comments

Comments
 (0)