diff --git a/lms/djangoapps/email_marketing/migrations/0007_auto_20170809_0653.py b/lms/djangoapps/email_marketing/migrations/0007_auto_20170809_0653.py new file mode 100644 index 0000000000..e99d25e163 --- /dev/null +++ b/lms/djangoapps/email_marketing/migrations/0007_auto_20170809_0653.py @@ -0,0 +1,29 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('email_marketing', '0006_auto_20170711_0615'), + ] + + operations = [ + migrations.AddField( + model_name='emailmarketingconfiguration', + name='sailthru_welcome_template', + field=models.CharField(help_text='Sailthru template to use on welcome send.', max_length=20, blank=True), + ), + migrations.AlterField( + model_name='emailmarketingconfiguration', + name='sailthru_activation_template', + field=models.CharField(help_text='DEPRECATED: use sailthru_welcome_template instead.', max_length=20, blank=True), + ), + migrations.AlterField( + model_name='emailmarketingconfiguration', + name='welcome_email_send_delay', + field=models.IntegerField(default=600, help_text='Number of seconds to delay the sending of User Welcome email after user has been created'), + ), + ] diff --git a/lms/djangoapps/email_marketing/migrations/0008_auto_20170809_0539.py b/lms/djangoapps/email_marketing/migrations/0008_auto_20170809_0539.py new file mode 100644 index 0000000000..c4c580b867 --- /dev/null +++ b/lms/djangoapps/email_marketing/migrations/0008_auto_20170809_0539.py @@ -0,0 +1,27 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models + + +def migrate_data_forwards(apps, schema_editor): + EmailMarketingConfiguration = apps.get_model('email_marketing', 'EmailMarketingConfiguration') + EmailMarketingConfiguration.objects.all().update( + sailthru_welcome_template=models.F('sailthru_activation_template') + ) + + +def migrate_data_backwards(apps, schema_editor): + # Just copying old field's value to new one in forward migration, so nothing needed here. + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('email_marketing', '0007_auto_20170809_0653'), + ] + + operations = [ + migrations.RunPython(migrate_data_forwards, migrate_data_backwards) + ] diff --git a/lms/djangoapps/email_marketing/models.py b/lms/djangoapps/email_marketing/models.py index 8aa182047d..224fcfebbd 100644 --- a/lms/djangoapps/email_marketing/models.py +++ b/lms/djangoapps/email_marketing/models.py @@ -51,7 +51,15 @@ class EmailMarketingConfiguration(ConfigurationModel): max_length=20, blank=True, help_text=_( - "Sailthru template to use on activation send. " + "DEPRECATED: use sailthru_welcome_template instead." + ) + ) + + sailthru_welcome_template = models.fields.CharField( + max_length=20, + blank=True, + help_text=_( + "Sailthru template to use on welcome send." ) ) @@ -132,7 +140,7 @@ class EmailMarketingConfiguration(ConfigurationModel): welcome_email_send_delay = models.fields.IntegerField( default=600, help_text=_( - "Number of seconds to delay the sending of User Welcome email after user has been activated" + "Number of seconds to delay the sending of User Welcome email after user has been created" ) ) @@ -145,5 +153,5 @@ class EmailMarketingConfiguration(ConfigurationModel): ) def __unicode__(self): - return u"Email marketing configuration: New user list %s, Activation template: %s" % \ - (self.sailthru_new_user_list, self.sailthru_activation_template) + return u"Email marketing configuration: New user list %s, Welcome template: %s" % \ + (self.sailthru_new_user_list, self.sailthru_welcome_template) diff --git a/lms/djangoapps/email_marketing/signals.py b/lms/djangoapps/email_marketing/signals.py index 80a29f0bfe..745de42748 100644 --- a/lms/djangoapps/email_marketing/signals.py +++ b/lms/djangoapps/email_marketing/signals.py @@ -149,9 +149,9 @@ def email_marketing_user_field_changed(sender, user=None, table=None, setting=No if not email_config.enabled: return - # perform update asynchronously, flag if activation + # perform update asynchronously update_user.delay(_create_sailthru_user_vars(user, user.profile), user.email, site=_get_current_site(), - new_user=False, activation=(setting == 'is_active') and new_value is True) + new_user=False) elif setting == 'email': # email update is special case diff --git a/lms/djangoapps/email_marketing/tasks.py b/lms/djangoapps/email_marketing/tasks.py index a6e952e515..a0d4b254b4 100644 --- a/lms/djangoapps/email_marketing/tasks.py +++ b/lms/djangoapps/email_marketing/tasks.py @@ -59,14 +59,13 @@ def get_email_cookies_via_sailthru(self, user_email, post_parms): # pylint: disable=not-callable @task(bind=True, default_retry_delay=3600, max_retries=24) -def update_user(self, sailthru_vars, email, site=None, new_user=False, activation=False): +def update_user(self, sailthru_vars, email, site=None, new_user=False): """ Adds/updates Sailthru profile information for a user. Args: sailthru_vars(dict): User profile information to pass as 'vars' to Sailthru email(str): User email address new_user(boolean): True if new registration - activation(boolean): True if activation request Returns: None """ @@ -95,15 +94,15 @@ def update_user(self, sailthru_vars, email, site=None, new_user=False, activatio max_retries=email_config.sailthru_max_retries) return - # if activating user, send welcome email - if activation and email_config.sailthru_activation_template: + # if new user, send welcome email + if new_user and email_config.sailthru_welcome_template: scheduled_datetime = datetime.utcnow() + timedelta(seconds=email_config.welcome_email_send_delay) try: sailthru_response = sailthru_client.api_post( "send", { "email": email, - "template": email_config.sailthru_activation_template, + "template": email_config.sailthru_welcome_template, "schedule_time": scheduled_datetime.strftime('%Y-%m-%dT%H:%M:%SZ') } ) diff --git a/lms/djangoapps/email_marketing/tests/test_signals.py b/lms/djangoapps/email_marketing/tests/test_signals.py index 2bf28791a6..62b44ccabc 100644 --- a/lms/djangoapps/email_marketing/tests/test_signals.py +++ b/lms/djangoapps/email_marketing/tests/test_signals.py @@ -41,7 +41,7 @@ TEST_EMAIL = "test@edx.org" def update_email_marketing_config(enabled=True, key='badkey', secret='badsecret', new_user_list='new list', - template='Activation', enroll_cost=100, lms_url_override='http://testserver'): + template='Welcome', enroll_cost=100, lms_url_override='http://testserver'): """ Enable / Disable Sailthru integration """ @@ -50,7 +50,7 @@ def update_email_marketing_config(enabled=True, key='badkey', secret='badsecret' sailthru_key=key, sailthru_secret=secret, sailthru_new_user_list=new_user_list, - sailthru_activation_template=template, + sailthru_welcome_template=template, sailthru_enroll_template='enroll_template', sailthru_lms_url_override=lms_url_override, sailthru_get_tags_from_sailthru=False, @@ -175,7 +175,7 @@ class EmailMarketingTests(TestCase): @patch('email_marketing.tasks.SailthruClient.api_get') def test_add_user(self, mock_sailthru_get, mock_sailthru_post, mock_log_error): """ - test async method in tasks that actually updates Sailthru + test async method in tasks that actually updates Sailthru and send Welcome template. """ site_dict = {'id': self.site.id, 'domain': self.site.domain, 'name': self.site.name} mock_sailthru_post.return_value = SailthruResponse(JsonResponse({'ok': True})) @@ -183,15 +183,13 @@ class EmailMarketingTests(TestCase): update_user.delay( {'gender': 'm', 'username': 'test', 'activated': 1}, TEST_EMAIL, site_dict, new_user=True ) + expected_schedule = datetime.datetime.utcnow() + datetime.timedelta(seconds=600) self.assertFalse(mock_log_error.called) - self.assertEquals(mock_sailthru_post.call_args[0][0], "user") + self.assertEquals(mock_sailthru_post.call_args[0][0], "send") userparms = mock_sailthru_post.call_args[0][1] - self.assertEquals(userparms['key'], "email") - self.assertEquals(userparms['id'], TEST_EMAIL) - self.assertEquals(userparms['vars']['gender'], "m") - self.assertEquals(userparms['vars']['username'], "test") - self.assertEquals(userparms['vars']['activated'], 1) - self.assertEquals(userparms['lists']['new list'], 1) + self.assertEquals(userparms['email'], TEST_EMAIL) + self.assertEquals(userparms['template'], "Welcome") + self.assertEquals(userparms['schedule_time'], expected_schedule.strftime('%Y-%m-%dT%H:%M:%SZ')) @patch('email_marketing.tasks.SailthruClient.api_post') @patch('email_marketing.tasks.SailthruClient.api_get') @@ -199,6 +197,8 @@ class EmailMarketingTests(TestCase): """ test non existing domain name updates Sailthru user lists with default list """ + # Set template to empty string to disable 2nd post call to Sailthru + update_email_marketing_config(template='') existing_site = Site.objects.create(domain='testing.com', name='testing.com') site_dict = {'id': existing_site.id, 'domain': existing_site.domain, 'name': existing_site.name} mock_sailthru_post.return_value = SailthruResponse(JsonResponse({'ok': True})) @@ -216,18 +216,16 @@ class EmailMarketingTests(TestCase): @patch('email_marketing.tasks.SailthruClient.api_get') def test_user_activation(self, mock_sailthru_get, mock_sailthru_post): """ - test send of activation template + Test that welcome template not sent if not new user. """ mock_sailthru_post.return_value = SailthruResponse(JsonResponse({'ok': True})) mock_sailthru_get.return_value = SailthruResponse(JsonResponse({'lists': [{'name': 'new list'}], 'ok': True})) - expected_schedule = datetime.datetime.utcnow() + datetime.timedelta(seconds=600) - update_user.delay({}, self.user.email, new_user=True, activation=True) + update_user.delay({}, self.user.email, new_user=False) # look for call args for 2nd call - self.assertEquals(mock_sailthru_post.call_args[0][0], "send") + self.assertEquals(mock_sailthru_post.call_args[0][0], "user") userparms = mock_sailthru_post.call_args[0][1] - self.assertEquals(userparms['email'], TEST_EMAIL) - self.assertEquals(userparms['template'], "Activation") - self.assertEquals(userparms['schedule_time'], expected_schedule.strftime('%Y-%m-%dT%H:%M:%SZ')) + self.assertIsNone(userparms.get('email')) + self.assertIsNone(userparms.get('template')) @patch('email_marketing.tasks.log.error') @patch('email_marketing.tasks.SailthruClient.api_post') @@ -248,14 +246,14 @@ class EmailMarketingTests(TestCase): # force Sailthru API exception on 2nd call mock_log_error.reset_mock() mock_sailthru.side_effect = [SailthruResponse(JsonResponse({'ok': True})), SailthruClientError] - update_user.delay({}, self.user.email, activation=True) + update_user.delay({}, self.user.email, new_user=True) self.assertTrue(mock_log_error.called) # force Sailthru API error return on 2nd call mock_log_error.reset_mock() mock_sailthru.side_effect = [SailthruResponse(JsonResponse({'ok': True})), SailthruResponse(JsonResponse({'error': 100, 'errormsg': 'Got an error'}))] - update_user.delay({}, self.user.email, activation=True) + update_user.delay({}, self.user.email, new_user=True) self.assertTrue(mock_log_error.called) @patch('email_marketing.tasks.update_user.retry')