def test_update_user_set_works_if_no_newsletters(self, get_user_data, sfdc_mock): """ A blank `newsletters` field when the update type is SET indicates that the person wishes to unsubscribe from all newsletters. This has caused exceptions because '' is not a valid newsletter name. """ models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en-US,fr', vendor_id='TITLE_UNKNOWN', ) data = { 'lang': 'en', 'country': 'US', 'newsletters': '', 'format': 'H', 'email': self.email, 'token': self.token, } sfdc_data = data.copy() sfdc_data['newsletters'] = {'slug': False} get_user_data.return_value = self.get_user_data upsert_user(SET, data) # We should have looked up the user's data get_user_data.assert_called() # We'll specifically unsubscribe each newsletter the user is # subscribed to. sfdc_mock.update.assert_called_with(self.get_user_data, sfdc_data)
def test_resubscribe_doesnt_update_newsletter(self, sfdc_mock, get_user_data): """ When subscribing to things the user is already subscribed to, we do not pass that newsletter to SF because we don't want that newsletter to be updated for no reason as that could cause another welcome to be sent. """ models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en-US,fr', vendor_id='TITLE_UNKNOWN', ) # We're going to ask to subscribe to this one again data = { 'lang': 'en', 'country': 'US', 'newsletters': 'slug', 'format': 'H', 'email': self.email, } sfdc_data = data.copy() sfdc_data['newsletters'] = {} get_user_data.return_value = self.get_user_data upsert_user(SUBSCRIBE, data) # We should have looked up the user's data get_user_data.assert_called() # We should not have mentioned this newsletter in our call to ET sfdc_mock.update.assert_called_with(self.get_user_data, sfdc_data)
def test_existing_mofo_user_subscribes_to_mofo_newsletter( self, get_user_data, sfdc_mock, ctms_mock, confirm_mock ): """If a user is already MoFo-relevant, a subscription does not set it again.""" user_data = self.get_user_data.copy() user_data["mofo_relevant"] = True get_user_data.return_value = user_data models.Newsletter.objects.create( slug="mozilla-foundation", title="The Mozilla Foundation News", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=False, is_mofo=True, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "mozilla-foundation", "email": self.email, } upsert_user(SUBSCRIBE, data) update_data = data.copy() update_data["newsletters"] = {"mozilla-foundation": True} update_data["optin"] = True sfdc_mock.update.assert_called_with(user_data, update_data) ctms_mock.update.assert_called_with(user_data, update_data) confirm_mock.delay.assert_not_called()
def test_update_source_url_de_empty(self, get_user_data, send_message, sfdc_mock, source_url_mock): """Subscription not including a source_url should be recorded in SFMC""" get_user_data.return_value = None # Does not exist yet models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en,fr', vendor_id='VENDOR1', requires_double_optin=True, ) models.Newsletter.objects.create( slug='slug2', title='title2', active=True, languages='en,fr', vendor_id='VENDOR2', requires_double_optin=True, ) data = { 'country': 'US', 'lang': 'en', 'format': 'H', 'newsletters': 'slug,slug2', 'first_name': 'The', 'last_name': 'Dude', 'email': self.email, } upsert_user(SUBSCRIBE, data) source_url_mock.delay.assert_has_calls([ call(self.email, None, 'VENDOR1'), call(self.email, None, 'VENDOR2'), ], any_order=True)
def test_new_user_subscribes_to_mofo_newsletter( self, get_user_data, sfdc_mock, ctms_mock, confirm_mock ): """Subscribing to a MoFo-relevant newsletter makes the new user mofo-relevant.""" get_user_data.return_value = None # Does not exist yet email_id = str(uuid4()) ctms_mock.add.return_value = {"email": {"email_id": email_id}} models.Newsletter.objects.create( slug="mozilla-foundation", title="The Mozilla Foundation News", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=False, is_mofo=True, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "mozilla-foundation", "email": self.email, } upsert_user(SUBSCRIBE, data) update_data = data.copy() update_data["newsletters"] = {"mozilla-foundation": True} update_data["mofo_relevant"] = True update_data["optin"] = True update_data["token"] = ANY ctms_mock.add.assert_called_with(update_data) update_data["email_id"] = email_id sfdc_mock.add.assert_called_with(update_data) confirm_mock.delay.assert_not_called()
def test_new_subscription_with_ctms_conflict( self, get_user_data, sfdc_mock, ctms_mock, confirm_mock ): """When CTMS returns an error for a new contact, the email_id is not sent to SF""" get_user_data.return_value = None # Does not exist yet ctms_mock.add.return_value = None # Conflict on create models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=True, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "slug", "email": self.email, } upsert_user(SUBSCRIBE, data) update_data = data.copy() update_data["newsletters"] = {"slug": True} update_data["token"] = ANY ctms_mock.add.assert_called_with(update_data) sfdc_mock.add.assert_called_with(update_data) confirm_mock.delay.assert_called_with(self.email, ANY, "en", "moz")
def test_send_fx_confirm(self, get_user_data, sfdc_mock, ctms_mock, confirm_mock): """Subscribing to a Fx newsletter should send a Fx confirm email""" get_user_data.return_value = None # Does not exist yet email_id = str(uuid4()) ctms_mock.add.return_value = {"email": {"email_id": email_id}} models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=True, firefox_confirm=True, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "slug", "email": self.email, } upsert_user(SUBSCRIBE, data) update_data = data.copy() update_data["newsletters"] = {"slug": True} update_data["token"] = ANY ctms_mock.add.assert_called_with(update_data) update_data["email_id"] = email_id sfdc_mock.add.assert_called_with(update_data) confirm_mock.delay.assert_called_with(self.email, ANY, "en", "fx")
def test_set_doesnt_update_newsletter(self, sfdc_mock, get_user_data): """ When setting the newsletters to ones the user is already subscribed to, we do not pass that newsletter to SF because we don't want that newsletter to send a new welcome. """ models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en-US,fr', vendor_id='TITLE_UNKNOWN', ) # We're going to ask to subscribe to this one again data = { 'lang': 'en', 'country': 'US', 'newsletters': 'slug', 'format': 'H', 'email': self.email, 'token': self.token, } sfdc_data = data.copy() sfdc_data['newsletters'] = {} # Mock user data - we want our user subbed to our newsletter to start get_user_data.return_value = self.get_user_data upsert_user(SET, data) # We should have looked up the user's data self.assertTrue(get_user_data.called) # We should not have mentioned this newsletter in our call to SF sfdc_mock.update.assert_called_with(self.get_user_data, sfdc_data)
def test_resubscribe_doesnt_update_newsletter(self, sfdc_mock, get_user_data): """ When subscribing to things the user is already subscribed to, we do not pass that newsletter to SF because we don't want that newsletter to be updated for no reason as that could cause another welcome to be sent. """ models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en-US,fr", vendor_id="TITLE_UNKNOWN", ) # We're going to ask to subscribe to this one again data = { "lang": "en", "country": "US", "newsletters": "slug", "format": "H", "email": self.email, } sfdc_data = data.copy() sfdc_data["newsletters"] = {} get_user_data.return_value = self.get_user_data upsert_user(SUBSCRIBE, data) # We should have looked up the user's data get_user_data.assert_called() # We should not have mentioned this newsletter in our call to ET sfdc_mock.update.assert_called_with(self.get_user_data, sfdc_data)
def test_no_send_confirm_user(self, get_user_data, sfdc_mock, confirm_mock): """ Subscribing to a newsletter should not send a confirm email if the user is already confirmed """ user_data = self.get_user_data.copy() user_data["optin"] = True user_data["newsletters"] = ["not-slug"] get_user_data.return_value = user_data models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=True, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "slug", "email": self.email, } upsert_user(SUBSCRIBE, data) sfdc_data = data.copy() sfdc_data["newsletters"] = {"slug": True} sfdc_mock.update.assert_called_with(user_data, sfdc_data) confirm_mock.delay.assert_not_called()
def test_update_first_last_names(self, get_user_data, send_message, sfdc_mock): """sending name fields should result in names being passed to SF""" get_user_data.return_value = None # Does not exist yet models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en,fr', vendor_id='VENDOR1', requires_double_optin=True, ) data = { 'country': 'US', 'lang': 'en', 'format': 'H', 'newsletters': 'slug', 'first_name': 'The', 'last_name': 'Dude', 'email': self.email, } upsert_user(SUBSCRIBE, data) sfdc_data = data.copy() sfdc_data['newsletters'] = {'slug': True} sfdc_data['token'] = ANY sfdc_mock.add.assert_called_with(sfdc_data)
def test_no_send_confirm_newsletter(self, get_user_data, sfdc_mock, confirm_mock): """ Subscribing to a newsletter should not send a confirm email if the newsletter does not require it """ get_user_data.return_value = None # Does not exist yet models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=False, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "slug", "email": self.email, } upsert_user(SUBSCRIBE, data) sfdc_data = data.copy() sfdc_data["newsletters"] = {"slug": True} sfdc_data["token"] = ANY sfdc_data["optin"] = True sfdc_mock.add.assert_called_with(sfdc_data) confirm_mock.delay.assert_not_called()
def test_update_user_with_email_id( self, get_user_mock, sfdc_mock, ctms_mock, confirm_mock ): """ If the SF data has an email_id, updates are sent to CTMS as well. """ models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en-US,fr", vendor_id="TITLE_UNKNOWN", ) get_user_mock.return_value = { "status": "ok", "format": "T", "email": "*****@*****.**", "token": "foo-token", "email_id": "ctms-email-id", "newsletters": ["other-one"], "optin": True, } data = { "lang": "en", "country": "US", "newsletters": "slug", "email": "*****@*****.**", } update_data = data.copy() update_data["newsletters"] = { "slug": True } # Only the set newsletter is mentioned upsert_user(SUBSCRIBE, data) sfdc_mock.update.assert_called_with(get_user_mock.return_value, update_data) ctms_mock.update.assert_called_with(get_user_mock.return_value, update_data)
def test_update_first_last_names(self, get_user_data, sfdc_mock, confirm_mock): """sending name fields should result in names being passed to SF""" get_user_data.return_value = None # Does not exist yet models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=True, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "slug", "first_name": "The", "last_name": "Dude", "email": self.email, } upsert_user(SUBSCRIBE, data) sfdc_data = data.copy() sfdc_data["newsletters"] = {"slug": True} sfdc_data["token"] = ANY sfdc_mock.add.assert_called_with(sfdc_data)
def test_set_doesnt_update_newsletter(self, get_user_data, sfdc_mock, confirm_mock): """ When setting the newsletters to ones the user is already subscribed to, we do not pass that newsletter to SF because we don't want that newsletter to send a new welcome. """ models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en-US,fr", vendor_id="TITLE_UNKNOWN", ) # We're going to ask to subscribe to this one again data = { "lang": "en", "country": "US", "newsletters": "slug", "format": "H", "email": self.email, "token": self.token, } sfdc_data = data.copy() sfdc_data["newsletters"] = {} # Mock user data - we want our user subbed to our newsletter to start get_user_data.return_value = self.get_user_data upsert_user(SET, data) # We should have looked up the user's data self.assertTrue(get_user_data.called) # We should not have mentioned this newsletter in our call to SF sfdc_mock.update.assert_called_with(self.get_user_data, sfdc_data)
def test_update_user_set_works_if_no_newsletters(self, get_user_data, sfdc_mock): """ A blank `newsletters` field when the update type is SET indicates that the person wishes to unsubscribe from all newsletters. This has caused exceptions because '' is not a valid newsletter name. """ models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en-US,fr", vendor_id="TITLE_UNKNOWN", ) data = { "lang": "en", "country": "US", "newsletters": "", "format": "H", "email": self.email, "token": self.token, } sfdc_data = data.copy() sfdc_data["newsletters"] = {"slug": False} get_user_data.return_value = self.get_user_data upsert_user(SET, data) # We should have looked up the user's data get_user_data.assert_called() # We'll specifically unsubscribe each newsletter the user is # subscribed to. sfdc_mock.update.assert_called_with(self.get_user_data, sfdc_data)
def test_send_moz_confirm(self, get_user_data, sfdc_mock, confirm_mock): """Subscribing to a Fx and moz newsletters should send a moz confirm email""" get_user_data.return_value = None # Does not exist yet models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=True, firefox_confirm=True, ) models.Newsletter.objects.create( slug="slug2", title="title", active=True, languages="en,fr", vendor_id="VENDOR2", requires_double_optin=True, firefox_confirm=False, ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "slug,slug2", "email": self.email, } upsert_user(SUBSCRIBE, data) sfdc_data = data.copy() sfdc_data["newsletters"] = {"slug": True, "slug2": True} sfdc_data["token"] = ANY sfdc_mock.add.assert_called_with(sfdc_data) confirm_mock.delay.assert_called_with(self.email, ANY, "en", "moz")
def test_update_source_url_de( self, get_user_data, send_message, sfdc_mock, source_url_mock, ): """Subscription including a source_url should be recorded in SFMC""" get_user_data.return_value = None # Does not exist yet models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en,fr", vendor_id="VENDOR1", requires_double_optin=True, ) models.Newsletter.objects.create( slug="slug2", title="title2", active=True, languages="en,fr", vendor_id="VENDOR2", requires_double_optin=True, ) source_url = ( "https://www.mozilla.org/en-US/newsletter/?utm_tracking_you=totally" ) data = { "country": "US", "lang": "en", "format": "H", "newsletters": "slug,slug2", "first_name": "The", "last_name": "Dude", "email": self.email, "source_url": source_url, } upsert_user(SUBSCRIBE, data) source_url_mock.delay.assert_has_calls( [ call(self.email, source_url, "VENDOR1"), call(self.email, source_url, "VENDOR2"), ], any_order=True, )
def test_update_user_without_format_doesnt_send_format( self, get_user_mock, sfdc_mock, confirm_mock, ): """ SF format not changed if update_user call doesn't specify. If update_user call doesn't specify a format (e.g. if bedrock doesn't get a changed value on a form submission), then Basket doesn't send any format to SF. It does use the user's choice of format to send them their welcome message. """ models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en-US,fr", vendor_id="TITLE_UNKNOWN", ) get_user_mock.return_value = { "status": "ok", "format": "T", "email": "*****@*****.**", "token": "foo-token", "newsletters": ["other-one"], "optin": True, } data = { "lang": "en", "country": "US", "newsletters": "slug", "email": "*****@*****.**", } sfdc_data = data.copy() # We should only mention slug, not slug2 sfdc_data["newsletters"] = {"slug": True} upsert_user(SUBSCRIBE, data) sfdc_mock.update.assert_called_with(get_user_mock.return_value, sfdc_data)
def test_update_user_without_format_doesnt_send_format( self, get_user_mock, sfdc_mock): """ SF format not changed if update_user call doesn't specify. If update_user call doesn't specify a format (e.g. if bedrock doesn't get a changed value on a form submission), then Basket doesn't send any format to SF. It does use the user's choice of format to send them their welcome message. """ models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en-US,fr', vendor_id='TITLE_UNKNOWN', ) get_user_mock.return_value = { 'status': 'ok', 'format': 'T', 'email': '*****@*****.**', 'token': 'foo-token', 'newsletters': ['other-one'], 'optin': True, } data = { 'lang': 'en', 'country': 'US', 'newsletters': 'slug', 'email': '*****@*****.**', } sfdc_data = data.copy() # We should only mention slug, not slug2 sfdc_data['newsletters'] = {'slug': True} upsert_user(SUBSCRIBE, data) sfdc_mock.update.assert_called_with(get_user_mock.return_value, sfdc_data)
def test_unsub_is_careful(self, get_user_data, sfdc_mock, ctms_mock, confirm_mock): """ When unsubscribing, we only unsubscribe things the user is currently subscribed to. """ models.Newsletter.objects.create( slug="slug", title="title", active=True, languages="en-US,fr", vendor_id="TITLE_UNKNOWN", ) models.Newsletter.objects.create( slug="slug2", title="title2", active=True, languages="en-US,fr", vendor_id="TITLE2_UNKNOWN", ) # We're going to ask to unsubscribe from both data = { "lang": "en", "country": "US", "newsletters": "slug,slug2", "format": "H", "token": self.token, } update_data = data.copy() # We should only mention slug, not slug2 update_data["newsletters"] = {"slug": False} get_user_data.return_value = self.get_user_data upsert_user(UNSUBSCRIBE, data) # We should have looked up the user's data self.assertTrue(get_user_data.called) sfdc_mock.update.assert_called_with(self.get_user_data, update_data) ctms_mock.update.assert_called_with(self.get_user_data, update_data)
def test_update_user_without_format_doesnt_send_format(self, get_user_mock, sfdc_mock): """ SF format not changed if update_user call doesn't specify. If update_user call doesn't specify a format (e.g. if bedrock doesn't get a changed value on a form submission), then Basket doesn't send any format to SF. It does use the user's choice of format to send them their welcome message. """ models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en-US,fr', vendor_id='TITLE_UNKNOWN', ) get_user_mock.return_value = { 'status': 'ok', 'format': 'T', 'email': '*****@*****.**', 'token': 'foo-token', 'newsletters': ['other-one'], 'optin': True, } data = { 'lang': 'en', 'country': 'US', 'newsletters': 'slug', 'email': '*****@*****.**', } sfdc_data = data.copy() # We should only mention slug, not slug2 sfdc_data['newsletters'] = {'slug': True} upsert_user(SUBSCRIBE, data) sfdc_mock.update.assert_called_with(get_user_mock.return_value, sfdc_data)
def test_unsub_is_careful(self, sfdc_mock, get_user_data): """ When unsubscribing, we only unsubscribe things the user is currently subscribed to. """ models.Newsletter.objects.create( slug='slug', title='title', active=True, languages='en-US,fr', vendor_id='TITLE_UNKNOWN', ) models.Newsletter.objects.create( slug='slug2', title='title2', active=True, languages='en-US,fr', vendor_id='TITLE2_UNKNOWN', ) # We're going to ask to unsubscribe from both data = { 'lang': 'en', 'country': 'US', 'newsletters': 'slug,slug2', 'format': 'H', 'token': self.token } sfdc_data = data.copy() # We should only mention slug, not slug2 sfdc_data['newsletters'] = {'slug': False} get_user_data.return_value = self.get_user_data upsert_user(UNSUBSCRIBE, data) # We should have looked up the user's data self.assertTrue(get_user_data.called) sfdc_mock.update.assert_called_with(self.get_user_data, sfdc_data)