Skip to content

Commit 650036b

Browse files
authored
Enhancement qeq integration (#11)
* Add fecha_nacimiento_date computed field to Person model * Add is_potential_false_positive method to Person model * Update version to 1.0.2.dev1 for development release * Refactor fecha_nacimiento_date from computed field to property in Person model * Update version to 1.0.2 for stable release * Refactor Person model methods: rename fecha_nacimiento_date to fecha_nacimiento_to_date and update is_potential_false_positive to matches_data with improved logic * Refactor matches_data method in Person model for improved logic * Update version to 1.0.2 for stable release
1 parent 534f792 commit 650036b

3 files changed

Lines changed: 141 additions & 7 deletions

File tree

quienesquien/person.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import datetime as dt
2+
13
from pydantic import (
24
BaseModel,
35
ConfigDict,
@@ -27,12 +29,22 @@ class Person(BaseModel):
2729
extra='allow',
2830
)
2931

30-
@computed_field # type: ignore[misc]
31-
@property
32+
@computed_field
3233
def peso1(self) -> str:
3334
# peso1 is required for backward compatibility with previous version.
3435
return str(self.coincidencia)
3536

37+
@property
38+
def fecha_nacimiento_to_date(self) -> dt.date | None:
39+
if not self.fecha_nacimiento:
40+
return None
41+
try:
42+
return dt.datetime.strptime(
43+
self.fecha_nacimiento, '%d/%m/%Y'
44+
).date()
45+
except (TypeError, ValueError):
46+
return None
47+
3648
@model_validator(mode='after')
3749
def collect_extra_fields(self):
3850
if self.model_extra:
@@ -42,3 +54,11 @@ def collect_extra_fields(self):
4254
self.model_extra.clear()
4355
self.model_extra.update(lowercase_extra)
4456
return self
57+
58+
def matches_data(
59+
self, date_of_birth: dt.date | None = None, curp: str | None = None
60+
) -> bool:
61+
dob = self.fecha_nacimiento_to_date
62+
match_dob = bool(dob and dob == date_of_birth)
63+
match_curp = bool(self.curp and self.curp == curp)
64+
return match_dob or match_curp

quienesquien/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = '1.0.1'
1+
__version__ = '1.0.2'

tests/test_person.py

Lines changed: 118 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
1+
import datetime as dt
2+
from typing import Any
3+
4+
import pytest
5+
16
from quienesquien.person import Person
27

38

4-
def test_collect_extra_fields():
5-
person_data = {
9+
def test_collect_extra_fields() -> None:
10+
person_data: dict[str, Any] = {
611
'LISTA': 'lista1',
712
'COINCIDENCIA': 100,
813
'NOMBRECOMP': 'Juan Pérez',
@@ -14,5 +19,114 @@ def test_collect_extra_fields():
1419
assert person.peso1 == '100'
1520
assert person.coincidencia == 100
1621
assert person.nombrecomp == 'Juan Pérez'
17-
assert person.campo_extra1 == 'valor1'
18-
assert person.campo_extra2 == 'valor2'
22+
23+
# Access extra fields through model_extra after lowercase conversion
24+
assert person.model_extra is not None
25+
assert person.model_extra['campo_extra1'] == 'valor1'
26+
assert person.model_extra['campo_extra2'] == 'valor2'
27+
28+
29+
@pytest.mark.parametrize(
30+
'fecha_nacimiento_input, expected_date',
31+
[
32+
('13/11/1953', dt.date(1953, 11, 13)),
33+
(None, None),
34+
('', None),
35+
('invalid-date', None),
36+
('1953-11-13', None),
37+
('13/11', None),
38+
('13-11-1953', None),
39+
],
40+
)
41+
def test_fecha_nacimiento_date(
42+
fecha_nacimiento_input: str | None,
43+
expected_date: dt.date | None,
44+
) -> None:
45+
person_data: dict[str, Any] = {
46+
'LISTA': 'PPE',
47+
'COINCIDENCIA': 100,
48+
'NOMBRECOMP': 'Andres Manuel López Obrador',
49+
'FECHA_NACIMIENTO': fecha_nacimiento_input,
50+
}
51+
person = Person(**person_data)
52+
53+
assert person.fecha_nacimiento == fecha_nacimiento_input
54+
assert person.fecha_nacimiento_to_date == expected_date
55+
56+
57+
@pytest.mark.parametrize(
58+
'p_nacimiento, p_curp, input_date, input_curp, expected_result',
59+
[
60+
# Different birth dates
61+
('13/11/1953', None, dt.date(1953, 11, 14), None, False),
62+
# Same birth dates
63+
('13/11/1953', None, dt.date(1953, 11, 13), None, True),
64+
# Different CURPs
65+
(None, 'LOOA531113HDFPBR07', None, 'DIFFERENT_CURP_123', False),
66+
# Same CURPs
67+
(None, 'LOOA531113HDFPBR07', None, 'LOOA531113HDFPBR07', True),
68+
# Different birth dates and same curp
69+
(
70+
'13/11/1953',
71+
'LOOA531113HDFPBR07',
72+
dt.date(1953, 11, 14),
73+
'LOOA531113HDFPBR07',
74+
True,
75+
),
76+
# Same birth dates and different curp
77+
(
78+
'13/11/1953',
79+
'LOOA531113HDFPBR07',
80+
dt.date(1953, 11, 13),
81+
'DIFFERENT_CURP_123',
82+
True,
83+
),
84+
# Both date and CURP different
85+
(
86+
'13/11/1953',
87+
'LOOA531113HDFPBR07',
88+
dt.date(1953, 11, 14),
89+
'DIFFERENT_CURP_123',
90+
False,
91+
),
92+
# Both date and CURP same
93+
(
94+
'13/11/1953',
95+
'LOOA531113HDFPBR07',
96+
dt.date(1953, 11, 13),
97+
'LOOA531113HDFPBR07',
98+
True,
99+
),
100+
# No data to compare
101+
(None, None, None, None, False),
102+
# Person has data but no input data
103+
('13/11/1953', None, None, None, False),
104+
(None, 'LOOA531113HDFPBR07', None, None, False),
105+
('13/11/1953', 'LOOA531113HDFPBR07', None, None, False),
106+
# Input data but person has no data
107+
(None, None, dt.date(1953, 11, 13), 'LOOA531113HDFPBR07', False),
108+
],
109+
)
110+
def test_matches_data(
111+
p_nacimiento: str | None,
112+
p_curp: str | None,
113+
input_date: dt.date | None,
114+
input_curp: str | None,
115+
expected_result: bool,
116+
) -> None:
117+
person_data: dict[str, Any] = {
118+
'LISTA': 'PPE',
119+
'COINCIDENCIA': 90,
120+
'NOMBRECOMP': 'Test Person',
121+
}
122+
123+
if p_nacimiento is not None:
124+
person_data['FECHA_NACIMIENTO'] = p_nacimiento
125+
126+
if p_curp is not None:
127+
person_data['CURP'] = p_curp
128+
129+
person = Person(**person_data)
130+
131+
result = person.matches_data(date_of_birth=input_date, curp=input_curp)
132+
assert result == expected_result

0 commit comments

Comments
 (0)