Skip to content

Commit

Permalink
🐛(api) allow date_maj field to be set to "today"
Browse files Browse the repository at this point in the history
Today is not a past date but is a perfectly acceptable value for the
`date_maj` field.
  • Loading branch information
jmaupetit committed Dec 10, 2024
1 parent e1b9f59 commit 38437e5
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 2 deletions.
4 changes: 4 additions & 0 deletions src/api/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ and this project adheres to
- Upgrade sentry-sdk to `2.19.2`
- Upgrade typer to `0.15.1`

### Fixed

- Allow `date_maj` field to be set to "today"

## [0.15.0] - 2024-11-21

### Changed
Expand Down
16 changes: 15 additions & 1 deletion src/api/qualicharge/models/static.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

import json
import re
from datetime import date, datetime, timezone
from enum import StrEnum
from typing import Optional

from pydantic import (
AfterValidator,
BaseModel,
BeforeValidator,
EmailStr,
Expand Down Expand Up @@ -107,6 +109,18 @@ def to_coordinates_tuple(value):
]


def not_future(value: date):
"""Ensure date is not in the future."""
today = datetime.now(timezone.utc).date()
if value > today:
raise ValueError(f"{value} is in the future")
return value


# A date not in the future (today or in the past)
NotFutureDate = Annotated[date, AfterValidator(not_future)]


class Statique(ModelSchemaMixin, BaseModel):
"""IRVE static model."""

Expand Down Expand Up @@ -168,7 +182,7 @@ class Statique(ModelSchemaMixin, BaseModel):
num_pdl: Optional[Annotated[str, Field(max_length=64)]]
date_mise_en_service: Optional[PastDate]
observations: Optional[str]
date_maj: PastDate
date_maj: NotFutureDate
cable_t2_attache: Optional[bool]

@model_validator(mode="after")
Expand Down
3 changes: 2 additions & 1 deletion src/api/qualicharge/schemas/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
DataGouvCoordinate,
FrenchPhoneNumber,
ImplantationStationEnum,
NotFutureDate,
RaccordementEnum,
)
from . import BaseTimestampedSQLModel
Expand Down Expand Up @@ -237,7 +238,7 @@ class Station(BaseTimestampedSQLModel, table=True):
station_deux_roues: bool
raccordement: Optional[RaccordementEnum]
num_pdl: Optional[str] = Field(max_length=64)
date_maj: PastDate = Field(sa_type=Date)
date_maj: NotFutureDate = Field(sa_type=Date)
date_mise_en_service: Optional[PastDate] = Field(sa_type=Date)

# Relationships
Expand Down
17 changes: 17 additions & 0 deletions src/api/tests/models/test_static.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
"""QualiCharge static models tests."""

from datetime import datetime, timedelta, timezone

import pytest
from pydantic_extra_types.coordinate import Coordinate

Expand Down Expand Up @@ -106,3 +108,18 @@ def test_statique_model_num_pdl():

with pytest.raises(ValueError, match="String should have at most 64 characters"):
StatiqueFactory.build(num_pdl="a" * 65)


def test_statique_model_date_maj():
"""Test statique model accepts only a `date_maj` not in the future."""
today = datetime.now(timezone.utc).date()
statique = StatiqueFactory.build(date_maj=today)
assert statique.date_maj == today

yesterday = today - timedelta(days=1)
statique = StatiqueFactory.build(date_maj=yesterday)
assert statique.date_maj == yesterday

tomorrow = today + timedelta(days=1)
with pytest.raises(ValueError, match=f"{tomorrow} is in the future"):
StatiqueFactory.build(date_maj=tomorrow)
17 changes: 17 additions & 0 deletions src/api/tests/schemas/test_static.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,23 @@ def test_station_events(db_session):
assert other_operational_unit.stations[0] == station


def test_station_date_maj(db_session):
"""Test station schema accepts only a `date_maj` not in the future."""
StationFactory.__session__ = db_session

today = datetime.now(timezone.utc).date()
station = StationFactory.create_sync(date_maj=today)
assert station.date_maj == today

yesterday = today - timedelta(days=1)
station = StationFactory.create_sync(date_maj=yesterday)
assert station.date_maj == yesterday

tomorrow = today + timedelta(days=1)
with pytest.raises(ValueError, match=f"{tomorrow} is in the future"):
StationFactory.create_sync(date_maj=tomorrow)


def test_operational_unit_create_stations_fk_no_station(db_session):
"""Test OperationalUnit.create_stations_fk method with no matching station."""
OperationalUnitFactory.__session__ = db_session
Expand Down

0 comments on commit 38437e5

Please sign in to comment.