From e86869d63c48b6feabed7a36090a92e226039c3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Cabrera?= Date: Mon, 13 Oct 2025 15:12:58 -0600 Subject: [PATCH] add expiration date field --- mati/types/enums.py | 35 +++++++++++++++++++++++ mati/version.py | 2 +- tests/test_types.py | 69 ++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 104 insertions(+), 2 deletions(-) diff --git a/mati/types/enums.py b/mati/types/enums.py index 8410988..f3123dc 100644 --- a/mati/types/enums.py +++ b/mati/types/enums.py @@ -1,4 +1,5 @@ from dataclasses import dataclass, field, fields +from datetime import date from enum import Enum from typing import Any, BinaryIO, Dict, List, Optional, Union @@ -184,6 +185,40 @@ def ocr_number(self) -> str: return self.fields['ocr_number']['value'] return '' + @property + def expiration_date(self) -> Optional[date]: + """ + This property fills the expiration date direct from the ocr + fields `expiration_date`. + + Returns a date object if the field is present and valid. + Returns None if the field is missing, invalid, or fields is None. + """ + if self.fields is None: + return None + try: + date_str = self.fields['expiration_date']['value'] + return date.fromisoformat(date_str) + except (KeyError, TypeError, ValueError): + return None + + @property + def emission_date(self) -> Optional[date]: + """ + This property fills the emission date direct from the ocr + fields `emission_date`. + + Returns a date object if the field is present and valid. + Returns None if the field is missing, invalid, or fields is None. + """ + if self.fields is None: + return None + try: + date_str = self.fields['emission_date']['value'] + return date.fromisoformat(date_str) + except (KeyError, TypeError, ValueError): + return None + def add_expired_step(self) -> None: ''' Appends an expired error step to the document if missing. diff --git a/mati/version.py b/mati/version.py index 2940e26..9d2551a 100644 --- a/mati/version.py +++ b/mati/version.py @@ -1 +1 @@ -__version__ = '2.0.8' +__version__ = '2.0.9' diff --git a/tests/test_types.py b/tests/test_types.py index f5b2639..886e66b 100644 --- a/tests/test_types.py +++ b/tests/test_types.py @@ -1,8 +1,11 @@ +from datetime import date +from typing import Any, Dict, Optional + import pytest from pytest_lazyfixture import lazy_fixture from mati.types import ValidationInputType -from mati.types.enums import VerificationDocumentStep +from mati.types.enums import VerificationDocument, VerificationDocumentStep def test_type_to_str(): @@ -44,3 +47,67 @@ def test_excess_fields(): data = {'some': 'data', 'aditional': 'data', 'id': 'foo', 'status': 10} VerificationDocumentStep._filter_excess_fields(data) assert 'some' not in data + + +@pytest.mark.parametrize( + ('fields', 'expected'), + [ + ( + { + 'expiration_date': { + 'value': '2030-12-31', + 'label': 'Date of Expiration', + 'format': 'date', + } + }, + date(2030, 12, 31), + ), + (None, None), + ({'address': {'value': 'Test Address', 'label': 'Address'}}, None), + ({'expiration_date': {'label': 'Date of Expiration'}}, None), + ], +) +def test_expiration_date_property( + fields: Optional[Dict[str, Any]], expected: Optional[date] +) -> None: + doc = VerificationDocument( + country='MX', + region='', + photos=[], + steps=[], + type='national-id', + fields=fields, + ) + assert doc.expiration_date == expected + + +@pytest.mark.parametrize( + ('fields', 'expected'), + [ + ( + { + 'emission_date': { + 'value': '2023-01-15', + 'label': 'Emission Date', + 'format': 'date', + } + }, + date(2023, 1, 15), + ), + (None, None), + ({'address': {'value': 'Test Address', 'label': 'Address'}}, None), + ({'emission_date': {'label': 'Emission Date'}}, None), + ], +) +def test_emission_date_property( + fields: Optional[Dict[str, Any]], expected: Optional[date] +) -> None: + doc = VerificationDocument( + country='MX', + region='', + photos=[], + steps=[], + type='proof-of-residency', + fields=fields, + ) + assert doc.emission_date == expected