Skip to content

Commit bafe62e

Browse files
feat: add Mir card validation support (#420)
* feat(validators): add Mir card number validation * feat: add mir method to __init__ * test(card): add Mir card validation tests * docs(mir): update example valid mir card * fix(tests): update examples mir_cards and drop mir_cards from failed_on_valid_mastercard * fix: rearrangement of imports * fix(tests): update imports * chore: formatting --------- Co-authored-by: Yozachar <[email protected]>
1 parent 7c97eca commit bafe62e

File tree

3 files changed

+94
-9
lines changed

3 files changed

+94
-9
lines changed

src/validators/__init__.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
# local
44
from .between import between
5-
from .card import amex, card_number, diners, discover, jcb, mastercard, unionpay, visa
5+
from .card import amex, card_number, diners, discover, jcb, mastercard, mir, unionpay, visa
66
from .country import calling_code, country_code, currency
77
from .cron import cron
88
from .crypto_addresses import bsc_address, btc_address, eth_address, trx_address
@@ -49,8 +49,9 @@
4949
"discover",
5050
"jcb",
5151
"mastercard",
52-
"visa",
5352
"unionpay",
53+
"visa",
54+
"mir",
5455
# country
5556
"calling_code",
5657
"country_code",

src/validators/card.py

+22
Original file line numberDiff line numberDiff line change
@@ -192,3 +192,25 @@ def discover(value: str, /):
192192
"""
193193
pattern = re.compile(r"^(60|64|65)")
194194
return card_number(value) and len(value) == 16 and pattern.match(value)
195+
196+
197+
@validator
198+
def mir(value: str, /):
199+
"""Return whether or not given value is a valid Mir card number.
200+
201+
Examples:
202+
>>> mir('2200123456789019')
203+
True
204+
>>> mir('4242424242424242')
205+
ValidationError(func=mir, args={'value': '4242424242424242'})
206+
207+
Args:
208+
value:
209+
Mir card number string to validate.
210+
211+
Returns:
212+
(Literal[True]): If `value` is a valid Mir card number.
213+
(ValidationError): If `value` is an invalid Mir card number.
214+
"""
215+
pattern = re.compile(r"^(220[0-4])")
216+
return card_number(value) and len(value) == 16 and pattern.match(value)

tests/test_card.py

+69-7
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
discover,
1313
jcb,
1414
mastercard,
15+
mir,
1516
unionpay,
1617
visa,
1718
)
@@ -23,6 +24,7 @@
2324
diners_cards = ["3056930009020004", "36227206271667"]
2425
jcb_cards = ["3566002020360505"]
2526
discover_cards = ["6011111111111117", "6011000990139424"]
27+
mir_cards = ["2200123456789019", "2204987654321098"]
2628

2729

2830
@pytest.mark.parametrize(
@@ -33,14 +35,23 @@
3335
+ unionpay_cards
3436
+ diners_cards
3537
+ jcb_cards
36-
+ discover_cards,
38+
+ discover_cards
39+
+ mir_cards,
3740
)
3841
def test_returns_true_on_valid_card_number(value: str):
3942
"""Test returns true on valid card number."""
4043
assert card_number(value)
4144

4245

43-
@pytest.mark.parametrize("value", ["4242424242424240", "4000002760003180", "400000276000318X"])
46+
@pytest.mark.parametrize(
47+
"value",
48+
[
49+
"4242424242424240",
50+
"4000002760003180",
51+
"400000276000318X",
52+
"220012345678901X",
53+
],
54+
)
4455
def test_returns_failed_on_valid_card_number(value: str):
4556
"""Test returns failed on valid card number."""
4657
assert isinstance(card_number(value), ValidationError)
@@ -84,7 +95,13 @@ def test_returns_true_on_valid_amex(value: str):
8495

8596
@pytest.mark.parametrize(
8697
"value",
87-
visa_cards + mastercard_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards,
98+
visa_cards
99+
+ mastercard_cards
100+
+ unionpay_cards
101+
+ diners_cards
102+
+ jcb_cards
103+
+ discover_cards
104+
+ mir_cards,
88105
)
89106
def test_returns_failed_on_valid_amex(value: str):
90107
"""Test returns failed on valid amex."""
@@ -99,7 +116,13 @@ def test_returns_true_on_valid_unionpay(value: str):
99116

100117
@pytest.mark.parametrize(
101118
"value",
102-
visa_cards + mastercard_cards + amex_cards + diners_cards + jcb_cards + discover_cards,
119+
visa_cards
120+
+ mastercard_cards
121+
+ amex_cards
122+
+ diners_cards
123+
+ jcb_cards
124+
+ discover_cards
125+
+ mir_cards,
103126
)
104127
def test_returns_failed_on_valid_unionpay(value: str):
105128
"""Test returns failed on valid unionpay."""
@@ -114,7 +137,13 @@ def test_returns_true_on_valid_diners(value: str):
114137

115138
@pytest.mark.parametrize(
116139
"value",
117-
visa_cards + mastercard_cards + amex_cards + unionpay_cards + jcb_cards + discover_cards,
140+
visa_cards
141+
+ mastercard_cards
142+
+ amex_cards
143+
+ unionpay_cards
144+
+ jcb_cards
145+
+ discover_cards
146+
+ mir_cards,
118147
)
119148
def test_returns_failed_on_valid_diners(value: str):
120149
"""Test returns failed on valid diners."""
@@ -129,7 +158,13 @@ def test_returns_true_on_valid_jcb(value: str):
129158

130159
@pytest.mark.parametrize(
131160
"value",
132-
visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + discover_cards,
161+
visa_cards
162+
+ mastercard_cards
163+
+ amex_cards
164+
+ unionpay_cards
165+
+ diners_cards
166+
+ discover_cards
167+
+ mir_cards,
133168
)
134169
def test_returns_failed_on_valid_jcb(value: str):
135170
"""Test returns failed on valid jcb."""
@@ -144,8 +179,35 @@ def test_returns_true_on_valid_discover(value: str):
144179

145180
@pytest.mark.parametrize(
146181
"value",
147-
visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards,
182+
visa_cards
183+
+ mastercard_cards
184+
+ amex_cards
185+
+ unionpay_cards
186+
+ diners_cards
187+
+ jcb_cards
188+
+ mir_cards,
148189
)
149190
def test_returns_failed_on_valid_discover(value: str):
150191
"""Test returns failed on valid discover."""
151192
assert isinstance(discover(value), ValidationError)
193+
194+
195+
@pytest.mark.parametrize("value", mir_cards)
196+
def test_returns_true_on_valid_mir(value: str):
197+
"""Test returns true on valid Mir card."""
198+
assert mir(value)
199+
200+
201+
@pytest.mark.parametrize(
202+
"value",
203+
visa_cards
204+
+ mastercard_cards
205+
+ amex_cards
206+
+ unionpay_cards
207+
+ diners_cards
208+
+ jcb_cards
209+
+ discover_cards,
210+
)
211+
def test_returns_failed_on_valid_mir(value: str):
212+
"""Test returns failed on invalid Mir card (other payment systems)."""
213+
assert isinstance(mir(value), ValidationError)

0 commit comments

Comments
 (0)