diff --git a/notifications_utils/recipients.py b/notifications_utils/recipients.py index 36eda081a..3bcbfe2b3 100644 --- a/notifications_utils/recipients.py +++ b/notifications_utils/recipients.py @@ -29,10 +29,30 @@ "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 @@ -126,7 +146,7 @@ def template_type(self): @template_type.setter def template_type(self, value): self._template_type = value - self.recipient_column_headers = first_column_headings[self.user_language][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") ) @@ -278,16 +298,32 @@ 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) - ) or key not in self.recipient_column_headers_lang_check - ) - ) + """ + 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() + # import pdb; pdb.set_trace() + 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): @@ -313,7 +349,7 @@ def has_recipient_columns(self): 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 + for recipient_column in self.recipient_column_headers_lang_check # type: ignore if not self.is_optional_address_column(recipient_column) ) ) diff --git a/tests/test_recipient_csv.py b/tests/test_recipient_csv.py index aa6c409af..1b0e9d090 100644 --- a/tests/test_recipient_csv.py +++ b/tests/test_recipient_csv.py @@ -16,16 +16,8 @@ def _index_rows(rows): @pytest.mark.parametrize( "file_contents,template_type,expected,user_language", [ - ( - "", - "sms", - [], "en" - ), - ( - "phone number", - "sms", - [], "fr" - ), + ("", "sms", [], "en"), + ("phone number", "sms", [], "fr"), ( """ phone number,name @@ -33,7 +25,8 @@ def _index_rows(rows): +1 456,test2 """, "sms", - [[("phone number", "+1 123"), ("name", "test1")], [("phone number", "+1 456"), ("name", "test2")]], "en" + [[("phone number", "+1 123"), ("name", "test1")], [("phone number", "+1 456"), ("name", "test2")]], + "en", ), ( """ @@ -42,7 +35,8 @@ def _index_rows(rows): +1 456 """, "sms", - [[("phone number", "+1 123"), ("name", None)], [("phone number", "+1 456"), ("name", None)]], "en" + [[("phone number", "+1 123"), ("name", None)], [("phone number", "+1 456"), ("name", None)]], + "en", ), ( """ @@ -54,7 +48,8 @@ def _index_rows(rows): [ [("email address", "test@example.com"), ("name", "test1")], [("email address", "test2@example.com"), ("name", "test2")], - ], "en" + ], + "en", ), ( """ @@ -66,7 +61,8 @@ def _index_rows(rows): [ [("email address", "test@example.com"), (None, ["test1", "red"])], [("email address", "test2@example.com"), (None, ["test2", "blue"])], - ], "en" + ], + "en", ), ( """ @@ -80,7 +76,8 @@ def _index_rows(rows): [("email address", "test@example.com"), ("name", "test1")], [("email address", "test2@example.com"), ("name", "test2")], [("email address", "test3@example.com"), ("name", "test3")], - ], "en" + ], + "en", ), ( """ @@ -92,7 +89,8 @@ 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" + ], + "en", ), ( """ @@ -106,7 +104,8 @@ def _index_rows(rows): [("phone number", "07900900001"), ("list", ["cat", "rat", "gnat"])], [("phone number", "07900900002"), ("list", ["dog", "hog", "frog"])], [("phone number", "07900900003"), ("list", ["elephant", None, None])], - ], "en" + ], + "en", ), ( """ @@ -118,7 +117,8 @@ def _index_rows(rows): [ [("address courriel", "test@example.com"), ("name", "test1")], [("address courriel", "test2@example.com"), ("name", "test2")], - ], "fr" + ], + "fr", ), ( """ @@ -132,9 +132,10 @@ def _index_rows(rows): [("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" + ], + "fr", ), - ( + ( """ numéro de téléphone, list, list, list 07900900001, cat, rat, gnat @@ -146,7 +147,8 @@ def _index_rows(rows): [("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" + ], + "en", ), ], ) @@ -411,9 +413,22 @@ 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"), + ( + """ + numéro de téléphone, name + 6502532222,test1 + 6502532222,test1 + 6502532222,test1 + """, + "sms", + ["numéro de téléphone", "name"], + set(), + "fr", + ), ( """ phone number,name @@ -424,6 +439,7 @@ def test_get_recipient_respects_order(file_contents, template_type, placeholders "sms", ["phone number", "name"], set(), + "en", ), ( """ @@ -432,6 +448,7 @@ def test_get_recipient_respects_order(file_contents, template_type, placeholders "email", ["email address", "name", "colour"], set(), + "en", ), ( """ @@ -440,6 +457,7 @@ def test_get_recipient_respects_order(file_contents, template_type, placeholders "email", ["email address", "colour"], set(["name"]), + "en", ), ( """ @@ -448,11 +466,33 @@ def test_get_recipient_respects_order(file_contents, template_type, placeholders "sms", ["phone number", "list", "name"], set(), + "en", + ), + ( + """ + numéro de téléphone,list,list,name,list + """, + "sms", + ["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) @@ -473,7 +513,6 @@ def test_column_headers(file_contents, template_type, expected, expected_missing ("email_address", "email"), ("adresse courriel", "email"), ("numéro de téléphone", "sms"), - ("numero de telephone", "sms") ], ) def test_recipient_column(placeholders, file_contents, template_type):