diff --git a/src/api/CHANGELOG.md b/src/api/CHANGELOG.md index 71dccdb2..9002e6f4 100644 --- a/src/api/CHANGELOG.md +++ b/src/api/CHANGELOG.md @@ -25,6 +25,7 @@ and this project adheres to - Decrease the number of database queries for dynamic endpoints - Cache the "get PointDeCharge id from its `id_pdc_itinerance`" database query - Improve JSON string parsing using pyarrow engine +- Add default values for optional Statique model fields - Upgrade pydantic to `2.10.4` - Upgrade pydantic-settings to `2.7.1` - Upgrade python-multipart to `0.0.20` diff --git a/src/api/qualicharge/models/static.py b/src/api/qualicharge/models/static.py index ecaecb36..70f85983 100644 --- a/src/api/qualicharge/models/static.py +++ b/src/api/qualicharge/models/static.py @@ -120,11 +120,17 @@ def not_future(value: date): # A date not in the future (today or in the past) NotFutureDate = Annotated[date, AfterValidator(not_future)] +# Default values (if not provided) +DEFAULT_CHAR_VALUE: str = "NA" +DEFAULT_EMAIL_ADDRESS: str = "na@example.org" +DEFAULT_PHONE_NUMBER: FrenchPhoneNumber = FrenchPhoneNumber("+33.123456789") +DEFAULT_SIREN_NUMBER: str = "123456789" + class Statique(ModelSchemaMixin, BaseModel): """IRVE static model.""" - nom_amenageur: Optional[str] + nom_amenageur: Optional[str] = DEFAULT_CHAR_VALUE siren_amenageur: Optional[ Annotated[ str, @@ -135,11 +141,11 @@ class Statique(ModelSchemaMixin, BaseModel): ], ), ] - ] - contact_amenageur: Optional[EmailStr] - nom_operateur: Optional[str] + ] = DEFAULT_SIREN_NUMBER + contact_amenageur: Optional[EmailStr] = DEFAULT_EMAIL_ADDRESS + nom_operateur: Optional[str] = DEFAULT_CHAR_VALUE contact_operateur: EmailStr - telephone_operateur: Optional[FrenchPhoneNumber] + telephone_operateur: Optional[FrenchPhoneNumber] = DEFAULT_PHONE_NUMBER nom_enseigne: str id_station_itinerance: Annotated[ str, Field(pattern="(?:(?:^|,)(^[A-Z]{2}[A-Z0-9]{4,33}$|Non concerné))+$") diff --git a/src/api/qualicharge/schemas/sql.py b/src/api/qualicharge/schemas/sql.py index 674669de..222aa18a 100644 --- a/src/api/qualicharge/schemas/sql.py +++ b/src/api/qualicharge/schemas/sql.py @@ -18,7 +18,7 @@ from typing_extensions import Optional from ..exceptions import ObjectDoesNotExist, ProgrammingError -from ..models.static import Statique +from ..models.static import DEFAULT_CHAR_VALUE, Statique from . import BaseTimestampedSQLModel from .core import ( AccessibilitePMREnum, diff --git a/src/api/tests/api/v1/routers/test_statique.py b/src/api/tests/api/v1/routers/test_statique.py index c3c83180..d2db3b77 100644 --- a/src/api/tests/api/v1/routers/test_statique.py +++ b/src/api/tests/api/v1/routers/test_statique.py @@ -16,6 +16,7 @@ from qualicharge.auth.schemas import GroupOperationalUnit, ScopesEnum, User, UserGroup from qualicharge.conf import settings from qualicharge.factories.static import StatiqueFactory +from qualicharge.models.static import Statique from qualicharge.schemas.core import ( OperationalUnit, PointDeCharge, @@ -383,6 +384,43 @@ def test_create_for_superuser(client_auth): assert json_response["items"][0] == id_pdc_itinerance +def test_create_without_optional_fields(client_auth): + """Test the /statique/ create endpoint when optional fields are not provided.""" + id_pdc_itinerance = "FR911E1111ER1" + data = Statique( + **StatiqueFactory.build( + id_pdc_itinerance=id_pdc_itinerance, + ).model_dump( + exclude={ + "nom_amenageur", + "siren_amenageur", + "contact_amenageur", + "nom_operateur", + "telephone_operateur", + } + ) + ) + + # Create the Statique without optional fields + response = client_auth.post("/statique/", json=json.loads(data.model_dump_json())) + assert response.status_code == status.HTTP_201_CREATED + json_response = response.json() + assert json_response["message"] == "Statique items created" + assert json_response["size"] == 1 + assert json_response["items"][0] == id_pdc_itinerance + + # Get created Statique and check defaults + response = client_auth.get(f"/statique/{id_pdc_itinerance}") + assert response.status_code == status.HTTP_200_OK + json_response = response.json() + statique = Statique(**json_response) + assert statique.nom_amenageur == "NA" + assert statique.siren_amenageur == "123456789" + assert statique.contact_amenageur == "na@example.org" + assert statique.nom_operateur == "NA" + assert statique.telephone_operateur == "tel:+33-1-23-45-67-89" + + def test_create_twice(client_auth): """Test the /statique/ create endpoint with the same payload twice.""" id_pdc_itinerance = "FR911E1111ER1" diff --git a/src/api/tests/models/test_static.py b/src/api/tests/models/test_static.py index bc2cf8ea..f4164f6a 100644 --- a/src/api/tests/models/test_static.py +++ b/src/api/tests/models/test_static.py @@ -123,3 +123,25 @@ def test_statique_model_date_maj(): tomorrow = today + timedelta(days=1) with pytest.raises(ValueError, match=f"{tomorrow} is in the future"): StatiqueFactory.build(date_maj=tomorrow) + + +def test_statique_model_defaults(): + """Test the Statique model defaut values (when not provided).""" + example = StatiqueFactory.build() + statique = Statique( + **example.model_dump( + exclude={ + "nom_amenageur", + "siren_amenageur", + "contact_amenageur", + "nom_operateur", + "telephone_operateur", + } + ) + ) + + assert statique.nom_amenageur == "NA" + assert statique.siren_amenageur == "123456789" + assert statique.contact_amenageur == "na@example.org" + assert statique.nom_operateur == "NA" + assert statique.telephone_operateur == "+33.123456789"