class LocaleStewards(models.Model): """ List of steward emails for a specific interest-locale combination. """ interest = models.ForeignKey(Interest, on_delete=models.CASCADE, related_name='stewards') locale = LocaleField() emails = CommaSeparatedEmailField( blank=False, help_text='Comma-separated list of the stewards\' email addresses.', ) @property def emails_list(self): return parse_emails(self.emails) class Meta: unique_together = ('interest', 'locale') verbose_name = 'Locale Steward' verbose_name_plural = 'Locale Stewards' def __unicode__(self): return 'Stewards for {lang_code} ({lang_name})'.format( lang_code=self.locale, lang_name=product_details.languages[self.locale]['English'], )
class LocaleStewards(models.Model): """ List of steward emails for a specific interest-locale combination. """ interest = models.ForeignKey( Interest, on_delete=models.CASCADE, related_name="stewards", ) locale = LocaleField() emails = CommaSeparatedEmailField( blank=False, help_text="Comma-separated list of the stewards' email addresses.", ) @property def emails_list(self): return parse_emails(self.emails) class Meta: unique_together = ("interest", "locale") verbose_name = "Locale Steward" verbose_name_plural = "Locale Stewards" def __str__(self): return "Stewards for {lang_code} ({lang_name})".format( lang_code=self.locale, lang_name=product_details.languages[self.locale]["English"], )
class Interest(models.Model): title = models.CharField( max_length=128, help_text='Public name of interest in English', ) interest_id = models.SlugField( unique=True, db_index=True, help_text='The ID for the interest that will be used by clients', ) # Note: use .welcome_id property to get this field or the default _welcome_id = models.CharField( max_length=64, help_text='The ID of the welcome message sent for this interest. ' 'This is the HTML version of the message; append _T to this ' 'ID to get the ID of the text-only version. If blank, ' 'welcome message ID will be assumed to be the same as ' 'the interest_id', blank=True, verbose_name='Welcome ID', ) default_steward_emails = CommaSeparatedEmailField( blank=True, help_text= 'Comma-separated list of the default / en-US stewards\' email addresses.', verbose_name='Default / en-US Steward Emails', ) @property def welcome_id(self): return self._welcome_id or self.interest_id def notify_stewards(self, name, email, lang, message): """ Send an email to the stewards about a new interested subscriber. """ email_body = render_to_string( 'news/get_involved/steward_email.txt', { 'contributor_name': name, 'contributor_email': email, 'interest': self, 'lang': lang, 'message': message, }) # Find the right stewards for the given language. try: stewards = self.localestewards_set.get(locale=lang) emails = stewards.emails except LocaleStewards.DoesNotExist: emails = self.default_steward_emails emails = emails.split(',') send_mail('Inquiry about {0}'.format(self.title), email_body, '*****@*****.**', emails) def __unicode__(self): return self.title
class CommaSeparatedEmailFieldTests(TestCase): def setUp(self): self.field = CommaSeparatedEmailField(blank=True) def test_validate(self): """ Validate should run the email validator on all non-empty emails in the list. """ with patch('basket.news.fields.validate_email') as validate_email: self.field.validate(' [email protected] ,[email protected] ', None) validate_email.assert_has_calls([ call('*****@*****.**'), call('*****@*****.**'), ]) validate_email.reset_mock() self.field.validate('*****@*****.**', None) validate_email.assert_has_calls([ call('*****@*****.**'), ]) validate_email.reset_mock() self.field.validate('', None) self.assertFalse(validate_email.called) def test_pre_save(self): """pre_save should remove unnecessary whitespace and commas.""" instance = Mock() self.field.attname = 'blah' # Basic instance.blah = '[email protected],[email protected]' self.assertEqual(self.field.pre_save(instance, False), '[email protected],[email protected]') # Excess whitespace instance.blah = ' [email protected] ,[email protected] ' self.assertEqual(self.field.pre_save(instance, False), '[email protected],[email protected]') # Extra commas instance.blah = '[email protected] ,,,, [email protected] ' self.assertEqual(self.field.pre_save(instance, False), '[email protected],[email protected]')
class Interest(models.Model): title = models.CharField( max_length=128, help_text="Public name of interest in English", ) interest_id = models.SlugField( unique=True, db_index=True, help_text="The ID for the interest that will be used by clients", ) # Note: use .welcome_id property to get this field or the default _welcome_id = models.CharField( max_length=64, help_text="The ID of the welcome message sent for this interest. " "This is the HTML version of the message; append _T to this " "ID to get the ID of the text-only version. If blank, " "welcome message ID will be assumed to be the same as " "the interest_id", blank=True, verbose_name="Welcome ID", ) default_steward_emails = CommaSeparatedEmailField( blank=True, help_text="Comma-separated list of the default / en-US stewards' email addresses.", verbose_name="Default / en-US Steward Emails", ) @property def default_steward_emails_list(self): return parse_emails(self.default_steward_emails) @property def welcome_id(self): return self._welcome_id or self.interest_id def notify_stewards(self, name, email, lang, message): """ Send an email to the stewards about a new interested subscriber. """ email_body = render_to_string( "news/get_involved/steward_email.txt", { "contributor_name": name, "contributor_email": email, "interest": self, "lang": lang, "message": message, }, ) # Find the right stewards for the given language. try: stewards = self.stewards.get(locale=lang) emails = stewards.emails_list except LocaleStewards.DoesNotExist: emails = self.default_steward_emails_list send_mail( "Inquiry about {0}".format(self.title), email_body, "*****@*****.**", emails, ) def __str__(self): return self.title
def setUp(self): self.field = CommaSeparatedEmailField(blank=True)
class CommaSeparatedEmailFieldTests(TestCase): def setUp(self): self.field = CommaSeparatedEmailField(blank=True) def test_validate(self): """ Validate should run the email validator on all non-empty emails in the list. """ with patch("basket.news.fields.validate_email") as validate_email: instance = Mock() self.field.attname = "blah" instance.blah = " [email protected] ,[email protected] " self.field.pre_save(instance, False) validate_email.assert_has_calls( [call("*****@*****.**"), call("*****@*****.**")], ) validate_email.reset_mock() instance.blah = "*****@*****.**" self.field.pre_save(instance, False) validate_email.assert_has_calls([call("*****@*****.**")]) validate_email.reset_mock() instance.blah = "" self.field.pre_save(instance, False) self.assertFalse(validate_email.called) def test_invalid_email(self): instance = Mock() self.field.attname = "blah" instance.blah = "the.dude" with self.assertRaises(ValidationError): self.field.pre_save(instance, False) def test_pre_save(self): """pre_save should remove unnecessary whitespace and commas.""" instance = Mock() self.field.attname = "blah" # Basic instance.blah = "[email protected],[email protected]" self.assertEqual( self.field.pre_save(instance, False), "[email protected],[email protected]", ) # Excess whitespace instance.blah = " [email protected] ,[email protected] " self.assertEqual( self.field.pre_save(instance, False), "[email protected],[email protected]", ) # Extra commas instance.blah = "[email protected] ,,,, [email protected] " self.assertEqual( self.field.pre_save(instance, False), "[email protected],[email protected]", )