From 56723e08d36f3484d30cd6576d2ca3b9bcef1dd4 Mon Sep 17 00:00:00 2001 From: Andrei Neagu Date: Mon, 10 Mar 2025 11:33:22 +0100 Subject: [PATCH] fixed issue with validation --- .../models/services_db.py | 17 +++++++- .../unit/with_dbs/test_db_repositories.py | 43 +++++++++++++++---- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/services/catalog/src/simcore_service_catalog/models/services_db.py b/services/catalog/src/simcore_service_catalog/models/services_db.py index 5ddcbe239ef2..2ad800d2b44d 100644 --- a/services/catalog/src/simcore_service_catalog/models/services_db.py +++ b/services/catalog/src/simcore_service_catalog/models/services_db.py @@ -9,7 +9,14 @@ from models_library.services_base import ServiceKeyVersion from models_library.services_types import ServiceKey, ServiceVersion from models_library.utils.common_validators import empty_str_to_none_pre_validator -from pydantic import BaseModel, ConfigDict, Field, field_validator +from pydantic import ( + BaseModel, + BeforeValidator, + ConfigDict, + Field, + HttpUrl, + field_validator, +) from pydantic.config import JsonDict from simcore_postgres_database.models.services_compatibility import CompatiblePolicyDict @@ -83,6 +90,12 @@ def _update_json_schema_extra(schema: JsonDict) -> None: ) +def _httpurl_to_str(value: HttpUrl | str | None) -> str | None: + if isinstance(value, HttpUrl): + return f"{value}" + return value + + class ServiceMetaDataDBCreate(BaseModel): # primary-keys key: ServiceKey @@ -96,7 +109,7 @@ class ServiceMetaDataDBCreate(BaseModel): description: str description_ui: bool = False thumbnail: str | None = None - icon: str | None = None + icon: Annotated[str | None, BeforeValidator(_httpurl_to_str)] = None version_display: str | None = None # tagging diff --git a/services/catalog/tests/unit/with_dbs/test_db_repositories.py b/services/catalog/tests/unit/with_dbs/test_db_repositories.py index 67e53525e38b..cf52a79e72b9 100644 --- a/services/catalog/tests/unit/with_dbs/test_db_repositories.py +++ b/services/catalog/tests/unit/with_dbs/test_db_repositories.py @@ -10,7 +10,7 @@ from models_library.users import UserID from packaging import version from packaging.version import Version -from pydantic import EmailStr, TypeAdapter +from pydantic import EmailStr, HttpUrl, TypeAdapter from simcore_service_catalog.db.repositories.services import ServicesRepository from simcore_service_catalog.models.services_db import ( ServiceAccessRightsAtDB, @@ -125,6 +125,31 @@ async def test_create_services( ) == service_db_create.model_dump(exclude_unset=True) +@pytest.mark.parametrize( + "url_object", + [ + "https://github.com/some/path/to/image.png?raw=true", + TypeAdapter(HttpUrl).validate_python( + "https://github.com/some/path/to/image.png?raw=true" + ), + "", + None, + ], +) +async def test_regression_service_meta_data_db_create( + create_fake_service_data: Callable, url_object: str | HttpUrl | None +): + fake_service, *_ = create_fake_service_data( + "simcore/services/dynamic/jupyterlab", + "1.0.0", + team_access="x", + everyone_access="x", + ) + + fake_service["icon"] = url_object + assert ServiceMetaDataDBCreate.model_validate(fake_service) + + async def test_read_services( services_repo: ServicesRepository, user_groups_ids: list[int], @@ -240,19 +265,19 @@ async def test_list_service_releases_version_filtered( assert latest assert latest.version == fake_catalog_with_jupyterlab.expected_latest - releases_1_1_x: list[ - ServiceMetaDataDBGet - ] = await services_repo.list_service_releases( - "simcore/services/dynamic/jupyterlab", major=1, minor=1 + releases_1_1_x: list[ServiceMetaDataDBGet] = ( + await services_repo.list_service_releases( + "simcore/services/dynamic/jupyterlab", major=1, minor=1 + ) ) assert [ s.version for s in releases_1_1_x ] == fake_catalog_with_jupyterlab.expected_1_1_x - expected_0_x_x: list[ - ServiceMetaDataDBGet - ] = await services_repo.list_service_releases( - "simcore/services/dynamic/jupyterlab", major=0 + expected_0_x_x: list[ServiceMetaDataDBGet] = ( + await services_repo.list_service_releases( + "simcore/services/dynamic/jupyterlab", major=0 + ) ) assert [ s.version for s in expected_0_x_x