-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
🗃️(api) add default values for optional Statique model fields
The importation process may create many duplicates as the upsert technique we use does not compare rows with missing fields. Two tables are mostly concerned: Operateur and Amenageur. Hence we decided to fill optional (non filled) fields with default generic strings (e.g. "NA").
- Loading branch information
Showing
4 changed files
with
114 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 = "[email protected]" | ||
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é))+$") | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 == "[email protected]" | ||
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" | ||
|
@@ -656,6 +694,48 @@ def test_bulk_for_superuser(client_auth): | |
assert json_response["items"][1] == data[1].id_pdc_itinerance | ||
|
||
|
||
def test_bulk_without_optional_fields(client_auth): | ||
"""Test the /statique/bulk create endpoint when optional fields are not provided.""" | ||
data = StatiqueFactory.batch( | ||
size=2, | ||
) | ||
|
||
payload = [ | ||
json.loads( | ||
d.model_dump_json( | ||
exclude={ | ||
"nom_amenageur", | ||
"siren_amenageur", | ||
"contact_amenageur", | ||
"nom_operateur", | ||
"telephone_operateur", | ||
} | ||
) | ||
) | ||
for d in data | ||
] | ||
response = client_auth.post("/statique/bulk", json=payload) | ||
|
||
assert response.status_code == status.HTTP_201_CREATED | ||
json_response = response.json() | ||
assert json_response["message"] == "Statique items created" | ||
assert json_response["size"] == len(payload) | ||
assert json_response["items"][0] == data[0].id_pdc_itinerance | ||
assert json_response["items"][1] == data[1].id_pdc_itinerance | ||
|
||
# Get created Statique and check defaults | ||
response = client_auth.get("/statique/") | ||
assert response.status_code == status.HTTP_200_OK | ||
json_response = response.json() | ||
for item in json_response["items"]: | ||
statique = Statique(**item) | ||
assert statique.nom_amenageur == "NA" | ||
assert statique.siren_amenageur == "123456789" | ||
assert statique.contact_amenageur == "[email protected]" | ||
assert statique.nom_operateur == "NA" | ||
assert statique.telephone_operateur == "tel:+33-1-23-45-67-89" | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"client_auth", | ||
( | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 == "[email protected]" | ||
assert statique.nom_operateur == "NA" | ||
assert statique.telephone_operateur == "+33.123456789" |