def test_newsletter_map_with_extra_data(self, mock_nl_slugs, mock_langs): """A newsletter map adds extra data to subscriptions""" data = { "newsletters": { "slug1": True, "slug2": False, "slug3": True, "other": True, }, "source_url": " https://example.com", "lang": "es", "format": "T", } prepared = to_vendor(data) assert prepared == { "email": {"email_format": "T", "email_lang": "es"}, "newsletters": [ { "name": "slug1", "subscribed": True, "format": "T", "lang": "es", "source": "https://example.com", }, {"name": "slug2", "subscribed": False}, { "name": "slug3", "subscribed": True, "format": "T", "lang": "es", "source": "https://example.com", }, ], }
def test_newsletter_list_with_extra_data(self, mock_nl_slugs, mock_langs): """A newsletter list can have additional data.""" data = { "newsletters": ["slug1", "slug2", "slug3", "other"], "source_url": " https://example.com", "lang": "es", "format": "T", } prepared = to_vendor(data) assert prepared == { "email": {"email_format": "T", "email_lang": "es"}, "newsletters": [ { "name": "slug1", "subscribed": True, "format": "T", "lang": "es", "source": "https://example.com", }, { "name": "slug2", "subscribed": True, "format": "T", "lang": "es", "source": "https://example.com", }, { "name": "slug3", "subscribed": True, "format": "T", "lang": "es", "source": "https://example.com", }, ], }
def test_output_with_manual_unsubscribe_all(self, mock_nl_slugs): """Manually unsubscribing is different from 'unsubscribe all'.""" data = { "newsletters": { "slug1": False, "slug2": False, "slug3": False, "slug4": False, }, } prepared = to_vendor(data) assert prepared == { "newsletters": [ { "name": "slug1", "subscribed": False }, { "name": "slug2", "subscribed": False }, { "name": "slug3", "subscribed": False }, { "name": "slug4", "subscribed": False }, ] }
def test_newsletter_map(self, mock_nl_slugs): """A newsletter map combines subscribe and unsubscribe requests.""" data = { "newsletters": { "slug1": True, "slug2": False, "slug3": True, "other": True, } } prepared = to_vendor(data) assert prepared == { "newsletters": [ { "name": "slug1", "subscribed": True }, { "name": "slug2", "subscribed": False }, { "name": "slug3", "subscribed": True }, ] }
def test_allow_rewrite_to_empty(self): """Allow setting to an empty string or None if there is an existing value""" existing_data = { "first_name": "Walter", "last_name": "Sobchak", "reason": "", "fxa_id": "12345", "amo_id": 54321, } data = { "first_name": " ", "last_name": "\t", "reason": "", "fxa_id": None, "amo_id": None, } prepared = to_vendor(data, existing_data) assert prepared == { "amo": { "user_id": None }, "email": { "first_name": "", "last_name": "" }, "fxa": { "fxa_id": None }, }
def test_ignored_fields(self): """Some fields exported to SFDC are quietly ignored in CTMS.""" data = { "_set_subscriber": True, "record_type": "someRecordType", "postal_code": "90210", "source_url": "https://example.com", "fsa_school": "U of X", "fsa_grad_year": "2020", "fsa_major": "CS", "fsa_city": "San Francisco", "fsa_current_status": "Graduate", "fsa_allow_share": True, "cv_days_interval": 2, "cv_created_at": "2021-03-11", "cv_goal_reached_at": "2021-04-11", "cv_first_contribution_date": "2021-03-12", "cv_two_day_streak": True, "cv_last_active_date": "2021-04-11", "fxa_last_login": "******", "api_key": "a-basket-api-key", "privacy": True, } prepared = to_vendor(data) assert prepared == {}
def test_newsletter_list_with_defaults(self, mock_nl_slugs, mock_langs): """A newsletter list uses the default language and format""" data = {"newsletters": ["slug1"]} existing_data = {"lang": "fr", "format": "H"} prepared = to_vendor(data, existing_data) assert prepared == { "newsletters": [ {"name": "slug1", "subscribed": True, "format": "H", "lang": "fr"}, ], }
def test_newsletter_list(self, mock_nl_slugs): """A newsletter list is treated as subscription requests.""" data = {"newsletters": ["slug1", "slug2", "slug3", "other"]} prepared = to_vendor(data) assert prepared == { "newsletters": [ {"name": "slug1", "subscribed": True}, {"name": "slug2", "subscribed": True}, {"name": "slug3", "subscribed": True}, ] }
def test_newsletter_list_with_null_source_url(self, mock_nl_slugs): """A null newsletter subscription source URL is ignored.""" data = {"newsletters": ["slug1", "slug2", "slug3", "other"], "source_url": None} prepared = to_vendor(data) assert prepared == { "newsletters": [ {"name": "slug1", "subscribed": True}, {"name": "slug2", "subscribed": True}, {"name": "slug3", "subscribed": True}, ] }
def test_newsletter_list_with_defaults_override(self, mock_nl_slugs, mock_langs): """A newsletter list uses the updated data rather than the defaults""" data = {"lang": "en", "format": "T", "newsletters": ["slug1"]} existing_data = {"lang": "fr", "format": "H"} prepared = to_vendor(data, existing_data) assert prepared == { "email": {"email_format": "T", "email_lang": "en"}, "newsletters": [ {"name": "slug1", "subscribed": True, "format": "T", "lang": "en"}, ], }
def test_amo_deleted(self): """amo_deleted requests that AMO data is deleted.""" data = { "amo_deleted": True, "amo_id": None, "amo_display_name": "Add-ons Author", "amo_homepage": "firefox/user/98765", "amo_last_login": "******", "amo_location": "California", "amo_user": True, } prepared = to_vendor(data) assert prepared == {"amo": "DELETE"}
def test_sample_format(self, mock_nl_slugs): """The output of from_vendor is a valid input to to_vendor""" data = to_vendor(SAMPLE_BASKET_FORMAT) assert data == { "amo": { "display_name": "Add-ons Author", "last_login": "******", "location": "California", "profile_url": "firefox/user/98765", "user": True, "user_id": "98765", }, "email": { "basket_token": "c4a7d759-bb52-457b-896b-90f1d3ef8433", "create_timestamp": "2020-03-28T15:41:00.000Z", "double_opt_in": True, "email_format": "H", "email_id": "332de237-cab7-4461-bcc3-48e68f42bd5c", "email_lang": "en", "first_name": "Jane", "has_opted_out_of_email": False, "last_name": "Doe", "mailing_country": "us", "primary_email": "*****@*****.**", "sfdc_id": "001A000023aABcDEFG", "unsubscribe_reason": "string", "update_timestamp": "2021-01-28T21:26:57.511Z", }, "fxa": { "account_deleted": False, "created_date": "2021-01-29T18:43:49.082375+00:00", "first_service": "sync", "fxa_id": "6eb6ed6ac3b64259968aa490c6c0b9df", "lang": "en,en-US", "primary_email": "*****@*****.**", }, "mofo": { "mofo_relevant": False }, "newsletters": [{ "name": "mozilla-welcome", "subscribed": True, "format": "H", "lang": "en", }], "vpn_waitlist": { "geo": "fr", "platform": "ios,mac" }, }
def test_truncate_empty_to_none(self): """Empty or space-only strings are omitted.""" data = { "email": "", "format": "\n", "first_name": "\r\n", "last_name": "\t", "reason": " " * 1200, "fpn_country": " ", "fpn_platform": None, } prepared = to_vendor(data) assert prepared == {}
def test_truncate(self): """Strings are stripped and truncated.""" tests = ( ("first_name", 255, "email", "first_name", f" first {'x' * 500}"), ("last_name", 255, "email", "last_name", f" Last {'x' * 500} "), ("reason", 1000, "email", "unsubscribe_reason", f"Cause:{'.' * 1500}"), ("fpn_country", 100, "vpn_waitlist", "geo", f" Iran {'a' * 100} "), ("fpn_platform", 100, "vpn_waitlist", "platform", f" Linux {'x' * 120} "), ) for field, max_length, group, key, value in tests: assert len(value) > max_length data = to_vendor({field: value}) new_value = data[group][key] assert len(new_value) == max_length
def test_output_with_unsubscribe(self, mock_nl_slugs): """An 'unsubscribe all' request is detected.""" data = { "optout": True, "newsletters": { "slug1": False, "slug2": False, "slug3": False, "slug4": False, }, } prepared = to_vendor(data) assert prepared == { "email": {"has_opted_out_of_email": True}, "newsletters": "UNSUBSCRIBE", }
def test_country(self): """country is validated and added as email.mailing_country""" tests = ( ("mx", "mx"), ("CN", "cn"), (" USA ", "us"), ("en", None), (" ABC ", None), ) for original, converted in tests: data = to_vendor({"country": original}) if converted: assert data == {"email": {"mailing_country": converted}} else: assert data == {}
def test_unknown_field_is_reported(self, mock_sentry): """Unknown basket fields are reported to Sentry.""" data = { "foo": "bar", "email": "*****@*****.**", "email_id": "332de237-cab7-4461-bcc3-48e68f42bd5c", } ctms_data = to_vendor(data) assert ctms_data == { "email": { "email_id": "332de237-cab7-4461-bcc3-48e68f42bd5c", "primary_email": "*****@*****.**", } } mock_sentry.assert_called_once_with( "ctms.to_vendor() could not convert unknown data", unknown_data={"foo": "bar"}, )
def test_lang(self, mock_languages): """lang is validated and added as email.email_lang""" tests = ( ("en", "en"), ("ES", "es"), (" FR ", "fr"), ("en-US", "en"), ("zh", "zh"), ("zh-TW ", "zh"), (" zh-CN", "zh"), ("zh-Hans ", "zh-Hans"), ("zh-Hant", "zh-Hant"), (" ru", "en"), ("en-CA", "en"), ("es-MX", "es"), ) for original, converted in tests: data = to_vendor({"lang": original}) if converted: assert data == {"email": {"email_lang": converted}} else: assert data == {}