diff --git a/app/scodoc/sco_utils.py b/app/scodoc/sco_utils.py index 53d2c66cb..c2f6f2dde 100644 --- a/app/scodoc/sco_utils.py +++ b/app/scodoc/sco_utils.py @@ -152,16 +152,20 @@ def convert_fr_date( raise ScoValueError("Date (j/m/a) invalide") -def heure_to_iso8601(t, null_is_empty=False) -> str: - "convert time string to ISO 8601 (allow 16:03, 16h03, 16)" +def heure_to_iso8601(t: str | datetime.time = None) -> str: + """Convert time string or time object to ISO 8601 (allows 16:03, 16h03, 16), + returns hh:mm:ss or empty string + """ if isinstance(t, datetime.time): return t.isoformat() - if not t and null_is_empty: + if not t: return "" - t = t.strip().upper().replace("H", ":") - if t and t.count(":") == 0 and len(t) < 3: - t = t + ":00" - return t + parts = t.strip().upper().replace("H", ":").split(":") + # here we can have hh, hh:mm or hh:mm:ss + h = int(parts[0]) + m = int(parts[1]) if len(parts) > 1 else 0 + s = int(parts[2]) if len(parts) > 2 else 0 + return datetime.time(h, m, s).isoformat() def print_progress_bar( diff --git a/tests/unit/test_sco_utils.py b/tests/unit/test_sco_utils.py new file mode 100644 index 000000000..4f0baa16d --- /dev/null +++ b/tests/unit/test_sco_utils.py @@ -0,0 +1,82 @@ +"""Test des fonctions utilitaires de sco_utils.py + + +Utiliser comme: + pytest tests/unit/test_sco_utils.py + +""" + +# pylint: disable=C0111 +# no doc strings in short tests + +import datetime +import pytest + +from app.scodoc.sco_exceptions import ScoValueError +from app.scodoc.sco_utils import convert_fr_date, heure_to_iso8601 + + +def test_convert_fr_date_full_date(): + assert convert_fr_date("12/2/1972") == datetime.datetime(1972, 2, 12) + + +def test_convert_fr_date_short_date_before_pivot(): + assert convert_fr_date("12/2/24") == datetime.datetime(2024, 2, 12) + + +def test_convert_fr_date_short_date_after_pivot(): + assert convert_fr_date("12/2/72") == datetime.datetime(1972, 2, 12) + + +def test_convert_fr_date_datetime_object(): + dt = datetime.datetime(2022, 2, 12) + assert convert_fr_date(dt) == dt + + +def test_convert_fr_date_invalid_date(): + with pytest.raises(ScoValueError): + convert_fr_date("invalid date") + + +def test_convert_fr_date_iso_format(): + assert convert_fr_date("2022-02-12T00:00:00") == datetime.datetime(2022, 2, 12) + + +def test_convert_fr_date_invalid_iso_format(): + with pytest.raises(ScoValueError): + convert_fr_date("2022-02-30T00:00:00") + + +def test_heure_to_iso8601_full_time(): + assert heure_to_iso8601("16:01:02") == "16:01:02" + + +def test_heure_to_iso8601_hour_minute(): + assert heure_to_iso8601("16:03") == "16:03:00" + + +def test_heure_to_iso8601_hour_only(): + assert heure_to_iso8601("16") == "16:00:00" + + +def test_heure_to_iso8601_single_digit(): + assert heure_to_iso8601("1:2:3") == "01:02:03" + + +def test_heure_to_iso8601_invalid_input(): + with pytest.raises(ValueError): + heure_to_iso8601("invalid") + + +def test_heure_to_iso8601_datetime_time(): + time_obj = datetime.time(16, 1, 2) + assert heure_to_iso8601(time_obj) == "16:01:02" + + +def test_heure_to_iso8601_null(): + assert heure_to_iso8601("") == "" + + +# Run the tests +if __name__ == "__main__": + pytest.main()