Skip to content

Add Mir card validation support #420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
5 changes: 3 additions & 2 deletions src/validators/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# local
from .between import between
from .card import amex, card_number, diners, discover, jcb, mastercard, unionpay, visa
from .card import amex, card_number, diners, discover, jcb, mastercard, mir, unionpay, visa
from .country import calling_code, country_code, currency
from .cron import cron
from .crypto_addresses import bsc_address, btc_address, eth_address, trx_address
Expand Down Expand Up @@ -49,8 +49,9 @@
"discover",
"jcb",
"mastercard",
"visa",
"unionpay",
"visa",
"mir",
# country
"calling_code",
"country_code",
Expand Down
22 changes: 22 additions & 0 deletions src/validators/card.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,25 @@ def discover(value: str, /):
"""
pattern = re.compile(r"^(60|64|65)")
return card_number(value) and len(value) == 16 and pattern.match(value)


@validator
def mir(value: str, /):
"""Return whether or not given value is a valid Mir card number.

Examples:
>>> mir('2200123456789019')
# Output: True
>>> mir('4242424242424242')
# Output: ValidationError(func=mir, args={'value': '4242424242424242'})

Args:
value:
Mir card number string to validate.

Returns:
(Literal[True]): If `value` is a valid Mir card number.
(ValidationError): If `value` is an invalid Mir card number.
"""
pattern = re.compile(r"^(220[0-4])")
return card_number(value) and len(value) == 16 and pattern.match(value)
32 changes: 25 additions & 7 deletions tests/test_card.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
discover,
jcb,
mastercard,
mir,
unionpay,
visa,
)
Expand All @@ -23,6 +24,7 @@
diners_cards = ["3056930009020004", "36227206271667"]
jcb_cards = ["3566002020360505"]
discover_cards = ["6011111111111117", "6011000990139424"]
mir_cards = ["2200123456789019", "2204987654321098"]


@pytest.mark.parametrize(
Expand All @@ -33,14 +35,15 @@
+ unionpay_cards
+ diners_cards
+ jcb_cards
+ discover_cards,
+ discover_cards
+ mir_cards,
)
def test_returns_true_on_valid_card_number(value: str):
"""Test returns true on valid card number."""
assert card_number(value)


@pytest.mark.parametrize("value", ["4242424242424240", "4000002760003180", "400000276000318X"])
@pytest.mark.parametrize("value", ["4242424242424240", "4000002760003180", "400000276000318X", "220012345678901X"])
def test_returns_failed_on_valid_card_number(value: str):
"""Test returns failed on valid card number."""
assert isinstance(card_number(value), ValidationError)
Expand Down Expand Up @@ -84,7 +87,7 @@ def test_returns_true_on_valid_amex(value: str):

@pytest.mark.parametrize(
"value",
visa_cards + mastercard_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards,
visa_cards + mastercard_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards + mir_cards,
)
def test_returns_failed_on_valid_amex(value: str):
"""Test returns failed on valid amex."""
Expand All @@ -99,7 +102,7 @@ def test_returns_true_on_valid_unionpay(value: str):

@pytest.mark.parametrize(
"value",
visa_cards + mastercard_cards + amex_cards + diners_cards + jcb_cards + discover_cards,
visa_cards + mastercard_cards + amex_cards + diners_cards + jcb_cards + discover_cards + mir_cards,
)
def test_returns_failed_on_valid_unionpay(value: str):
"""Test returns failed on valid unionpay."""
Expand All @@ -114,7 +117,7 @@ def test_returns_true_on_valid_diners(value: str):

@pytest.mark.parametrize(
"value",
visa_cards + mastercard_cards + amex_cards + unionpay_cards + jcb_cards + discover_cards,
visa_cards + mastercard_cards + amex_cards + unionpay_cards + jcb_cards + discover_cards + mir_cards,
)
def test_returns_failed_on_valid_diners(value: str):
"""Test returns failed on valid diners."""
Expand All @@ -129,7 +132,7 @@ def test_returns_true_on_valid_jcb(value: str):

@pytest.mark.parametrize(
"value",
visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + discover_cards,
visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + discover_cards + mir_cards,
)
def test_returns_failed_on_valid_jcb(value: str):
"""Test returns failed on valid jcb."""
Expand All @@ -144,8 +147,23 @@ def test_returns_true_on_valid_discover(value: str):

@pytest.mark.parametrize(
"value",
visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards,
visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards + mir_cards,
)
def test_returns_failed_on_valid_discover(value: str):
"""Test returns failed on valid discover."""
assert isinstance(discover(value), ValidationError)


@pytest.mark.parametrize("value", mir_cards)
def test_returns_true_on_valid_mir(value: str):
"""Test returns true on valid Mir card."""
assert mir(value)


@pytest.mark.parametrize(
"value",
visa_cards + mastercard_cards + amex_cards + unionpay_cards + diners_cards + jcb_cards + discover_cards,
)
def test_returns_failed_on_valid_mir(value: str):
"""Test returns failed on invalid Mir card (other payment systems)."""
assert isinstance(mir(value), ValidationError)
Loading