2024-05-16 10:17:45 -04:00
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
|
|
|
|
from notifications_utils.recipients import (
|
|
|
|
|
|
InvalidEmailError,
|
|
|
|
|
|
InvalidPhoneError,
|
|
|
|
|
|
allowed_to_send_to,
|
|
|
|
|
|
format_phone_number_human_readable,
|
|
|
|
|
|
format_recipient,
|
|
|
|
|
|
get_international_phone_info,
|
|
|
|
|
|
international_phone_info,
|
|
|
|
|
|
is_us_phone_number,
|
2024-07-01 10:35:20 -07:00
|
|
|
|
show_mangled_number_clues,
|
2024-05-16 10:17:45 -04:00
|
|
|
|
try_validate_and_format_phone_number,
|
|
|
|
|
|
validate_and_format_phone_number,
|
|
|
|
|
|
validate_email_address,
|
|
|
|
|
|
validate_phone_number,
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
valid_us_phone_numbers = [
|
|
|
|
|
|
"1-202-555-0104",
|
|
|
|
|
|
"+12025550104",
|
|
|
|
|
|
"12025550104",
|
|
|
|
|
|
"2025550104",
|
|
|
|
|
|
"(202) 555-0104",
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
# TODO
|
|
|
|
|
|
# International phone number tests are commented out as a result of issue #943 in notifications-admin. We are
|
|
|
|
|
|
# deliberately eliminating the ability to send to numbers outside of country code 1. These tests should
|
|
|
|
|
|
# be removed at some point when we are sure we are never going to support international numbers
|
|
|
|
|
|
|
|
|
|
|
|
valid_international_phone_numbers = [
|
|
|
|
|
|
# "+71234567890", # Russia
|
|
|
|
|
|
# "+447123456789", # UK
|
|
|
|
|
|
# "+4407123456789", # UK
|
|
|
|
|
|
# "+4407123 456789", # UK
|
|
|
|
|
|
# "+4407123-456-789", # UK
|
|
|
|
|
|
# "+23051234567", # Mauritius,
|
|
|
|
|
|
# "+682 12345", # Cook islands
|
|
|
|
|
|
# "+3312345678",
|
|
|
|
|
|
# "+9-2345-12345-12345", # 15 digits
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
valid_phone_numbers = valid_us_phone_numbers + valid_international_phone_numbers
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
invalid_us_phone_numbers = sum(
|
|
|
|
|
|
[
|
|
|
|
|
|
[(phone_number, error) for phone_number in group]
|
|
|
|
|
|
for error, group in [
|
|
|
|
|
|
(
|
|
|
|
|
|
"Too many digits",
|
|
|
|
|
|
(
|
|
|
|
|
|
"55512345678",
|
|
|
|
|
|
"+155512345678",
|
|
|
|
|
|
"(555) 1234-5678",
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
"Not enough digits",
|
|
|
|
|
|
(
|
|
|
|
|
|
"555123123",
|
|
|
|
|
|
"(555) 123-123",
|
|
|
|
|
|
"7890x32109",
|
|
|
|
|
|
"07123 ☟☜⬇⬆☞☝",
|
|
|
|
|
|
"07123☟☜⬇⬆☞☝",
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
("Phone number range is not in use", ("1555123123",)),
|
|
|
|
|
|
("Phone number is not possible", ("07123 456789...",)),
|
|
|
|
|
|
(
|
|
|
|
|
|
"The string supplied did not seem to be a phone number.",
|
|
|
|
|
|
(
|
|
|
|
|
|
'07";DROP TABLE;"',
|
|
|
|
|
|
"ALPHANUM3R1C",
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
]
|
|
|
|
|
|
],
|
|
|
|
|
|
[],
|
|
|
|
|
|
)
|
|
|
|
|
|
|
2025-04-03 08:02:08 -07:00
|
|
|
|
# TODO what is wrong with cook islands
|
2024-05-16 10:17:45 -04:00
|
|
|
|
invalid_phone_numbers = [
|
|
|
|
|
|
("+80233456789", "Not a valid country prefix"),
|
|
|
|
|
|
("1234567", "Not enough digits"),
|
2025-04-03 08:02:08 -07:00
|
|
|
|
# ("+682 1234", "Invalid country code"), # Cook Islands phone numbers can be 5 digits
|
2024-05-16 10:17:45 -04:00
|
|
|
|
("+12345 12345 12345 6", "Too many digits"),
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
valid_email_addresses = (
|
|
|
|
|
|
"email@domain.com",
|
|
|
|
|
|
"email@domain.COM",
|
|
|
|
|
|
"firstname.lastname@domain.com",
|
|
|
|
|
|
"firstname.o'lastname@domain.com",
|
|
|
|
|
|
"email@subdomain.domain.com",
|
|
|
|
|
|
"firstname+lastname@domain.com",
|
|
|
|
|
|
"1234567890@domain.com",
|
|
|
|
|
|
"email@domain-one.com",
|
|
|
|
|
|
"_______@domain.com",
|
|
|
|
|
|
"email@domain.name",
|
|
|
|
|
|
"email@domain.superlongtld",
|
|
|
|
|
|
"email@domain.co.jp",
|
|
|
|
|
|
"firstname-lastname@domain.com",
|
|
|
|
|
|
"info@german-financial-services.vermögensberatung",
|
|
|
|
|
|
"info@german-financial-services.reallylongarbitrarytldthatiswaytoohugejustincase",
|
|
|
|
|
|
"japanese-info@例え.テスト",
|
|
|
|
|
|
"email@double--hyphen.com",
|
|
|
|
|
|
)
|
|
|
|
|
|
invalid_email_addresses = (
|
|
|
|
|
|
"email@123.123.123.123",
|
|
|
|
|
|
"email@[123.123.123.123]",
|
|
|
|
|
|
"plainaddress",
|
|
|
|
|
|
"@no-local-part.com",
|
|
|
|
|
|
"Outlook Contact <outlook-contact@domain.com>",
|
|
|
|
|
|
"no-at.domain.com",
|
|
|
|
|
|
"no-tld@domain",
|
|
|
|
|
|
";beginning-semicolon@domain.co.uk",
|
|
|
|
|
|
"middle-semicolon@domain.co;uk",
|
|
|
|
|
|
"trailing-semicolon@domain.com;",
|
|
|
|
|
|
'"email+leading-quotes@domain.com',
|
|
|
|
|
|
'email+middle"-quotes@domain.com',
|
|
|
|
|
|
'"quoted-local-part"@domain.com',
|
|
|
|
|
|
'"quoted@domain.com"',
|
|
|
|
|
|
"lots-of-dots@domain..gov..uk",
|
|
|
|
|
|
"two-dots..in-local@domain.com",
|
|
|
|
|
|
"multiple@domains@domain.com",
|
|
|
|
|
|
"spaces in local@domain.com",
|
|
|
|
|
|
"spaces-in-domain@dom ain.com",
|
|
|
|
|
|
"underscores-in-domain@dom_ain.com",
|
|
|
|
|
|
"pipe-in-domain@example.com|gov.uk",
|
|
|
|
|
|
"comma,in-local@gov.uk",
|
|
|
|
|
|
"comma-in-domain@domain,gov.uk",
|
|
|
|
|
|
"pound-sign-in-local£@domain.com",
|
|
|
|
|
|
"local-with-’-apostrophe@domain.com",
|
|
|
|
|
|
"local-with-”-quotes@domain.com",
|
|
|
|
|
|
"domain-starts-with-a-dot@.domain.com",
|
|
|
|
|
|
"brackets(in)local@domain.com",
|
|
|
|
|
|
"email-too-long-{}@example.com".format("a" * 320),
|
|
|
|
|
|
"incorrect-punycode@xn---something.com",
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("phone_number", valid_international_phone_numbers)
|
|
|
|
|
|
def test_detect_international_phone_numbers(phone_number):
|
|
|
|
|
|
assert is_us_phone_number(phone_number) is False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("phone_number", valid_us_phone_numbers)
|
|
|
|
|
|
def test_detect_us_phone_numbers(phone_number):
|
|
|
|
|
|
assert is_us_phone_number(phone_number) is True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2024-05-17 17:14:46 -04:00
|
|
|
|
("phone_number", "expected_info"),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
[
|
2025-04-03 08:02:08 -07:00
|
|
|
|
(
|
|
|
|
|
|
"+4407900900123",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="44", # UK
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
"+4407700900123",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="44", # Number in TV range
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
"+4407700800123",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="44", # UK Crown dependency, so prefix same as UK
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
( #
|
|
|
|
|
|
"+20-12-1234-1234",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="20", # Egypt
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
"+201212341234",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="20", # Egypt
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
(
|
|
|
|
|
|
"+1 664-491-3434",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="1664", # Montserrat
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
2025-04-03 08:02:08 -07:00
|
|
|
|
(
|
|
|
|
|
|
"+71234567890",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="7", # Russia
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
(
|
|
|
|
|
|
"1-202-555-0104",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=False,
|
|
|
|
|
|
country_prefix="1", # USA
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
|
|
|
|
|
(
|
|
|
|
|
|
"202-555-0104",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=False,
|
|
|
|
|
|
country_prefix="1", # USA
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
2025-04-03 08:02:08 -07:00
|
|
|
|
(
|
|
|
|
|
|
"+23051234567",
|
|
|
|
|
|
international_phone_info(
|
|
|
|
|
|
international=True,
|
|
|
|
|
|
country_prefix="230", # Mauritius
|
|
|
|
|
|
billable_units=1,
|
|
|
|
|
|
),
|
|
|
|
|
|
),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_get_international_info(phone_number, expected_info):
|
|
|
|
|
|
assert get_international_phone_info(phone_number) == expected_info
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"phone_number",
|
|
|
|
|
|
[
|
|
|
|
|
|
"+21 4321 0987",
|
|
|
|
|
|
"+00997 1234 7890",
|
|
|
|
|
|
"+801234-7890",
|
|
|
|
|
|
"+8-0-1234-78901",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_get_international_info_raises(phone_number):
|
|
|
|
|
|
with pytest.raises(InvalidPhoneError) as error:
|
|
|
|
|
|
get_international_phone_info(phone_number)
|
|
|
|
|
|
assert str(error.value) == "Not a valid country prefix"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("phone_number", valid_us_phone_numbers)
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"extra_args",
|
|
|
|
|
|
[
|
|
|
|
|
|
{},
|
|
|
|
|
|
{"international": False},
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_phone_number_accepts_valid_values(extra_args, phone_number):
|
|
|
|
|
|
try:
|
|
|
|
|
|
validate_phone_number(phone_number, **extra_args)
|
|
|
|
|
|
except InvalidPhoneError:
|
|
|
|
|
|
pytest.fail("Unexpected InvalidPhoneError")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("phone_number", valid_phone_numbers)
|
|
|
|
|
|
def test_phone_number_accepts_valid_international_values(phone_number):
|
|
|
|
|
|
try:
|
|
|
|
|
|
validate_phone_number(phone_number, international=True)
|
|
|
|
|
|
except InvalidPhoneError:
|
|
|
|
|
|
pytest.fail("Unexpected InvalidPhoneError")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("phone_number", valid_us_phone_numbers)
|
|
|
|
|
|
def test_valid_us_phone_number_can_be_formatted_consistently(phone_number):
|
|
|
|
|
|
assert validate_and_format_phone_number(phone_number) == "+12025550104"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2024-05-17 17:14:46 -04:00
|
|
|
|
("phone_number", "expected_formatted"),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
[
|
2025-04-03 08:02:08 -07:00
|
|
|
|
("+44071234567890", "+4471234567890"),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
("1-202-555-0104", "+12025550104"),
|
|
|
|
|
|
("+12025550104", "+12025550104"),
|
|
|
|
|
|
("12025550104", "+12025550104"),
|
2025-04-03 08:02:08 -07:00
|
|
|
|
("+23051234567", "+23051234567"),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_valid_international_phone_number_can_be_formatted_consistently(
|
|
|
|
|
|
phone_number, expected_formatted
|
|
|
|
|
|
):
|
|
|
|
|
|
assert (
|
|
|
|
|
|
validate_and_format_phone_number(phone_number, international=True)
|
|
|
|
|
|
== expected_formatted
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-05-17 17:14:46 -04:00
|
|
|
|
@pytest.mark.parametrize(("phone_number", "error_message"), invalid_us_phone_numbers)
|
2024-05-16 10:17:45 -04:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"extra_args",
|
|
|
|
|
|
[
|
|
|
|
|
|
{},
|
|
|
|
|
|
{"international": False},
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_phone_number_rejects_invalid_values(extra_args, phone_number, error_message):
|
|
|
|
|
|
with pytest.raises(InvalidPhoneError) as e:
|
|
|
|
|
|
validate_phone_number(phone_number, **extra_args)
|
|
|
|
|
|
assert error_message == str(e.value)
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-05-17 17:14:46 -04:00
|
|
|
|
@pytest.mark.parametrize(("phone_number", "error_message"), invalid_phone_numbers)
|
2024-05-16 10:17:45 -04:00
|
|
|
|
def test_phone_number_rejects_invalid_international_values(phone_number, error_message):
|
|
|
|
|
|
with pytest.raises(InvalidPhoneError) as e:
|
|
|
|
|
|
validate_phone_number(phone_number, international=True)
|
|
|
|
|
|
assert error_message == str(e.value)
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-07-01 10:35:20 -07:00
|
|
|
|
def test_show_mangled_number_clues():
|
|
|
|
|
|
x = show_mangled_number_clues("848!!-202?-2020$$")
|
|
|
|
|
|
assert x == "XXX!!-XXX?-XXXX$$"
|
|
|
|
|
|
|
|
|
|
|
|
|
2024-05-16 10:17:45 -04:00
|
|
|
|
@pytest.mark.parametrize("email_address", valid_email_addresses)
|
|
|
|
|
|
def test_validate_email_address_accepts_valid(email_address):
|
|
|
|
|
|
try:
|
|
|
|
|
|
assert validate_email_address(email_address) == email_address
|
|
|
|
|
|
except InvalidEmailError:
|
|
|
|
|
|
pytest.fail("Unexpected InvalidEmailError")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"email",
|
|
|
|
|
|
[
|
|
|
|
|
|
" email@domain.com ",
|
|
|
|
|
|
"\temail@domain.com",
|
|
|
|
|
|
"\temail@domain.com\n",
|
|
|
|
|
|
"\u200Bemail@domain.com\u200B",
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_validate_email_address_strips_whitespace(email):
|
|
|
|
|
|
assert validate_email_address(email) == "email@domain.com"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("email_address", invalid_email_addresses)
|
|
|
|
|
|
def test_validate_email_address_raises_for_invalid(email_address):
|
|
|
|
|
|
with pytest.raises(InvalidEmailError) as e:
|
|
|
|
|
|
validate_email_address(email_address)
|
|
|
|
|
|
assert str(e.value) == "Not a valid email address"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("phone_number", valid_us_phone_numbers)
|
|
|
|
|
|
def test_validates_against_guestlist_of_phone_numbers(phone_number):
|
|
|
|
|
|
assert allowed_to_send_to(
|
|
|
|
|
|
phone_number, ["2025550104", "2025550105", "test@example.com"]
|
|
|
|
|
|
)
|
|
|
|
|
|
assert not allowed_to_send_to(
|
|
|
|
|
|
phone_number, ["2025550105", "2028675309", "test@example.com"]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-04-03 08:02:08 -07:00
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
|
|
"recipient_number, allowlist_number",
|
|
|
|
|
|
[
|
|
|
|
|
|
["+4407123-456-789", "+4407123456789"],
|
|
|
|
|
|
["+4407123456789", "+4407123-456-789"],
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_validates_against_guestlist_of_international_phone_numbers(
|
|
|
|
|
|
recipient_number, allowlist_number
|
|
|
|
|
|
):
|
|
|
|
|
|
assert allowed_to_send_to(recipient_number, [allowlist_number])
|
2024-05-16 10:17:45 -04:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("email_address", valid_email_addresses)
|
|
|
|
|
|
def test_validates_against_guestlist_of_email_addresses(email_address):
|
|
|
|
|
|
assert not allowed_to_send_to(
|
|
|
|
|
|
email_address, ["very_special_and_unique@example.com"]
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-04-03 08:02:08 -07:00
|
|
|
|
# TODO something wrong with formatting Egyptian numbers, doesn't seem
|
|
|
|
|
|
# like this would affect sendability need to confirm with AWS simulated numbers.
|
2024-05-16 10:17:45 -04:00
|
|
|
|
@pytest.mark.parametrize(
|
2024-05-17 17:14:46 -04:00
|
|
|
|
("phone_number", "expected_formatted"),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
[
|
2025-04-03 08:02:08 -07:00
|
|
|
|
("+4407900900123", "+44 7900 900123"), # UK
|
|
|
|
|
|
("+44(0)7900900123", "+44 7900 900123"), # UK
|
|
|
|
|
|
("+447900900123", "+44 7900 900123"), # UK
|
2024-05-16 10:17:45 -04:00
|
|
|
|
# ("+20-12-1234-1234", "+20 121 234 1234"), # Egypt
|
|
|
|
|
|
# ("+201212341234", "+20 121 234 1234"), # Egypt
|
|
|
|
|
|
("+1 664 491-3434", "+1 664-491-3434"), # Montserrat
|
2025-04-03 08:02:08 -07:00
|
|
|
|
("+7 499 1231212", "+7 499 123-12-12"), # Moscow (Russia)
|
2024-05-16 10:17:45 -04:00
|
|
|
|
("1-202-555-0104", "(202) 555-0104"), # Washington DC (USA)
|
2025-04-03 08:02:08 -07:00
|
|
|
|
("+23051234567", "+230 5123 4567"), # Mauritius
|
|
|
|
|
|
("+33(0)1 12345678", "+33 1 12 34 56 78"), # Paris (France)
|
2024-05-16 10:17:45 -04:00
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_format_us_and_international_phone_numbers(phone_number, expected_formatted):
|
|
|
|
|
|
assert format_phone_number_human_readable(phone_number) == expected_formatted
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
2024-05-17 17:14:46 -04:00
|
|
|
|
("recipient", "expected_formatted"),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
[
|
|
|
|
|
|
(True, ""),
|
|
|
|
|
|
(False, ""),
|
|
|
|
|
|
(0, ""),
|
|
|
|
|
|
(0.1, ""),
|
|
|
|
|
|
(None, ""),
|
|
|
|
|
|
("foo", "foo"),
|
|
|
|
|
|
("TeSt@ExAmPl3.com", "test@exampl3.com"),
|
2025-04-03 08:02:08 -07:00
|
|
|
|
("+4407900 900 123", "+447900900123"),
|
2024-05-16 10:17:45 -04:00
|
|
|
|
("+1 800 555 5555", "+18005555555"),
|
|
|
|
|
|
],
|
|
|
|
|
|
)
|
|
|
|
|
|
def test_format_recipient(recipient, expected_formatted):
|
|
|
|
|
|
assert format_recipient(recipient) == expected_formatted
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_try_format_recipient_doesnt_throw():
|
|
|
|
|
|
assert try_validate_and_format_phone_number("ALPHANUM3R1C") == "ALPHANUM3R1C"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_format_phone_number_human_readable_doenst_throw():
|
|
|
|
|
|
assert format_phone_number_human_readable("ALPHANUM3R1C") == "ALPHANUM3R1C"
|