Skip to content

Commit

Permalink
Updated recipients.csv to accept both lang
Browse files Browse the repository at this point in the history
- EN FR headings are now allowed for sms and email
- Your error message will be in the language of your choice
  • Loading branch information
jzbahrai committed Sep 25, 2023
1 parent dedcf14 commit 7f83f22
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 72 deletions.
76 changes: 65 additions & 11 deletions notifications_utils/recipients.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,38 @@
region_code = os.getenv("PHONE_REGION_CODE", "US")

first_column_headings = {
"email": ["email address"],
"sms": ["phone number"],
"en": {
"email": ["email address"],
"sms": ["phone number"],
# For backwards compatibility
"letter": [
"address line 1",
"address line 2",
"address line 3",
"address line 4",
"address line 5",
"address line 6",
"postcode",
],
},
"fr": {
"email": ["adresse courriel"],
"sms": ["numéro de téléphone"],
# For backwards compatibility
"letter": [
"address line 1",
"address line 2",
"address line 3",
"address line 4",
"address line 5",
"address line 6",
"postcode",
],
},
"email": ["email address"], # left this for backwards compatibility
"sms": ["phone number"], # left this for backwards compatibility
"email_both": ["email address", "adresse courriel"],
"sms_both": ["phone number", "numéro de téléphone"],
"letter": [
"address line 1",
"address line 2",
Expand Down Expand Up @@ -60,7 +90,9 @@ def __init__(
remaining_messages=sys.maxsize,
international_sms=False,
max_rows=50000,
user_language="en",
):
self.user_language = user_language
self.file_data = strip_whitespace(file_data, extra_characters=",")
self.template_type = template_type
self.placeholders = placeholders
Expand Down Expand Up @@ -114,7 +146,10 @@ def template_type(self):
@template_type.setter
def template_type(self, value):
self._template_type = value
self.recipient_column_headers = first_column_headings[self.template_type]
self.recipient_column_headers = first_column_headings[self.user_language][self.template_type] # type: ignore
self.recipient_column_headers_lang_check = (
first_column_headings.get("email_both") if self.template_type == "email" else first_column_headings.get("sms_both")
)

@property
def has_errors(self):
Expand Down Expand Up @@ -263,11 +298,31 @@ def column_headers_as_column_keys(self):

@property
def missing_column_headers(self):
return set(
key
for key in self.placeholders
if (Columns.make_key(key) not in self.column_headers_as_column_keys and not self.is_optional_address_column(key))
)
"""
Missing headers must return the following in each case:
Eg 1: file: []
placeholders: [phone number, name]
missing: [phone number, name]
Eg 2: file: [adresse courriel]
placeholders: [email address]
missing: []
"""
result = set()
for key in self.placeholders:
# If the key has a different heading due to language, then we need to check that the column_headers
# in the file have either the same or other language. This is only for email address / phone number
if key in self.recipient_column_headers_lang_check: # type: ignore
if not set(map(Columns.make_key, self.recipient_column_headers_lang_check)).intersection( # type: ignore
set(self.column_headers_as_column_keys)
):
result.add(key)
continue
elif Columns.make_key(key) not in self.column_headers_as_column_keys and not self.is_optional_address_column(key):
result.add(key)
return result

@property
def duplicate_recipient_column_headers(self):
Expand All @@ -290,13 +345,12 @@ def is_optional_address_column(self, key):

@property
def has_recipient_columns(self):
return (
return set([list(self.column_headers_as_column_keys)[0]]).issubset(
set(
Columns.make_key(recipient_column)
for recipient_column in self.recipient_column_headers
for recipient_column in self.recipient_column_headers_lang_check # type: ignore
if not self.is_optional_address_column(recipient_column)
)
<= self.column_headers_as_column_keys
)

def _get_error_for_field(self, key, value): # noqa: C901
Expand Down
152 changes: 91 additions & 61 deletions tests/test_recipient_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,10 @@ def _index_rows(rows):


@pytest.mark.parametrize(
"file_contents,template_type,expected",
"file_contents,template_type,expected,user_language",
[
(
"",
"sms",
[],
),
(
"phone number",
"sms",
[],
),
("", "sms", [], "en"),
("phone number", "sms", [], "fr"),
(
"""
phone number,name
Expand All @@ -34,6 +26,7 @@ def _index_rows(rows):
""",
"sms",
[[("phone number", "+1 123"), ("name", "test1")], [("phone number", "+1 456"), ("name", "test2")]],
"en",
),
(
"""
Expand All @@ -43,6 +36,7 @@ def _index_rows(rows):
""",
"sms",
[[("phone number", "+1 123"), ("name", None)], [("phone number", "+1 456"), ("name", None)]],
"en",
),
(
"""
Expand All @@ -55,6 +49,7 @@ def _index_rows(rows):
[("email address", "[email protected]"), ("name", "test1")],
[("email address", "[email protected]"), ("name", "test2")],
],
"en",
),
(
"""
Expand All @@ -67,6 +62,7 @@ def _index_rows(rows):
[("email address", "[email protected]"), (None, ["test1", "red"])],
[("email address", "[email protected]"), (None, ["test2", "blue"])],
],
"en",
),
(
"""
Expand All @@ -81,6 +77,7 @@ def _index_rows(rows):
[("email address", "[email protected]"), ("name", "test2")],
[("email address", "[email protected]"), ("name", "test3")],
],
"en",
),
(
"""
Expand All @@ -93,53 +90,70 @@ def _index_rows(rows):
[("email address", "[email protected]"), ("date", "Nov 28, 2016"), ("name", "test1")],
[("email address", "[email protected]"), ("date", "Nov 29, 2016"), ("name", "test2")],
],
"en",
),
(
"""
address_line_1
Alice
Bob
phone number, list, list, list
07900900001, cat, rat, gnat
07900900002, dog, hog, frog
07900900003, elephant
""",
"letter",
[[("address_line_1", "Alice")], [("address_line_1", "Bob")]],
"sms",
[
[("phone number", "07900900001"), ("list", ["cat", "rat", "gnat"])],
[("phone number", "07900900002"), ("list", ["dog", "hog", "frog"])],
[("phone number", "07900900003"), ("list", ["elephant", None, None])],
],
"en",
),
(
"""
address line 1,address line 2,address line 5,address line 6,postcode,name,thing
A. Name,,,,XM4 5HQ,example,example
address courriel,name
[email protected],test1
[email protected], test2
""",
"letter",
"email",
[
[
("addressline1", "A. Name"),
("addressline2", None),
# optional address rows 3 and 4 not in file
("addressline5", None),
("addressline5", None),
("postcode", "XM4 5HQ"),
("name", "example"),
("thing", "example"),
]
[("address courriel", "[email protected]"), ("name", "test1")],
[("address courriel", "[email protected]"), ("name", "test2")],
],
"fr",
),
(
"""
phone number, list, list, list
numéro de téléphone, list, list, list
07900900001, cat, rat, gnat
07900900002, dog, hog, frog
07900900003, elephant
""",
"sms",
[
[("phone number", "07900900001"), ("list", ["cat", "rat", "gnat"])],
[("phone number", "07900900002"), ("list", ["dog", "hog", "frog"])],
[("phone number", "07900900003"), ("list", ["elephant", None, None])],
[("numéro de téléphone", "07900900001"), ("list", ["cat", "rat", "gnat"])],
[("numéro de téléphone", "07900900002"), ("list", ["dog", "hog", "frog"])],
[("numéro de téléphone", "07900900003"), ("list", ["elephant", None, None])],
],
"fr",
),
(
"""
numéro de téléphone, list, list, list
07900900001, cat, rat, gnat
07900900002, dog, hog, frog
07900900003, elephant
""",
"sms",
[
[("numéro de téléphone", "07900900001"), ("list", ["cat", "rat", "gnat"])],
[("numéro de téléphone", "07900900002"), ("list", ["dog", "hog", "frog"])],
[("numéro de téléphone", "07900900003"), ("list", ["elephant", None, None])],
],
"en",
),
],
)
def test_get_rows(file_contents, template_type, expected):
rows = list(RecipientCSV(file_contents, template_type=template_type).rows)
def test_get_rows(file_contents, template_type, expected, user_language):
rows = list(RecipientCSV(file_contents, template_type=template_type, user_language=user_language).rows)
if not expected:
assert rows == expected
for index, row in enumerate(expected):
Expand Down Expand Up @@ -399,35 +413,42 @@ def test_get_recipient_respects_order(file_contents, template_type, placeholders


@pytest.mark.parametrize(
"file_contents,template_type,expected,expected_missing",
"file_contents,template_type,expected,expected_missing, user_language",
[
("", "sms", [], set(["phone number", "name"])),
("", "sms", [], set(["phone number", "name"]), "en"),
("", "email", [], set(["email address", "name"]), "en"),
(
"""
phone number,name
numéro de téléphone, name
6502532222,test1
6502532222,test1
6502532222,test1
""",
"sms",
["phone number", "name"],
["numéro de téléphone", "name"],
set(),
"fr",
),
(
"""
email address,name,colour
phone number,name
6502532222,test1
6502532222,test1
6502532222,test1
""",
"email",
["email address", "name", "colour"],
"sms",
["phone number", "name"],
set(),
"en",
),
(
"""
address_line_1, address_line_2, postcode, name
email address,name,colour
""",
"letter",
["address_line_1", "address_line_2", "postcode", "name"],
"email",
["email address", "name", "colour"],
set(),
"en",
),
(
"""
Expand All @@ -436,27 +457,42 @@ def test_get_recipient_respects_order(file_contents, template_type, placeholders
"email",
["email address", "colour"],
set(["name"]),
"en",
),
(
"""
address_line_1, address_line_2, name
phone number,list,list,name,list
""",
"letter",
["address_line_1", "address_line_2", "name"],
set(["postcode"]),
"sms",
["phone number", "list", "name"],
set(),
"en",
),
(
"""
phone number,list,list,name,list
numéro de téléphone,list,list,name,list
""",
"sms",
["phone number", "list", "name"],
["numéro de téléphone", "list", "name"],
set(),
"en",
),
(
"""
list,list,name,list
""",
"sms",
[
"list",
"name",
],
set(["numéro de téléphone"]),
"fr",
),
],
)
def test_column_headers(file_contents, template_type, expected, expected_missing):
recipients = RecipientCSV(file_contents, template_type=template_type, placeholders=["name"])
def test_column_headers(file_contents, template_type, expected, expected_missing, user_language):
recipients = RecipientCSV(file_contents, template_type=template_type, placeholders=["name"], user_language=user_language)
assert recipients.column_headers == expected
assert recipients.missing_column_headers == expected_missing
assert recipients.has_errors == bool(expected_missing)
Expand All @@ -469,20 +505,14 @@ def test_column_headers(file_contents, template_type, expected, expected_missing
pytest.param("", "sms", marks=pytest.mark.xfail),
pytest.param("name", "sms", marks=pytest.mark.xfail),
pytest.param("email address", "sms", marks=pytest.mark.xfail),
pytest.param(
# missing postcode
"address_line_1, address_line_2, address_line_3, address_line_4, address_line_5",
"letter",
marks=pytest.mark.xfail,
),
("phone number", "sms"),
("phone number,name", "sms"),
("email address", "email"),
("email address,name", "email"),
("PHONENUMBER", "sms"),
("email_address", "email"),
("address_line_1, address_line_2, postcode", "letter"),
("address_line_1, address_line_2, address_line_3, address_line_4, address_line_5, address_line_6, postcode", "letter"),
("adresse courriel", "email"),
("numéro de téléphone", "sms"),
],
)
def test_recipient_column(placeholders, file_contents, template_type):
Expand Down

0 comments on commit 7f83f22

Please sign in to comment.