def setUp(self): """ Create a newsletter, newsletter issue and some subscriptions to test with. """ # Create some newsletters self.newsletter1 = _make_newsletter("Test Newsletter 1") self.newsletter2 = _make_newsletter("Test Newsletter 2") # Create some approvers self.newsletter1.approvers = """\ [email protected] [email protected] [email protected] [email protected]""" self.newsletter1.save() self.template = "<html><head></head><body><h1>Test</h1></body></html>" self.plaintext = "****\nTest\n****" # Create an issue for each newsletter self.newsletter_issue1 = NewsletterIssue() self.newsletter_issue1.subject = 'Test Newsletter Issue 1' self.newsletter_issue1.template = self.template self.newsletter_issue1.newsletter = self.newsletter1 self.newsletter_issue1.save() self.newsletter_issue2 = NewsletterIssue() self.newsletter_issue2.subject = 'Test Newsletter Issue 2' self.newsletter_issue2.template = self.template self.newsletter_issue2.newsletter = self.newsletter2 self.newsletter_issue2.save() # Create some email addresses and subscribe them to a newsletter emails = [ '*****@*****.**', '*****@*****.**', '*****@*****.**' ] for email in emails: email_address = EmailAddress.objects.create_with_random_token( email=email) email_address.confirmed = True email_address.save() Subscription.objects.create(email_address=email_address, newsletter=self.newsletter1) # Create an unconfirmed email address self.unconfirmed_email = EmailAddress.objects.create_with_random_token( '*****@*****.**') Subscription.objects.create(email_address=self.unconfirmed_email, newsletter=self.newsletter1) # Create an extra email address and subscribe it to the second newsletter self.exclude_email = EmailAddress.objects.create_with_random_token( '*****@*****.**') self.exclude_email.confirmed = True self.exclude_email.save() Subscription.objects.create(email_address=self.exclude_email, newsletter=self.newsletter2)
def test_default_tracking_domain(self): """ Verify that on save a NewsletterIssue is assigned a default tracking domain from the parent Newsletter. """ tracking_domain = 'darkhorse.com' self.newsletter1.default_tracking_domain = tracking_domain self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_tracking_domain, tracking_domain) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.tracking_domain not in ( '', None, )) self.assertEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain) # Verify an existing tracking domain is not overwritten tracking_domain = 'tfaw.com' issue.tracking_domain = tracking_domain issue.save() self.assertEqual(tracking_domain, issue.tracking_domain) self.assertNotEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain)
def test_default_template(self): """ Verify that on save a NewsletterIssue is assigned a default template from the parent Newsletter. """ template_name = 'nova/test.html' self.newsletter1.default_template = template_name self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_template, template_name) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.template not in ( '', None, )) context = Context({}) expected_template = render_to_string(template_name, context) issue_template = Template(issue.template).render(context) self.assertEqual(expected_template, issue_template) # Verify an existing template is not overwritten new_template = 'hai' issue.template = new_template issue.save() self.assertEqual(new_template, NewsletterIssue.objects.get(pk=issue.pk).template)
def setUp(self): """ Create a newsletter, newsletter issue and some subscriptions to test with. """ # Create some newsletters self.newsletter1 = _make_newsletter("Test Newsletter 1") self.newsletter2 = _make_newsletter("Test Newsletter 2") # Create some approvers self.newsletter1.approvers = """\ [email protected] [email protected] [email protected] [email protected]""" self.newsletter1.save() self.template = "<html><head></head><body><h1>Test</h1></body></html>" self.plaintext = "****\nTest\n****" # Create an issue for each newsletter self.newsletter_issue1 = NewsletterIssue() self.newsletter_issue1.subject = 'Test Newsletter Issue 1' self.newsletter_issue1.template = self.template self.newsletter_issue1.newsletter = self.newsletter1 self.newsletter_issue1.save() self.newsletter_issue2 = NewsletterIssue() self.newsletter_issue2.subject = 'Test Newsletter Issue 2' self.newsletter_issue2.template = self.template self.newsletter_issue2.newsletter = self.newsletter2 self.newsletter_issue2.save() # Create some email addresses and subscribe them to a newsletter emails = ['*****@*****.**', '*****@*****.**', '*****@*****.**'] for email in emails: email_address = EmailAddress.objects.create_with_random_token(email=email) email_address.confirmed = True email_address.save() Subscription.objects.create(email_address=email_address, newsletter=self.newsletter1) # Create an unconfirmed email address self.unconfirmed_email = EmailAddress.objects.create_with_random_token('*****@*****.**') Subscription.objects.create(email_address=self.unconfirmed_email, newsletter=self.newsletter1) # Create an extra email address and subscribe it to the second newsletter self.exclude_email = EmailAddress.objects.create_with_random_token('*****@*****.**') self.exclude_email.confirmed = True self.exclude_email.save() Subscription.objects.create(email_address=self.exclude_email, newsletter=self.newsletter2)
def test_render(self): """ Verify that the NewsletterIssue template is correctly rendered. """ email = '*****@*****.**' template = """\ Issue ID: {{ issue.pk }} Date: {% now "Y-m-d" %} Email: {{ email }}""" issue = NewsletterIssue() issue.subject = 'Test' issue.template = template issue.newsletter = self.newsletter1 issue.save() expected_template = """\ Issue ID: {issue_id} Date: {date:%Y-%m-%d} Email: {email}""".format(issue_id=issue.pk, date=datetime.now(), email=email) rendered_template = issue.render(template=template, extra_context={'email': email}) self.assertEqual(rendered_template, expected_template)
def test_default_tracking_domain(self): """ Verify that on save a NewsletterIssue is assigned a default tracking domain from the parent Newsletter. """ tracking_domain = 'darkhorse.com' self.newsletter1.default_tracking_domain = tracking_domain self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_tracking_domain, tracking_domain) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.tracking_domain not in ('', None,)) self.assertEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain) # Verify an existing tracking domain is not overwritten tracking_domain = 'tfaw.com' issue.tracking_domain = tracking_domain issue.save() self.assertEqual(tracking_domain, issue.tracking_domain) self.assertNotEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain)
def test_default_template(self): """ Verify that on save a NewsletterIssue is assigned a default template from the parent Newsletter. """ template_name = 'nova/test.html' self.newsletter1.default_template = template_name self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_template, template_name) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.template not in ('', None,)) context = Context({}) expected_template = render_to_string(template_name, context) issue_template = Template(issue.template).render(context) self.assertEqual(expected_template, issue_template) # Verify an existing template is not overwritten new_template = 'hai' issue.template = new_template issue.save() self.assertEqual(new_template, NewsletterIssue.objects.get(pk=issue.pk).template)
def test_nova_context_processors(self): """ Verify that NewsletterIssues use NOVA_CONTEXT_PROCESSORS to render themselves when render() is called """ old_settings = getattr(settings, 'NOVA_CONTEXT_PROCESSORS', '!unset') settings.NOVA_CONTEXT_PROCESSORS = ['nova.tests.test_context_processor'] try: issue = NewsletterIssue(template="{{ test }}") issue.newsletter = self.newsletter1 issue.save() self.assertEqual('extra test context', issue.render(extra_context={ 'email': EmailAddress(email='*****@*****.**')})) finally: if old_settings == '!unset': del settings.NOVA_CONTEXT_PROCESSORS else: settings.NOVA_CONTEXT_PROCESSORS = old_settings
def test_nova_context_processors(self): """ Verify that NewsletterIssues use NOVA_CONTEXT_PROCESSORS to render themselves when render() is called """ old_settings = getattr(settings, 'NOVA_CONTEXT_PROCESSORS', '!unset') settings.NOVA_CONTEXT_PROCESSORS = [ 'nova.tests.test_context_processor' ] try: issue = NewsletterIssue(template="{{ test }}") issue.newsletter = self.newsletter1 issue.save() self.assertEqual( 'extra test context', issue.render(extra_context={ 'email': EmailAddress(email='*****@*****.**') })) finally: if old_settings == '!unset': del settings.NOVA_CONTEXT_PROCESSORS else: settings.NOVA_CONTEXT_PROCESSORS = old_settings
class TestNewsletterIssueModel(TestCase): """ Model API unit tests """ def setUp(self): """ Create a newsletter, newsletter issue and some subscriptions to test with. """ # Create some newsletters self.newsletter1 = _make_newsletter("Test Newsletter 1") self.newsletter2 = _make_newsletter("Test Newsletter 2") # Create some approvers self.newsletter1.approvers = """\ [email protected] [email protected] [email protected] [email protected]""" self.newsletter1.save() self.template = "<html><head></head><body><h1>Test</h1></body></html>" self.plaintext = "****\nTest\n****" # Create an issue for each newsletter self.newsletter_issue1 = NewsletterIssue() self.newsletter_issue1.subject = 'Test Newsletter Issue 1' self.newsletter_issue1.template = self.template self.newsletter_issue1.newsletter = self.newsletter1 self.newsletter_issue1.save() self.newsletter_issue2 = NewsletterIssue() self.newsletter_issue2.subject = 'Test Newsletter Issue 2' self.newsletter_issue2.template = self.template self.newsletter_issue2.newsletter = self.newsletter2 self.newsletter_issue2.save() # Create some email addresses and subscribe them to a newsletter emails = [ '*****@*****.**', '*****@*****.**', '*****@*****.**' ] for email in emails: email_address = EmailAddress.objects.create_with_random_token( email=email) email_address.confirmed = True email_address.save() Subscription.objects.create(email_address=email_address, newsletter=self.newsletter1) # Create an unconfirmed email address self.unconfirmed_email = EmailAddress.objects.create_with_random_token( '*****@*****.**') Subscription.objects.create(email_address=self.unconfirmed_email, newsletter=self.newsletter1) # Create an extra email address and subscribe it to the second newsletter self.exclude_email = EmailAddress.objects.create_with_random_token( '*****@*****.**') self.exclude_email.confirmed = True self.exclude_email.save() Subscription.objects.create(email_address=self.exclude_email, newsletter=self.newsletter2) def test_default_template(self): """ Verify that on save a NewsletterIssue is assigned a default template from the parent Newsletter. """ template_name = 'nova/test.html' self.newsletter1.default_template = template_name self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_template, template_name) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.template not in ( '', None, )) context = Context({}) expected_template = render_to_string(template_name, context) issue_template = Template(issue.template).render(context) self.assertEqual(expected_template, issue_template) # Verify an existing template is not overwritten new_template = 'hai' issue.template = new_template issue.save() self.assertEqual(new_template, NewsletterIssue.objects.get(pk=issue.pk).template) def test_default_tracking_domain(self): """ Verify that on save a NewsletterIssue is assigned a default tracking domain from the parent Newsletter. """ tracking_domain = 'darkhorse.com' self.newsletter1.default_tracking_domain = tracking_domain self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_tracking_domain, tracking_domain) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.tracking_domain not in ( '', None, )) self.assertEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain) # Verify an existing tracking domain is not overwritten tracking_domain = 'tfaw.com' issue.tracking_domain = tracking_domain issue.save() self.assertEqual(tracking_domain, issue.tracking_domain) self.assertNotEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain) def test_premailer(self): """ If the premailer script is enabled, test the premailer method which calls out to the external script. """ if getattr(settings, 'NOVA_USE_PREMAILER', False): template = """\ <html> <head> <style> .foo { color: red; } </style> </head> <body> <p class="foo">Some Text</p> </body> </html>""" expected_html = """\ <html> <head> </head> <body> <p class="foo" style="color: red;">Some Text</p> </body> </html>""" # Ensure the expected html has been returned from premailer premailed_html = self.newsletter_issue1.premailer(template) self.assertEqual(premailed_html, expected_html) # Ensure that the expected plaintext has been returned from premailer premailed_plaintext = self.newsletter_issue1.premailer( template, plaintext=True) self.assertTrue('Some Text' in premailed_plaintext) self.assertTrue('html' not in premailed_plaintext) else: print '\nNOVA_USE_PREMAILER is False or undefined. Skipping...' def test_premail(self): """ Ensure that the premail method calls the expected helper functions on the newsletter template. The helper functions themselves are to be tested separately. """ with patch( 'nova.models.canonicalize_links') as mock_canonicalize_links: self.newsletter_issue1.premail(track=False) self.assertTrue(mock_canonicalize_links.called) with patch('nova.models.track_document') as mock_track_document: self.newsletter_issue1.premail(canonicalize=False) self.assertTrue(mock_track_document.called) if getattr(settings, 'NOVA_USE_PREMAILER', False): with patch( 'nova.models.NewsletterIssue.premailer') as mock_premailer: html, plaintext = self.newsletter_issue1.premail() self.assertTrue(mock_premailer.called) self.assertTrue(html is not None) self.assertTrue(plaintext is not None) def test_render(self): """ Verify that the NewsletterIssue template is correctly rendered. """ email = '*****@*****.**' template = """\ Issue ID: {{ issue.pk }} Date: {% now "Y-m-d" %} Email: {{ email }}""" issue = NewsletterIssue() issue.subject = 'Test' issue.template = template issue.newsletter = self.newsletter1 issue.save() expected_template = """\ Issue ID: {issue_id} Date: {date:%Y-%m-%d} Email: {email}""".format(issue_id=issue.pk, date=datetime.now(), email=email) rendered_template = issue.render(template=template, extra_context={'email': email}) self.assertEqual(rendered_template, expected_template) def test_nova_context_processors(self): """ Verify that NewsletterIssues use NOVA_CONTEXT_PROCESSORS to render themselves when render() is called """ old_settings = getattr(settings, 'NOVA_CONTEXT_PROCESSORS', '!unset') settings.NOVA_CONTEXT_PROCESSORS = [ 'nova.tests.test_context_processor' ] try: issue = NewsletterIssue(template="{{ test }}") issue.newsletter = self.newsletter1 issue.save() self.assertEqual( 'extra test context', issue.render(extra_context={ 'email': EmailAddress(email='*****@*****.**') })) finally: if old_settings == '!unset': del settings.NOVA_CONTEXT_PROCESSORS else: settings.NOVA_CONTEXT_PROCESSORS = old_settings def test_send_test(self): """ Verify the send_test method only sends an issue to the email addresses listed in the approvers field on the Newsletter model and doesn't blow up if approvers is empty. """ approvers = self.newsletter1.approvers.split() self.assertEqual(len(approvers), 4) self.newsletter_issue1.send_test() self.assertEqual(len(mail.outbox), 4) expected_subject = "FOR APPROVERS: %s" % self.newsletter_issue1.subject for message in mail.outbox: self.assertTrue(message.to[0] in approvers) self.assertEqual(message.subject, expected_subject) self.assertEqual(message.alternatives[0][1], 'text/html') self.assertEqual(message.alternatives[0][0], self.newsletter_issue1.template) def test_send(self): """ Ensure that a newsletter issue is successfully sent to all *confirmed* subscribers of that newsletter. """ self.assertEqual(self.newsletter1.subscribers.count(), 3) self.newsletter_issue1.send() self.assertEqual(len(mail.outbox), 3) for message in mail.outbox: self.assertNotEqual(self.unconfirmed_email.email, message.to[0]) self.assertNotEqual(self.exclude_email.email, message.to[0]) self.assertEqual(message.subject, self.newsletter_issue1.subject) self.assertEqual(message.alternatives[0][1], 'text/html') self.assertEqual(message.alternatives[0][0], self.newsletter_issue1.template) def test_send_custom_list(self): """ Ensure that a newsletter issue is successfully sent to a custom list of recipients. """ emails = ['*****@*****.**', '*****@*****.**'] email_addresses = [] for email in emails: e = EmailAddress.objects.create(email=email) email_addresses.append(e) # Sanity Check self.assertEqual(len(email_addresses), 2) self.assertEqual(self.newsletter1.subscribers.count(), 3) self.newsletter_issue1.send(email_addresses=email_addresses) self.assertEqual(len(mail.outbox), 2) subscribers = [email.email for email in self.newsletter1.subscribers] for message in mail.outbox: self.assertTrue(message.to[0] not in subscribers) self.assertNotEqual(self.unconfirmed_email.email, message.to[0]) self.assertNotEqual(self.exclude_email.email, message.to[0]) self.assertEqual(message.subject, self.newsletter_issue1.subject) self.assertEqual(message.alternatives[0][1], 'text/html') self.assertEqual(message.alternatives[0][0], self.newsletter_issue1.template) def test_send_unsubscribe(self): """ Verify that a subscriber who once received issues, can successfully opt-out by unsubscribing. """ newsletter_issue = self.newsletter_issue1 email_address = newsletter_issue.newsletter.subscribers[0] # Unsubscribe email email_address.unsubscribe() # Verify unsubscribe self.assertTrue( email_address not in newsletter_issue.newsletter.subscribers) # Verify unsubscribed email not in sent issues newsletter_issue.send() for message in mail.outbox: self.assertNotEqual(email_address.email, message.to[0])
class TestNewsletterIssueModel(TestCase): """ Model API unit tests """ def setUp(self): """ Create a newsletter, newsletter issue and some subscriptions to test with. """ # Create some newsletters self.newsletter1 = _make_newsletter("Test Newsletter 1") self.newsletter2 = _make_newsletter("Test Newsletter 2") # Create some approvers self.newsletter1.approvers = """\ [email protected] [email protected] [email protected] [email protected]""" self.newsletter1.save() self.template = "<html><head></head><body><h1>Test</h1></body></html>" self.plaintext = "****\nTest\n****" # Create an issue for each newsletter self.newsletter_issue1 = NewsletterIssue() self.newsletter_issue1.subject = 'Test Newsletter Issue 1' self.newsletter_issue1.template = self.template self.newsletter_issue1.newsletter = self.newsletter1 self.newsletter_issue1.save() self.newsletter_issue2 = NewsletterIssue() self.newsletter_issue2.subject = 'Test Newsletter Issue 2' self.newsletter_issue2.template = self.template self.newsletter_issue2.newsletter = self.newsletter2 self.newsletter_issue2.save() # Create some email addresses and subscribe them to a newsletter emails = ['*****@*****.**', '*****@*****.**', '*****@*****.**'] for email in emails: email_address = EmailAddress.objects.create_with_random_token(email=email) email_address.confirmed = True email_address.save() Subscription.objects.create(email_address=email_address, newsletter=self.newsletter1) # Create an unconfirmed email address self.unconfirmed_email = EmailAddress.objects.create_with_random_token('*****@*****.**') Subscription.objects.create(email_address=self.unconfirmed_email, newsletter=self.newsletter1) # Create an extra email address and subscribe it to the second newsletter self.exclude_email = EmailAddress.objects.create_with_random_token('*****@*****.**') self.exclude_email.confirmed = True self.exclude_email.save() Subscription.objects.create(email_address=self.exclude_email, newsletter=self.newsletter2) def test_default_template(self): """ Verify that on save a NewsletterIssue is assigned a default template from the parent Newsletter. """ template_name = 'nova/test.html' self.newsletter1.default_template = template_name self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_template, template_name) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.template not in ('', None,)) context = Context({}) expected_template = render_to_string(template_name, context) issue_template = Template(issue.template).render(context) self.assertEqual(expected_template, issue_template) # Verify an existing template is not overwritten new_template = 'hai' issue.template = new_template issue.save() self.assertEqual(new_template, NewsletterIssue.objects.get(pk=issue.pk).template) def test_default_tracking_domain(self): """ Verify that on save a NewsletterIssue is assigned a default tracking domain from the parent Newsletter. """ tracking_domain = 'darkhorse.com' self.newsletter1.default_tracking_domain = tracking_domain self.newsletter1.save() # Sanity check self.assertEqual(self.newsletter1.default_tracking_domain, tracking_domain) issue = NewsletterIssue() issue.subject = 'Test' issue.newsletter = self.newsletter1 issue.save() self.assertTrue(issue.tracking_domain not in ('', None,)) self.assertEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain) # Verify an existing tracking domain is not overwritten tracking_domain = 'tfaw.com' issue.tracking_domain = tracking_domain issue.save() self.assertEqual(tracking_domain, issue.tracking_domain) self.assertNotEqual(issue.tracking_domain, issue.newsletter.default_tracking_domain) def test_premailer(self): """ If the premailer script is enabled, test the premailer method which calls out to the external script. """ if getattr(settings, 'NOVA_USE_PREMAILER', False): template = """\ <html> <head> <style> .foo { color: red; } </style> </head> <body> <p class="foo">Some Text</p> </body> </html>""" expected_html = """\ <html> <head> </head> <body> <p class="foo" style="color: red;">Some Text</p> </body> </html>""" # Ensure the expected html has been returned from premailer premailed_html = self.newsletter_issue1.premailer(template) self.assertEqual(premailed_html, expected_html) # Ensure that the expected plaintext has been returned from premailer premailed_plaintext = self.newsletter_issue1.premailer(template, plaintext=True) self.assertTrue('Some Text' in premailed_plaintext) self.assertTrue('html' not in premailed_plaintext) else: print '\nNOVA_USE_PREMAILER is False or undefined. Skipping...' def test_premail(self): """ Ensure that the premail method calls the expected helper functions on the newsletter template. The helper functions themselves are to be tested separately. """ with patch('nova.models.canonicalize_links') as mock_canonicalize_links: self.newsletter_issue1.premail(track=False) self.assertTrue(mock_canonicalize_links.called) with patch('nova.models.track_document') as mock_track_document: self.newsletter_issue1.premail(canonicalize=False) self.assertTrue(mock_track_document.called) if getattr(settings, 'NOVA_USE_PREMAILER', False): with patch('nova.models.NewsletterIssue.premailer') as mock_premailer: html, plaintext = self.newsletter_issue1.premail() self.assertTrue(mock_premailer.called) self.assertTrue(html is not None) self.assertTrue(plaintext is not None) def test_render(self): """ Verify that the NewsletterIssue template is correctly rendered. """ email = '*****@*****.**' template = """\ Issue ID: {{ issue.pk }} Date: {% now "Y-m-d" %} Email: {{ email }}""" issue = NewsletterIssue() issue.subject = 'Test' issue.template = template issue.newsletter = self.newsletter1 issue.save() expected_template = """\ Issue ID: {issue_id} Date: {date:%Y-%m-%d} Email: {email}""".format(issue_id=issue.pk, date=datetime.now(), email=email) rendered_template = issue.render(template=template, extra_context={'email': email}) self.assertEqual(rendered_template, expected_template) def test_nova_context_processors(self): """ Verify that NewsletterIssues use NOVA_CONTEXT_PROCESSORS to render themselves when render() is called """ old_settings = getattr(settings, 'NOVA_CONTEXT_PROCESSORS', '!unset') settings.NOVA_CONTEXT_PROCESSORS = ['nova.tests.test_context_processor'] try: issue = NewsletterIssue(template="{{ test }}") issue.newsletter = self.newsletter1 issue.save() self.assertEqual('extra test context', issue.render(extra_context={ 'email': EmailAddress(email='*****@*****.**')})) finally: if old_settings == '!unset': del settings.NOVA_CONTEXT_PROCESSORS else: settings.NOVA_CONTEXT_PROCESSORS = old_settings def test_send_test(self): """ Verify the send_test method only sends an issue to the email addresses listed in the approvers field on the Newsletter model and doesn't blow up if approvers is empty. """ approvers = self.newsletter1.approvers.split() self.assertEqual(len(approvers), 4) self.newsletter_issue1.send_test() self.assertEqual(len(mail.outbox), 4) expected_subject = "FOR APPROVERS: %s" % self.newsletter_issue1.subject for message in mail.outbox: self.assertTrue(message.to[0] in approvers) self.assertEqual(message.subject, expected_subject) self.assertEqual(message.alternatives[0][1], 'text/html') self.assertEqual(message.alternatives[0][0], self.newsletter_issue1.template) def test_send(self): """ Ensure that a newsletter issue is successfully sent to all *confirmed* subscribers of that newsletter. """ self.assertEqual(self.newsletter1.subscribers.count(), 3) self.newsletter_issue1.send() self.assertEqual(len(mail.outbox), 3) for message in mail.outbox: self.assertNotEqual(self.unconfirmed_email.email, message.to[0]) self.assertNotEqual(self.exclude_email.email, message.to[0]) self.assertEqual(message.subject, self.newsletter_issue1.subject) self.assertEqual(message.alternatives[0][1], 'text/html') self.assertEqual(message.alternatives[0][0], self.newsletter_issue1.template) def test_send_custom_list(self): """ Ensure that a newsletter issue is successfully sent to a custom list of recipients. """ emails = ['*****@*****.**', '*****@*****.**'] email_addresses = [] for email in emails: e = EmailAddress.objects.create(email=email) email_addresses.append(e) # Sanity Check self.assertEqual(len(email_addresses), 2) self.assertEqual(self.newsletter1.subscribers.count(), 3) self.newsletter_issue1.send(email_addresses=email_addresses) self.assertEqual(len(mail.outbox), 2) subscribers = [email.email for email in self.newsletter1.subscribers] for message in mail.outbox: self.assertTrue(message.to[0] not in subscribers) self.assertNotEqual(self.unconfirmed_email.email, message.to[0]) self.assertNotEqual(self.exclude_email.email, message.to[0]) self.assertEqual(message.subject, self.newsletter_issue1.subject) self.assertEqual(message.alternatives[0][1], 'text/html') self.assertEqual(message.alternatives[0][0], self.newsletter_issue1.template) def test_send_unsubscribe(self): """ Verify that a subscriber who once received issues, can successfully opt-out by unsubscribing. """ newsletter_issue = self.newsletter_issue1 email_address = newsletter_issue.newsletter.subscribers[0] # Unsubscribe email email_address.unsubscribe() # Verify unsubscribe self.assertTrue(email_address not in newsletter_issue.newsletter.subscribers) # Verify unsubscribed email not in sent issues newsletter_issue.send() for message in mail.outbox: self.assertNotEqual(email_address.email, message.to[0])