X-Git-Url: https://git.ozlabs.org/?a=blobdiff_plain;f=patchwork%2Ftests%2Ftest_mail_settings.py;fp=patchwork%2Ftests%2Ftest_mail_settings.py;h=a193c9711375920d08a27fc131e6816f31b2a0ce;hb=ad2762cf775a8dde508de47164d6429f3fd724f1;hp=0000000000000000000000000000000000000000;hpb=f09e982f58384946111d4157fd2b7c2b31b78612;p=patchwork diff --git a/patchwork/tests/test_mail_settings.py b/patchwork/tests/test_mail_settings.py new file mode 100644 index 0000000..a193c97 --- /dev/null +++ b/patchwork/tests/test_mail_settings.py @@ -0,0 +1,299 @@ +# Patchwork - automated patch tracking system +# Copyright (C) 2010 Jeremy Kerr +# +# This file is part of the Patchwork package. +# +# Patchwork is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# Patchwork is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Patchwork; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +import unittest +import re +from django.test import TestCase +from django.test.client import Client +from django.core import mail +from django.core.urlresolvers import reverse +from django.contrib.auth.models import User +from patchwork.models import EmailOptout, EmailConfirmation, Person +from patchwork.tests.utils import create_user, error_strings + +class MailSettingsTest(TestCase): + view = 'patchwork.views.mail.settings' + url = reverse(view) + + def testMailSettingsGET(self): + response = self.client.get(self.url) + self.assertEquals(response.status_code, 200) + self.assertTrue(response.context['form']) + + def testMailSettingsPOST(self): + email = u'foo@example.com' + response = self.client.post(self.url, {'email': email}) + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'patchwork/mail-settings.html') + self.assertEquals(response.context['email'], email) + + def testMailSettingsPOSTEmpty(self): + response = self.client.post(self.url, {'email': ''}) + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'patchwork/mail-form.html') + self.assertFormError(response, 'form', 'email', + 'This field is required.') + + def testMailSettingsPOSTInvalid(self): + response = self.client.post(self.url, {'email': 'foo'}) + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'patchwork/mail-form.html') + self.assertFormError(response, 'form', 'email', error_strings['email']) + + def testMailSettingsPOSTOptedIn(self): + email = u'foo@example.com' + response = self.client.post(self.url, {'email': email}) + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'patchwork/mail-settings.html') + self.assertEquals(response.context['is_optout'], False) + self.assertTrue('may' in response.content) + optout_url = reverse('patchwork.views.mail.optout') + self.assertTrue(('action="%s"' % optout_url) in response.content) + + def testMailSettingsPOSTOptedOut(self): + email = u'foo@example.com' + EmailOptout(email = email).save() + response = self.client.post(self.url, {'email': email}) + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'patchwork/mail-settings.html') + self.assertEquals(response.context['is_optout'], True) + self.assertTrue('may not' in response.content) + optin_url = reverse('patchwork.views.mail.optin') + self.assertTrue(('action="%s"' % optin_url) in response.content) + +class OptoutRequestTest(TestCase): + view = 'patchwork.views.mail.optout' + url = reverse(view) + + def testOptOutRequestGET(self): + response = self.client.get(self.url) + self.assertRedirects(response, reverse('patchwork.views.mail.settings')) + + def testOptoutRequestValidPOST(self): + email = u'foo@example.com' + response = self.client.post(self.url, {'email': email}) + + # check for a confirmation object + self.assertEquals(EmailConfirmation.objects.count(), 1) + conf = EmailConfirmation.objects.get(email = email) + + # check confirmation page + self.assertEquals(response.status_code, 200) + self.assertEquals(response.context['confirmation'], conf) + self.assertTrue(email in response.content) + + # check email + url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key}) + self.assertEquals(len(mail.outbox), 1) + msg = mail.outbox[0] + self.assertEquals(msg.to, [email]) + self.assertEquals(msg.subject, 'Patchwork opt-out confirmation') + self.assertTrue(url in msg.body) + + def testOptoutRequestInvalidPOSTEmpty(self): + response = self.client.post(self.url, {'email': ''}) + self.assertEquals(response.status_code, 200) + self.assertFormError(response, 'form', 'email', + 'This field is required.') + self.assertTrue(response.context['error']) + self.assertTrue('email_sent' not in response.context) + self.assertEquals(len(mail.outbox), 0) + + def testOptoutRequestInvalidPOSTNonEmail(self): + response = self.client.post(self.url, {'email': 'foo'}) + self.assertEquals(response.status_code, 200) + self.assertFormError(response, 'form', 'email', error_strings['email']) + self.assertTrue(response.context['error']) + self.assertTrue('email_sent' not in response.context) + self.assertEquals(len(mail.outbox), 0) + +class OptoutTest(TestCase): + view = 'patchwork.views.mail.optout' + url = reverse(view) + + def setUp(self): + self.email = u'foo@example.com' + self.conf = EmailConfirmation(type = 'optout', email = self.email) + self.conf.save() + + def testOptoutValidHash(self): + url = reverse('patchwork.views.confirm', + kwargs = {'key': self.conf.key}) + response = self.client.get(url) + + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'patchwork/optout.html') + self.assertTrue(self.email in response.content) + + # check that we've got an optout in the list + self.assertEquals(EmailOptout.objects.count(), 1) + self.assertEquals(EmailOptout.objects.all()[0].email, self.email) + + # check that the confirmation is now inactive + self.assertFalse(EmailConfirmation.objects.get( + pk = self.conf.pk).active) + + +class OptoutPreexistingTest(OptoutTest): + """Test that a duplicated opt-out behaves the same as the initial one""" + def setUp(self): + super(OptoutPreexistingTest, self).setUp() + EmailOptout(email = self.email).save() + +class OptinRequestTest(TestCase): + view = 'patchwork.views.mail.optin' + url = reverse(view) + + def setUp(self): + self.email = u'foo@example.com' + EmailOptout(email = self.email).save() + + def testOptInRequestGET(self): + response = self.client.get(self.url) + self.assertRedirects(response, reverse('patchwork.views.mail.settings')) + + def testOptInRequestValidPOST(self): + response = self.client.post(self.url, {'email': self.email}) + + # check for a confirmation object + self.assertEquals(EmailConfirmation.objects.count(), 1) + conf = EmailConfirmation.objects.get(email = self.email) + + # check confirmation page + self.assertEquals(response.status_code, 200) + self.assertEquals(response.context['confirmation'], conf) + self.assertTrue(self.email in response.content) + + # check email + url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key}) + self.assertEquals(len(mail.outbox), 1) + msg = mail.outbox[0] + self.assertEquals(msg.to, [self.email]) + self.assertEquals(msg.subject, 'Patchwork opt-in confirmation') + self.assertTrue(url in msg.body) + + def testOptoutRequestInvalidPOSTEmpty(self): + response = self.client.post(self.url, {'email': ''}) + self.assertEquals(response.status_code, 200) + self.assertFormError(response, 'form', 'email', + 'This field is required.') + self.assertTrue(response.context['error']) + self.assertTrue('email_sent' not in response.context) + self.assertEquals(len(mail.outbox), 0) + + def testOptoutRequestInvalidPOSTNonEmail(self): + response = self.client.post(self.url, {'email': 'foo'}) + self.assertEquals(response.status_code, 200) + self.assertFormError(response, 'form', 'email', error_strings['email']) + self.assertTrue(response.context['error']) + self.assertTrue('email_sent' not in response.context) + self.assertEquals(len(mail.outbox), 0) + +class OptinTest(TestCase): + + def setUp(self): + self.email = u'foo@example.com' + self.optout = EmailOptout(email = self.email) + self.optout.save() + self.conf = EmailConfirmation(type = 'optin', email = self.email) + self.conf.save() + + def testOptinValidHash(self): + url = reverse('patchwork.views.confirm', + kwargs = {'key': self.conf.key}) + response = self.client.get(url) + + self.assertEquals(response.status_code, 200) + self.assertTemplateUsed(response, 'patchwork/optin.html') + self.assertTrue(self.email in response.content) + + # check that there's no optout remaining + self.assertEquals(EmailOptout.objects.count(), 0) + + # check that the confirmation is now inactive + self.assertFalse(EmailConfirmation.objects.get( + pk = self.conf.pk).active) + +class OptinWithoutOptoutTest(TestCase): + """Test an opt-in with no existing opt-out""" + view = 'patchwork.views.mail.optin' + url = reverse(view) + + def testOptInWithoutOptout(self): + email = u'foo@example.com' + response = self.client.post(self.url, {'email': email}) + + # check for an error message + self.assertEquals(response.status_code, 200) + self.assertTrue(bool(response.context['error'])) + self.assertTrue('not on the patchwork opt-out list' in response.content) + +class UserProfileOptoutFormTest(TestCase): + """Test that the correct optin/optout forms appear on the user profile + page, for logged-in users""" + + view = 'patchwork.views.user.profile' + url = reverse(view) + optout_url = reverse('patchwork.views.mail.optout') + optin_url = reverse('patchwork.views.mail.optin') + form_re_template = (']*action="%(url)s"[^>]*>' + '.*?]*value="%(email)s"[^>]*>.*?' + '') + secondary_email = 'test2@example.com' + + def setUp(self): + self.user = create_user() + self.client.login(username = self.user.username, + password = self.user.username) + + def _form_re(self, url, email): + return re.compile(self.form_re_template % {'url': url, 'email': email}, + re.DOTALL) + + def testMainEmailOptoutForm(self): + form_re = self._form_re(self.optout_url, self.user.email) + response = self.client.get(self.url) + self.assertEquals(response.status_code, 200) + self.assertTrue(form_re.search(response.content) is not None) + + def testMainEmailOptinForm(self): + EmailOptout(email = self.user.email).save() + form_re = self._form_re(self.optin_url, self.user.email) + response = self.client.get(self.url) + self.assertEquals(response.status_code, 200) + self.assertTrue(form_re.search(response.content) is not None) + + def testSecondaryEmailOptoutForm(self): + p = Person(email = self.secondary_email, user = self.user) + p.save() + + form_re = self._form_re(self.optout_url, p.email) + response = self.client.get(self.url) + self.assertEquals(response.status_code, 200) + self.assertTrue(form_re.search(response.content) is not None) + + def testSecondaryEmailOptinForm(self): + p = Person(email = self.secondary_email, user = self.user) + p.save() + EmailOptout(email = p.email).save() + + form_re = self._form_re(self.optin_url, p.email) + response = self.client.get(self.url) + self.assertEquals(response.status_code, 200) + self.assertTrue(form_re.search(response.content) is not None)