diff --git a/quienesquien/person.py b/quienesquien/person.py index 2c95cf7..0bfde62 100644 --- a/quienesquien/person.py +++ b/quienesquien/person.py @@ -1,3 +1,5 @@ +import datetime as dt + from pydantic import ( BaseModel, ConfigDict, @@ -27,12 +29,22 @@ class Person(BaseModel): extra='allow', ) - @computed_field # type: ignore[misc] - @property + @computed_field def peso1(self) -> str: # peso1 is required for backward compatibility with previous version. return str(self.coincidencia) + @property + def fecha_nacimiento_to_date(self) -> dt.date | None: + if not self.fecha_nacimiento: + return None + try: + return dt.datetime.strptime( + self.fecha_nacimiento, '%d/%m/%Y' + ).date() + except (TypeError, ValueError): + return None + @model_validator(mode='after') def collect_extra_fields(self): if self.model_extra: @@ -42,3 +54,11 @@ def collect_extra_fields(self): self.model_extra.clear() self.model_extra.update(lowercase_extra) return self + + def matches_data( + self, date_of_birth: dt.date | None = None, curp: str | None = None + ) -> bool: + dob = self.fecha_nacimiento_to_date + match_dob = bool(dob and dob == date_of_birth) + match_curp = bool(self.curp and self.curp == curp) + return match_dob or match_curp diff --git a/quienesquien/version.py b/quienesquien/version.py index cd7ca49..a6221b3 100644 --- a/quienesquien/version.py +++ b/quienesquien/version.py @@ -1 +1 @@ -__version__ = '1.0.1' +__version__ = '1.0.2' diff --git a/tests/test_person.py b/tests/test_person.py index 87e3b2d..d8ff2fd 100644 --- a/tests/test_person.py +++ b/tests/test_person.py @@ -1,8 +1,13 @@ +import datetime as dt +from typing import Any + +import pytest + from quienesquien.person import Person -def test_collect_extra_fields(): - person_data = { +def test_collect_extra_fields() -> None: + person_data: dict[str, Any] = { 'LISTA': 'lista1', 'COINCIDENCIA': 100, 'NOMBRECOMP': 'Juan Pérez', @@ -14,5 +19,114 @@ def test_collect_extra_fields(): assert person.peso1 == '100' assert person.coincidencia == 100 assert person.nombrecomp == 'Juan Pérez' - assert person.campo_extra1 == 'valor1' - assert person.campo_extra2 == 'valor2' + + # Access extra fields through model_extra after lowercase conversion + assert person.model_extra is not None + assert person.model_extra['campo_extra1'] == 'valor1' + assert person.model_extra['campo_extra2'] == 'valor2' + + +@pytest.mark.parametrize( + 'fecha_nacimiento_input, expected_date', + [ + ('13/11/1953', dt.date(1953, 11, 13)), + (None, None), + ('', None), + ('invalid-date', None), + ('1953-11-13', None), + ('13/11', None), + ('13-11-1953', None), + ], +) +def test_fecha_nacimiento_date( + fecha_nacimiento_input: str | None, + expected_date: dt.date | None, +) -> None: + person_data: dict[str, Any] = { + 'LISTA': 'PPE', + 'COINCIDENCIA': 100, + 'NOMBRECOMP': 'Andres Manuel López Obrador', + 'FECHA_NACIMIENTO': fecha_nacimiento_input, + } + person = Person(**person_data) + + assert person.fecha_nacimiento == fecha_nacimiento_input + assert person.fecha_nacimiento_to_date == expected_date + + +@pytest.mark.parametrize( + 'p_nacimiento, p_curp, input_date, input_curp, expected_result', + [ + # Different birth dates + ('13/11/1953', None, dt.date(1953, 11, 14), None, False), + # Same birth dates + ('13/11/1953', None, dt.date(1953, 11, 13), None, True), + # Different CURPs + (None, 'LOOA531113HDFPBR07', None, 'DIFFERENT_CURP_123', False), + # Same CURPs + (None, 'LOOA531113HDFPBR07', None, 'LOOA531113HDFPBR07', True), + # Different birth dates and same curp + ( + '13/11/1953', + 'LOOA531113HDFPBR07', + dt.date(1953, 11, 14), + 'LOOA531113HDFPBR07', + True, + ), + # Same birth dates and different curp + ( + '13/11/1953', + 'LOOA531113HDFPBR07', + dt.date(1953, 11, 13), + 'DIFFERENT_CURP_123', + True, + ), + # Both date and CURP different + ( + '13/11/1953', + 'LOOA531113HDFPBR07', + dt.date(1953, 11, 14), + 'DIFFERENT_CURP_123', + False, + ), + # Both date and CURP same + ( + '13/11/1953', + 'LOOA531113HDFPBR07', + dt.date(1953, 11, 13), + 'LOOA531113HDFPBR07', + True, + ), + # No data to compare + (None, None, None, None, False), + # Person has data but no input data + ('13/11/1953', None, None, None, False), + (None, 'LOOA531113HDFPBR07', None, None, False), + ('13/11/1953', 'LOOA531113HDFPBR07', None, None, False), + # Input data but person has no data + (None, None, dt.date(1953, 11, 13), 'LOOA531113HDFPBR07', False), + ], +) +def test_matches_data( + p_nacimiento: str | None, + p_curp: str | None, + input_date: dt.date | None, + input_curp: str | None, + expected_result: bool, +) -> None: + person_data: dict[str, Any] = { + 'LISTA': 'PPE', + 'COINCIDENCIA': 90, + 'NOMBRECOMP': 'Test Person', + } + + if p_nacimiento is not None: + person_data['FECHA_NACIMIENTO'] = p_nacimiento + + if p_curp is not None: + person_data['CURP'] = p_curp + + person = Person(**person_data) + + result = person.matches_data(date_of_birth=input_date, curp=input_curp) + assert result == expected_result