1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2010 Jeremy Kerr <jk@ozlabs.org>
4 # This file is part of the Patchwork package.
6 # Patchwork is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # Patchwork is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with Patchwork; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 from django.test import TestCase
22 from django.core import mail
23 from django.core.urlresolvers import reverse
24 from patchwork.models import EmailOptout, EmailConfirmation, Person
25 from patchwork.tests.utils import create_user, error_strings
27 class MailSettingsTest(TestCase):
30 self.url = reverse('patchwork.views.mail.settings')
32 def testMailSettingsGET(self):
33 response = self.client.get(self.url)
34 self.assertEquals(response.status_code, 200)
35 self.assertTrue(response.context['form'])
37 def testMailSettingsPOST(self):
38 email = u'foo@example.com'
39 response = self.client.post(self.url, {'email': email})
40 self.assertEquals(response.status_code, 200)
41 self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
42 self.assertEquals(response.context['email'], email)
44 def testMailSettingsPOSTEmpty(self):
45 response = self.client.post(self.url, {'email': ''})
46 self.assertEquals(response.status_code, 200)
47 self.assertTemplateUsed(response, 'patchwork/mail-form.html')
48 self.assertFormError(response, 'form', 'email',
49 'This field is required.')
51 def testMailSettingsPOSTInvalid(self):
52 response = self.client.post(self.url, {'email': 'foo'})
53 self.assertEquals(response.status_code, 200)
54 self.assertTemplateUsed(response, 'patchwork/mail-form.html')
55 self.assertFormError(response, 'form', 'email', error_strings['email'])
57 def testMailSettingsPOSTOptedIn(self):
58 email = u'foo@example.com'
59 response = self.client.post(self.url, {'email': email})
60 self.assertEquals(response.status_code, 200)
61 self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
62 self.assertEquals(response.context['is_optout'], False)
63 self.assertTrue('<strong>may</strong>' in response.content)
64 optout_url = reverse('patchwork.views.mail.optout')
65 self.assertTrue(('action="%s"' % optout_url) in response.content)
67 def testMailSettingsPOSTOptedOut(self):
68 email = u'foo@example.com'
69 EmailOptout(email = email).save()
70 response = self.client.post(self.url, {'email': email})
71 self.assertEquals(response.status_code, 200)
72 self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
73 self.assertEquals(response.context['is_optout'], True)
74 self.assertTrue('<strong>may not</strong>' in response.content)
75 optin_url = reverse('patchwork.views.mail.optin')
76 self.assertTrue(('action="%s"' % optin_url) in response.content)
78 class OptoutRequestTest(TestCase):
81 self.url = reverse('patchwork.views.mail.optout')
83 def testOptOutRequestGET(self):
84 response = self.client.get(self.url)
85 self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
87 def testOptoutRequestValidPOST(self):
88 email = u'foo@example.com'
89 response = self.client.post(self.url, {'email': email})
91 # check for a confirmation object
92 self.assertEquals(EmailConfirmation.objects.count(), 1)
93 conf = EmailConfirmation.objects.get(email = email)
95 # check confirmation page
96 self.assertEquals(response.status_code, 200)
97 self.assertEquals(response.context['confirmation'], conf)
98 self.assertTrue(email in response.content)
101 url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
102 self.assertEquals(len(mail.outbox), 1)
104 self.assertEquals(msg.to, [email])
105 self.assertEquals(msg.subject, 'Patchwork opt-out confirmation')
106 self.assertTrue(url in msg.body)
108 def testOptoutRequestInvalidPOSTEmpty(self):
109 response = self.client.post(self.url, {'email': ''})
110 self.assertEquals(response.status_code, 200)
111 self.assertFormError(response, 'form', 'email',
112 'This field is required.')
113 self.assertTrue(response.context['error'])
114 self.assertTrue('email_sent' not in response.context)
115 self.assertEquals(len(mail.outbox), 0)
117 def testOptoutRequestInvalidPOSTNonEmail(self):
118 response = self.client.post(self.url, {'email': 'foo'})
119 self.assertEquals(response.status_code, 200)
120 self.assertFormError(response, 'form', 'email', error_strings['email'])
121 self.assertTrue(response.context['error'])
122 self.assertTrue('email_sent' not in response.context)
123 self.assertEquals(len(mail.outbox), 0)
125 class OptoutTest(TestCase):
128 self.url = reverse('patchwork.views.mail.optout')
129 self.email = u'foo@example.com'
130 self.conf = EmailConfirmation(type = 'optout', email = self.email)
133 def testOptoutValidHash(self):
134 url = reverse('patchwork.views.confirm',
135 kwargs = {'key': self.conf.key})
136 response = self.client.get(url)
138 self.assertEquals(response.status_code, 200)
139 self.assertTemplateUsed(response, 'patchwork/optout.html')
140 self.assertTrue(self.email in response.content)
142 # check that we've got an optout in the list
143 self.assertEquals(EmailOptout.objects.count(), 1)
144 self.assertEquals(EmailOptout.objects.all()[0].email, self.email)
146 # check that the confirmation is now inactive
147 self.assertFalse(EmailConfirmation.objects.get(
148 pk = self.conf.pk).active)
151 class OptoutPreexistingTest(OptoutTest):
152 """Test that a duplicated opt-out behaves the same as the initial one"""
154 super(OptoutPreexistingTest, self).setUp()
155 EmailOptout(email = self.email).save()
157 class OptinRequestTest(TestCase):
160 self.url = reverse('patchwork.views.mail.optin')
161 self.email = u'foo@example.com'
162 EmailOptout(email = self.email).save()
164 def testOptInRequestGET(self):
165 response = self.client.get(self.url)
166 self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
168 def testOptInRequestValidPOST(self):
169 response = self.client.post(self.url, {'email': self.email})
171 # check for a confirmation object
172 self.assertEquals(EmailConfirmation.objects.count(), 1)
173 conf = EmailConfirmation.objects.get(email = self.email)
175 # check confirmation page
176 self.assertEquals(response.status_code, 200)
177 self.assertEquals(response.context['confirmation'], conf)
178 self.assertTrue(self.email in response.content)
181 url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
182 self.assertEquals(len(mail.outbox), 1)
184 self.assertEquals(msg.to, [self.email])
185 self.assertEquals(msg.subject, 'Patchwork opt-in confirmation')
186 self.assertTrue(url in msg.body)
188 def testOptoutRequestInvalidPOSTEmpty(self):
189 response = self.client.post(self.url, {'email': ''})
190 self.assertEquals(response.status_code, 200)
191 self.assertFormError(response, 'form', 'email',
192 'This field is required.')
193 self.assertTrue(response.context['error'])
194 self.assertTrue('email_sent' not in response.context)
195 self.assertEquals(len(mail.outbox), 0)
197 def testOptoutRequestInvalidPOSTNonEmail(self):
198 response = self.client.post(self.url, {'email': 'foo'})
199 self.assertEquals(response.status_code, 200)
200 self.assertFormError(response, 'form', 'email', error_strings['email'])
201 self.assertTrue(response.context['error'])
202 self.assertTrue('email_sent' not in response.context)
203 self.assertEquals(len(mail.outbox), 0)
205 class OptinTest(TestCase):
208 self.email = u'foo@example.com'
209 self.optout = EmailOptout(email = self.email)
211 self.conf = EmailConfirmation(type = 'optin', email = self.email)
214 def testOptinValidHash(self):
215 url = reverse('patchwork.views.confirm',
216 kwargs = {'key': self.conf.key})
217 response = self.client.get(url)
219 self.assertEquals(response.status_code, 200)
220 self.assertTemplateUsed(response, 'patchwork/optin.html')
221 self.assertTrue(self.email in response.content)
223 # check that there's no optout remaining
224 self.assertEquals(EmailOptout.objects.count(), 0)
226 # check that the confirmation is now inactive
227 self.assertFalse(EmailConfirmation.objects.get(
228 pk = self.conf.pk).active)
230 class OptinWithoutOptoutTest(TestCase):
231 """Test an opt-in with no existing opt-out"""
234 self.url = reverse('patchwork.views.mail.optin')
236 def testOptInWithoutOptout(self):
237 email = u'foo@example.com'
238 response = self.client.post(self.url, {'email': email})
240 # check for an error message
241 self.assertEquals(response.status_code, 200)
242 self.assertTrue(bool(response.context['error']))
243 self.assertTrue('not on the patchwork opt-out list' in response.content)
245 class UserProfileOptoutFormTest(TestCase):
246 """Test that the correct optin/optout forms appear on the user profile
247 page, for logged-in users"""
250 self.url = reverse('patchwork.views.user.profile')
251 self.optout_url = reverse('patchwork.views.mail.optout')
252 self.optin_url = reverse('patchwork.views.mail.optin')
253 self.form_re_template = ('<form\s+[^>]*action="%(url)s"[^>]*>'
254 '.*?<input\s+[^>]*value="%(email)s"[^>]*>.*?'
256 self.secondary_email = 'test2@example.com'
258 self.user = create_user()
259 self.client.login(username = self.user.username,
260 password = self.user.username)
262 def _form_re(self, url, email):
263 return re.compile(self.form_re_template % {'url': url, 'email': email},
266 def testMainEmailOptoutForm(self):
267 form_re = self._form_re(self.optout_url, self.user.email)
268 response = self.client.get(self.url)
269 self.assertEquals(response.status_code, 200)
270 self.assertTrue(form_re.search(response.content) is not None)
272 def testMainEmailOptinForm(self):
273 EmailOptout(email = self.user.email).save()
274 form_re = self._form_re(self.optin_url, self.user.email)
275 response = self.client.get(self.url)
276 self.assertEquals(response.status_code, 200)
277 self.assertTrue(form_re.search(response.content) is not None)
279 def testSecondaryEmailOptoutForm(self):
280 p = Person(email = self.secondary_email, user = self.user)
283 form_re = self._form_re(self.optout_url, p.email)
284 response = self.client.get(self.url)
285 self.assertEquals(response.status_code, 200)
286 self.assertTrue(form_re.search(response.content) is not None)
288 def testSecondaryEmailOptinForm(self):
289 p = Person(email = self.secondary_email, user = self.user)
291 EmailOptout(email = p.email).save()
293 form_re = self._form_re(self.optin_url, p.email)
294 response = self.client.get(self.url)
295 self.assertEquals(response.status_code, 200)
296 self.assertTrue(form_re.search(response.content) is not None)