Skip to content

Commit 2e081c5

Browse files
committed
fix: keep all digits when formatting 13-digit SP/MG voter ids
format_voter_id used hardcoded 12-digit forward slices, so a valid 13-digit voter id (the SP/MG edge case with a 9-digit sequential number) lost its last digit and showed the wrong federative union and verifying digits, even though is_valid accepts it. Slice length-aware: the federative union and verifying digits are always the last four characters (via the existing backward-indexing helpers), and the sequential number is everything before them. 12-digit output is unchanged; 13-digit ids now format losslessly.
1 parent e1ce34a commit 2e081c5

2 files changed

Lines changed: 24 additions & 1 deletion

File tree

brutils/voter_id.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,11 +285,24 @@ def format_voter_id(voter_id: str) -> str | None:
285285
'6908 4709 28 28'
286286
>>> format_voter_id("163204010922")
287287
'1632 0401 09 22'
288+
>>> format_voter_id("3244567800167")
289+
'32445 6780 01 67'
288290
"""
289291

290292
if not is_valid(voter_id):
291293
return None
292294

295+
# The sequential number has 8 digits, except for the SP and MG edge case,
296+
# where it can have 9 digits (making the voter id 13 digits long). The
297+
# federative union and verifying digits are always the last 4 digits.
298+
sequential_number = voter_id[:-4]
299+
federative_union = _get_federative_union(voter_id)
300+
verifying_digits = _get_verifying_digits(voter_id)
301+
302+
split = len(sequential_number) - 4
293303
return "{} {} {} {}".format(
294-
voter_id[:4], voter_id[4:8], voter_id[8:10], voter_id[10:12]
304+
sequential_number[:split],
305+
sequential_number[split:],
306+
federative_union,
307+
verifying_digits,
295308
)

tests/test_voter_id.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,16 @@ def test_format_voter_id(self):
127127
self.assertIsNone(format_voter_id("000000000000"))
128128
self.assertIsNone(format_voter_id("800911840197"))
129129

130+
def test_format_voter_id_special_case(self):
131+
# SP & MG voter ids can have a 9-digit sequential number, making the
132+
# voter id 13 digits long. Formatting must keep every digit and place
133+
# the federative union and verifying digits correctly.
134+
voter_id = "3244567800167"
135+
self.assertIs(is_valid(voter_id), True)
136+
formatted = format_voter_id(voter_id)
137+
self.assertEqual(formatted, "32445 6780 01 67")
138+
self.assertEqual(formatted.replace(" ", ""), voter_id)
139+
130140

131141
if __name__ == "__main__":
132142
main()

0 commit comments

Comments
 (0)