From 7f83f22b8ea248f5651cde95034d0c81c82ce691 Mon Sep 17 00:00:00 2001 From: Jumana Bahrainwala Date: Wed, 20 Sep 2023 10:32:51 -0400 Subject: [PATCH 1/6] Updated recipients.csv to accept both lang - EN FR headings are now allowed for sms and email - Your error message will be in the language of your choice --- notifications_utils/recipients.py | 76 ++++++++++++--- tests/test_recipient_csv.py | 152 ++++++++++++++++++------------ 2 files changed, 156 insertions(+), 72 deletions(-) diff --git a/notifications_utils/recipients.py b/notifications_utils/recipients.py index 9b9a9863..a141a30d 100644 --- a/notifications_utils/recipients.py +++ b/notifications_utils/recipients.py @@ -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", @@ -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 @@ -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): @@ -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): @@ -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 diff --git a/tests/test_recipient_csv.py b/tests/test_recipient_csv.py index f9007a80..1b0e9d09 100644 --- a/tests/test_recipient_csv.py +++ b/tests/test_recipient_csv.py @@ -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 @@ -34,6 +26,7 @@ def _index_rows(rows): """, "sms", [[("phone number", "+1 123"), ("name", "test1")], [("phone number", "+1 456"), ("name", "test2")]], + "en", ), ( """ @@ -43,6 +36,7 @@ def _index_rows(rows): """, "sms", [[("phone number", "+1 123"), ("name", None)], [("phone number", "+1 456"), ("name", None)]], + "en", ), ( """ @@ -55,6 +49,7 @@ def _index_rows(rows): [("email address", "test@example.com"), ("name", "test1")], [("email address", "test2@example.com"), ("name", "test2")], ], + "en", ), ( """ @@ -67,6 +62,7 @@ def _index_rows(rows): [("email address", "test@example.com"), (None, ["test1", "red"])], [("email address", "test2@example.com"), (None, ["test2", "blue"])], ], + "en", ), ( """ @@ -81,6 +77,7 @@ def _index_rows(rows): [("email address", "test2@example.com"), ("name", "test2")], [("email address", "test3@example.com"), ("name", "test3")], ], + "en", ), ( """ @@ -93,53 +90,70 @@ def _index_rows(rows): [("email address", "test@example.com"), ("date", "Nov 28, 2016"), ("name", "test1")], [("email address", "test2@example.com"), ("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 + test@example.com,test1 + test2@example.com, 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", "test@example.com"), ("name", "test1")], + [("address courriel", "test2@example.com"), ("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): @@ -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", ), ( """ @@ -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) @@ -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): From 8d62ea98c066057473d1ba0d29ddddb477c83e6e Mon Sep 17 00:00:00 2001 From: Jumana Bahrainwala Date: Mon, 25 Sep 2023 17:11:29 -0400 Subject: [PATCH 2/6] add a further test --- tests/test_recipient_csv.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_recipient_csv.py b/tests/test_recipient_csv.py index 1b0e9d09..cdd218af 100644 --- a/tests/test_recipient_csv.py +++ b/tests/test_recipient_csv.py @@ -417,6 +417,7 @@ def test_get_recipient_respects_order(file_contents, template_type, placeholders [ ("", "sms", [], set(["phone number", "name"]), "en"), ("", "email", [], set(["email address", "name"]), "en"), + ("", "email", [], set(["adresse courriel", "name"]), "fr"), ( """ numéro de téléphone, name From 78bb2ec88e817c49c1f026be1c6cf3495937ff1b Mon Sep 17 00:00:00 2001 From: Jumana Bahrainwala Date: Tue, 26 Sep 2023 16:08:25 -0400 Subject: [PATCH 3/6] fix --- notifications_utils/recipients.py | 9 ++++-- tests/test_recipient_csv.py | 48 +++++++++++++++++++++++++------ 2 files changed, 45 insertions(+), 12 deletions(-) diff --git a/notifications_utils/recipients.py b/notifications_utils/recipients.py index a141a30d..b50a1b04 100644 --- a/notifications_utils/recipients.py +++ b/notifications_utils/recipients.py @@ -138,6 +138,9 @@ def placeholders(self, value): self.recipient_column_headers_as_column_keys = [ Columns.make_key(placeholder) for placeholder in self.recipient_column_headers ] + self.recipient_column_headers_lang_check_as_column_keys = [ + Columns.make_key(placeholder) for placeholder in self.recipient_column_headers_lang_check + ] @property def template_type(self): @@ -198,9 +201,9 @@ def get_rows(self): for column_name, column_value in zip(column_headers, row): column_value = strip_and_remove_obscure_whitespace(column_value) - - if Columns.make_key(column_name) in self.recipient_column_headers_as_column_keys: - output_dict[column_name] = column_value or None + if Columns.make_key(column_name) in self.recipient_column_headers_lang_check_as_column_keys: + english_name = first_column_headings["en"][self.template_type][0] + output_dict[english_name] = column_value or None else: insert_or_append_to_dict(output_dict, column_name, column_value or None) diff --git a/tests/test_recipient_csv.py b/tests/test_recipient_csv.py index cdd218af..98fc2550 100644 --- a/tests/test_recipient_csv.py +++ b/tests/test_recipient_csv.py @@ -109,14 +109,14 @@ def _index_rows(rows): ), ( """ - address courriel,name + adresse courriel,name test@example.com,test1 test2@example.com, test2 """, "email", [ - [("address courriel", "test@example.com"), ("name", "test1")], - [("address courriel", "test2@example.com"), ("name", "test2")], + [("email address", "test@example.com"), ("name", "test1")], + [("email address", "test2@example.com"), ("name", "test2")], ], "fr", ), @@ -129,9 +129,9 @@ def _index_rows(rows): """, "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])], + [("phone number", "07900900001"), ("list", ["cat", "rat", "gnat"])], + [("phone number", "07900900002"), ("list", ["dog", "hog", "frog"])], + [("phone number", "07900900003"), ("list", ["elephant", None, None])], ], "fr", ), @@ -144,9 +144,9 @@ def _index_rows(rows): """, "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])], + [("phone number", "07900900001"), ("list", ["cat", "rat", "gnat"])], + [("phone number", "07900900002"), ("list", ["dog", "hog", "frog"])], + [("phone number", "07900900003"), ("list", ["elephant", None, None])], ], "en", ), @@ -192,6 +192,36 @@ def test_get_rows_does_no_error_checking_of_rows_or_cells(mocker): assert cell_recipient_error_mock.called is False +def test_get_rows_does_no_error_checking_of_rows_or_cells_fr(mocker): + has_error_mock = mocker.patch.object(Row, "has_error") + has_bad_recipient_mock = mocker.patch.object(Row, "has_bad_recipient") + has_missing_data_mock = mocker.patch.object(Row, "has_missing_data") + cell_recipient_error_mock = mocker.patch.object(Cell, "recipient_error") + + recipients = RecipientCSV( + """ + adresse courriel, name + a@b.com, + a@b.com, My Name + a@b.com, + + + """, + template_type="email", + placeholders=["name"], + max_errors_shown=3, + ) + + rows = recipients.get_rows() + for i in range(3): + assert next(rows).recipient == "a@b.com" + + assert has_error_mock.called is False + assert has_bad_recipient_mock.called is False + assert has_missing_data_mock.called is False + assert cell_recipient_error_mock.called is False + + def test_get_rows_only_iterates_over_file_once(mocker): row_mock = mocker.patch("notifications_utils.recipients.Row") From cd36941fbcc2674484f8c5e9d0008a2c638df627 Mon Sep 17 00:00:00 2001 From: Jumana Bahrainwala Date: Tue, 26 Sep 2023 17:11:42 -0400 Subject: [PATCH 4/6] tester --- notifications_utils/columns.py | 6 ++++++ notifications_utils/recipients.py | 4 ++-- tests/test_recipient_csv.py | 16 ++++++++-------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/notifications_utils/columns.py b/notifications_utils/columns.py index 2ff7e689..04bb829c 100644 --- a/notifications_utils/columns.py +++ b/notifications_utils/columns.py @@ -44,10 +44,16 @@ def __init__( recipient_column_headers, placeholders, template, + template_type, ): self.index = index self.recipient_column_headers = recipient_column_headers self.placeholders = placeholders + self.template_type = template_type + + self.recipient_column_heards_lang_check = ( + ["email address", "adresse courriel"] if self.template_type == "email" else ["phone number", "numéro de téléphone"], + ) if template: template.values = row_dict diff --git a/notifications_utils/recipients.py b/notifications_utils/recipients.py index b50a1b04..8f994ba1 100644 --- a/notifications_utils/recipients.py +++ b/notifications_utils/recipients.py @@ -202,8 +202,7 @@ def get_rows(self): for column_name, column_value in zip(column_headers, row): column_value = strip_and_remove_obscure_whitespace(column_value) if Columns.make_key(column_name) in self.recipient_column_headers_lang_check_as_column_keys: - english_name = first_column_headings["en"][self.template_type][0] - output_dict[english_name] = column_value or None + output_dict[column_name] = column_value or None else: insert_or_append_to_dict(output_dict, column_name, column_value or None) @@ -223,6 +222,7 @@ def get_rows(self): recipient_column_headers=self.recipient_column_headers, placeholders=self.placeholders_as_column_keys, template=self.template, + template_type=self.template_type, ) else: yield None diff --git a/tests/test_recipient_csv.py b/tests/test_recipient_csv.py index 98fc2550..0c6aaa02 100644 --- a/tests/test_recipient_csv.py +++ b/tests/test_recipient_csv.py @@ -115,8 +115,8 @@ def _index_rows(rows): """, "email", [ - [("email address", "test@example.com"), ("name", "test1")], - [("email address", "test2@example.com"), ("name", "test2")], + [("adresse courriel", "test@example.com"), ("name", "test1")], + [("adresse courriel", "test2@example.com"), ("name", "test2")], ], "fr", ), @@ -129,9 +129,9 @@ def _index_rows(rows): """, "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", ), @@ -144,9 +144,9 @@ def _index_rows(rows): """, "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])], ], "en", ), From 3c7453e1f51ecc3f8b4f54adaf6f5a75511187d7 Mon Sep 17 00:00:00 2001 From: Jumana Bahrainwala Date: Wed, 27 Sep 2023 14:39:27 -0400 Subject: [PATCH 5/6] fixes --- notifications_utils/columns.py | 32 ++++++++++++++++++++------ notifications_utils/recipients.py | 2 +- tests/test_recipient_csv.py | 38 +++++++++++++++---------------- 3 files changed, 45 insertions(+), 27 deletions(-) diff --git a/notifications_utils/columns.py b/notifications_utils/columns.py index 04bb829c..c438e4ff 100644 --- a/notifications_utils/columns.py +++ b/notifications_utils/columns.py @@ -44,15 +44,14 @@ def __init__( recipient_column_headers, placeholders, template, - template_type, + template_type=None, ): self.index = index self.recipient_column_headers = recipient_column_headers self.placeholders = placeholders self.template_type = template_type - - self.recipient_column_heards_lang_check = ( - ["email address", "adresse courriel"] if self.template_type == "email" else ["phone number", "numéro de téléphone"], + self.recipient_column_hearders_lang_check = ( + ["email address", "adresse courriel"] if self.template_type == "email" else ["phone number", "numéro de téléphone"] ) if template: @@ -75,7 +74,16 @@ def has_error(self): @property def has_bad_recipient(self): - return any(self.get(recipient_column).recipient_error for recipient_column in self.recipient_column_headers) + """ + If the column has an error in the recipient field we want + to return True, otherwise False + + The recipient field is the first column in the csv. + """ + for column in self.recipient_column_hearders_lang_check: + if self.get(column).recipient_error is True: + return True + return False @property def has_missing_data(self): @@ -83,8 +91,18 @@ def has_missing_data(self): @property def recipient(self): - columns = [self.get(column).data for column in self.recipient_column_headers] - return columns[0] if len(columns) == 1 else columns + """ + We want to return the recipient from the first column in the csv + The reason we use self.recipient_column_hearders_lang_check is because + we want to check for the column name in both english and french. + + The recipient field is the first column in the csv. The column name + might be in english even though we are in french context and vice versa. + This is why we need to check both languages. + """ + for column in self.recipient_column_hearders_lang_check: + if self.get(column).data is not None: + return self.get(column).data @property def personalisation(self): diff --git a/notifications_utils/recipients.py b/notifications_utils/recipients.py index 8f994ba1..7307cbab 100644 --- a/notifications_utils/recipients.py +++ b/notifications_utils/recipients.py @@ -139,7 +139,7 @@ def placeholders(self, value): Columns.make_key(placeholder) for placeholder in self.recipient_column_headers ] self.recipient_column_headers_lang_check_as_column_keys = [ - Columns.make_key(placeholder) for placeholder in self.recipient_column_headers_lang_check + Columns.make_key(placeholder) for placeholder in self.recipient_column_headers_lang_check # type: ignore ] @property diff --git a/tests/test_recipient_csv.py b/tests/test_recipient_csv.py index 0c6aaa02..8056be6b 100644 --- a/tests/test_recipient_csv.py +++ b/tests/test_recipient_csv.py @@ -287,8 +287,9 @@ def test_get_annotated_rows(file_contents, template_type, expected): assert not recipients.has_errors -def test_get_rows_with_errors(): - recipients = RecipientCSV( +@pytest.mark.parametrize( + "file_contents", + [ """ email address, name a@b.com, @@ -300,6 +301,22 @@ def test_get_rows_with_errors(): """, + """ + adresse courriel, name + a@b.com, + a@b.com, + a@b.com, + a@b.com, + a@b.com, + a@b.com, + + + """, + ], +) +def test_get_rows_with_errors(file_contents): + recipients = RecipientCSV( + file_contents, template_type="email", placeholders=["name"], max_errors_shown=3, @@ -996,23 +1013,6 @@ def test_multiple_email_recipient_columns(): assert recipients.has_errors -def test_multiple_letter_recipient_columns(): - recipients = RecipientCSV( - """ - address line 1, Address Line 2, address line 1, address_line_2 - 1,2,3,4 - """, - template_type="letter", - ) - assert recipients.rows[0].get("addressline1").data == ("3") - assert recipients.rows[0].get("addressline1").error is None - assert recipients.has_errors - assert recipients.duplicate_recipient_column_headers == OrderedSet( - ["address line 1", "Address Line 2", "address line 1", "address_line_2"] - ) - assert recipients.has_errors - - def test_displayed_rows_when_some_rows_have_errors(): recipients = RecipientCSV( """ From b0b1110c07151a7fe0b061a9990e818609520aa1 Mon Sep 17 00:00:00 2001 From: Jumana Bahrainwala Date: Wed, 27 Sep 2023 16:22:56 -0400 Subject: [PATCH 6/6] add comment and simplify code --- notifications_utils/recipients.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/notifications_utils/recipients.py b/notifications_utils/recipients.py index 7307cbab..40d04da3 100644 --- a/notifications_utils/recipients.py +++ b/notifications_utils/recipients.py @@ -348,11 +348,13 @@ def is_optional_address_column(self, key): @property def has_recipient_columns(self): + """ + This is used to check if the first column in the csv is a recipient column + """ 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_lang_check # type: ignore - if not self.is_optional_address_column(recipient_column) ) )