Skip to content

Commit f2d87f8

Browse files
authored
Add pytest coverage for length, between, uuid, MAC, IBAN, cron, encodings and card brands (220 tests)
1 parent 604635f commit f2d87f8

1 file changed

Lines changed: 139 additions & 0 deletions

File tree

‎tests/test_cards_extended.py‎

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
"""Extended coverage for card numbers and the brand validators.
2+
3+
The repo's card tests (219 lines) cover the standard test numbers;
4+
this file pins the brand/prefix/length matrix the existing suite only
5+
samples: every brand against every other brand's number, Luhn failures
6+
that keep a valid prefix, and length-only failures.
7+
8+
All card numbers used here are the well-known gateway test numbers
9+
already used in the repo's own tests and docstrings.
10+
"""
11+
12+
import pytest
13+
14+
from validators import (
15+
ValidationError,
16+
amex,
17+
card_number,
18+
diners,
19+
discover,
20+
jcb,
21+
mastercard,
22+
mir,
23+
unionpay,
24+
visa,
25+
)
26+
27+
28+
# ---------------------------------------------------------------- generic Luhn
29+
30+
31+
@pytest.mark.parametrize(
32+
"value",
33+
["4242424242424242", "378282246310005", "6011111111111117", "30569309025904"],
34+
)
35+
def test_card_number_returns_true_on_luhn_valid_numbers(value):
36+
assert card_number(value) is True
37+
38+
39+
@pytest.mark.parametrize(
40+
"value",
41+
[
42+
"",
43+
"4242424242424241", # last digit breaks Luhn
44+
"4242 4242 4242 4242", # spaces are not stripped
45+
"4242-4242-4242-4242", # dashes are not stripped
46+
"abcd", # non-digits fail int() conversion
47+
"123", # Luhn sum is not a multiple of 10
48+
],
49+
)
50+
def test_card_number_returns_failed_validation_on_invalid_numbers(value):
51+
assert isinstance(card_number(value), ValidationError)
52+
53+
54+
# ---------------------------------------------------------------- brands
55+
56+
57+
@pytest.mark.parametrize(
58+
("validator", "value"),
59+
[
60+
(visa, "4242424242424242"),
61+
(visa, "4111111111111111"),
62+
(mastercard, "5555555555554444"),
63+
(mastercard, "2223003122003222"), # 2-series Mastercard
64+
(amex, "378282246310005"),
65+
(amex, "371449635398431"),
66+
(unionpay, "6200000000000005"),
67+
(diners, "30569309025904"), # 14 digits
68+
(diners, "3056930009020004"),
69+
(diners, "36148900647913"),
70+
(jcb, "3530111333300000"),
71+
(jcb, "3566002020360505"),
72+
(discover, "6011111111111117"),
73+
(discover, "6011000990139424"),
74+
(discover, "6445644564456445"), # 644 prefix
75+
(mir, "2200123456789019"),
76+
],
77+
)
78+
def test_brand_validators_accept_their_own_numbers(validator, value):
79+
assert validator(value) is True
80+
81+
82+
@pytest.mark.parametrize(
83+
("validator", "value"),
84+
[
85+
# Wrong brand, Luhn-valid number: prefix/length must reject it.
86+
(visa, "5555555555554444"),
87+
(mastercard, "4242424242424242"),
88+
(amex, "4242424242424242"),
89+
(unionpay, "4242424242424242"),
90+
(diners, "4242424242424242"),
91+
(jcb, "4242424242424242"),
92+
(discover, "4242424242424242"),
93+
(mir, "4242424242424242"),
94+
# Right prefix family, wrong length.
95+
(visa, "4222222222222"), # 13 digits, not 16
96+
(visa, "424242424242424"), # 15 digits, not 16
97+
(amex, "3782822463100050"), # 16 digits, not 15
98+
(mastercard, "555555555555444"), # 15 digits, not 16
99+
# Right prefix, broken Luhn.
100+
(amex, "378282246310006"),
101+
(unionpay, "6200000000000006"),
102+
(jcb, "3530111333300001"),
103+
(discover, "6011111111111118"),
104+
# Prefix just outside the accepted range.
105+
(mastercard, "2720992713989755"), # 2720-series edge, Luhn-invalid
106+
(mir, "2205123456789019"), # 2205 is outside 2200-2204
107+
(diners, "32148900647913"), # 32 is not a Diners prefix
108+
(discover, "6221111111111117"), # 62 is UnionPay, not Discover
109+
],
110+
)
111+
def test_brand_validators_reject_other_numbers(validator, value):
112+
assert isinstance(validator(value), ValidationError)
113+
114+
115+
def test_brand_validators_reject_empty_and_non_digit_input():
116+
for validator in (visa, mastercard, amex, unionpay, diners, jcb, discover, mir):
117+
assert isinstance(validator(""), ValidationError)
118+
assert isinstance(validator("abcd"), ValidationError)
119+
120+
121+
# ---------------------------------------------------------------- ValidationError mechanics
122+
123+
124+
def test_validation_error_is_falsy_and_carries_function_and_args():
125+
result = visa("5555555555554444")
126+
assert isinstance(result, ValidationError)
127+
assert bool(result) is False
128+
assert result.func.__name__ == "visa"
129+
assert result.value == "5555555555554444"
130+
assert repr(result).startswith("ValidationError(func=visa")
131+
132+
133+
def test_validation_error_raised_with_r_ve():
134+
with pytest.raises(ValidationError):
135+
visa("5555555555554444", r_ve=True)
136+
137+
138+
def test_validation_error_not_raised_with_r_ve_on_valid_input():
139+
assert visa("4242424242424242", r_ve=True) is True

0 commit comments

Comments
 (0)