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
22 from django.test import TestCase
23 from django.test.client import Client
24 from django.core import mail
25 from django.core.urlresolvers import reverse
26 from django.contrib.auth.models import User
27 from patchwork.models import EmailOptout, EmailConfirmation, Person
28 from patchwork.tests.utils import create_user, error_strings
30 class MailSettingsTest(TestCase):
31 view = 'patchwork.views.mail.settings'
34 def testMailSettingsGET(self):
35 response = self.client.get(self.url)
36 self.assertEquals(response.status_code, 200)
37 self.assertTrue(response.context['form'])
39 def testMailSettingsPOST(self):
40 email = u'foo@example.com'
41 response = self.client.post(self.url, {'email': email})
42 self.assertEquals(response.status_code, 200)
43 self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
44 self.assertEquals(response.context['email'], email)
46 def testMailSettingsPOSTEmpty(self):
47 response = self.client.post(self.url, {'email': ''})
48 self.assertEquals(response.status_code, 200)
49 self.assertTemplateUsed(response, 'patchwork/mail-form.html')
50 self.assertFormError(response, 'form', 'email',
51 'This field is required.')
53 def testMailSettingsPOSTInvalid(self):
54 response = self.client.post(self.url, {'email': 'foo'})
55 self.assertEquals(response.status_code, 200)
56 self.assertTemplateUsed(response, 'patchwork/mail-form.html')
57 self.assertFormError(response, 'form', 'email', error_strings['email'])
59 def testMailSettingsPOSTOptedIn(self):
60 email = u'foo@example.com'
61 response = self.client.post(self.url, {'email': email})
62 self.assertEquals(response.status_code, 200)
63 self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
64 self.assertEquals(response.context['is_optout'], False)
65 self.assertTrue('<strong>may</strong>' in response.content)
66 optout_url = reverse('patchwork.views.mail.optout')
67 self.assertTrue(('action="%s"' % optout_url) in response.content)
69 def testMailSettingsPOSTOptedOut(self):
70 email = u'foo@example.com'
71 EmailOptout(email = email).save()
72 response = self.client.post(self.url, {'email': email})
73 self.assertEquals(response.status_code, 200)
74 self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
75 self.assertEquals(response.context['is_optout'], True)
76 self.assertTrue('<strong>may not</strong>' in response.content)
77 optin_url = reverse('patchwork.views.mail.optin')
78 self.assertTrue(('action="%s"' % optin_url) in response.content)
80 class OptoutRequestTest(TestCase):
81 view = 'patchwork.views.mail.optout'
84 def testOptOutRequestGET(self):
85 response = self.client.get(self.url)
86 self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
88 def testOptoutRequestValidPOST(self):
89 email = u'foo@example.com'
90 response = self.client.post(self.url, {'email': email})
92 # check for a confirmation object
93 self.assertEquals(EmailConfirmation.objects.count(), 1)
94 conf = EmailConfirmation.objects.get(email = email)
96 # check confirmation page
97 self.assertEquals(response.status_code, 200)
98 self.assertEquals(response.context['confirmation'], conf)
99 self.assertTrue(email in response.content)
102 url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
103 self.assertEquals(len(mail.outbox), 1)
105 self.assertEquals(msg.to, [email])
106 self.assertEquals(msg.subject, 'Patchwork opt-out confirmation')
107 self.assertTrue(url in msg.body)
109 def testOptoutRequestInvalidPOSTEmpty(self):
110 response = self.client.post(self.url, {'email': ''})
111 self.assertEquals(response.status_code, 200)
112 self.assertFormError(response, 'form', 'email',
113 'This field is required.')
114 self.assertTrue(response.context['error'])
115 self.assertTrue('email_sent' not in response.context)
116 self.assertEquals(len(mail.outbox), 0)
118 def testOptoutRequestInvalidPOSTNonEmail(self):
119 response = self.client.post(self.url, {'email': 'foo'})
120 self.assertEquals(response.status_code, 200)
121 self.assertFormError(response, 'form', 'email', error_strings['email'])
122 self.assertTrue(response.context['error'])
123 self.assertTrue('email_sent' not in response.context)
124 self.assertEquals(len(mail.outbox), 0)
126 class OptoutTest(TestCase):
127 view = 'patchwork.views.mail.optout'
131 self.email = u'foo@example.com'
132 self.conf = EmailConfirmation(type = 'optout', email = self.email)
135 def testOptoutValidHash(self):
136 url = reverse('patchwork.views.confirm',
137 kwargs = {'key': self.conf.key})
138 response = self.client.get(url)
140 self.assertEquals(response.status_code, 200)
141 self.assertTemplateUsed(response, 'patchwork/optout.html')
142 self.assertTrue(self.email in response.content)
144 # check that we've got an optout in the list
145 self.assertEquals(EmailOptout.objects.count(), 1)
146 self.assertEquals(EmailOptout.objects.all()[0].email, self.email)
148 # check that the confirmation is now inactive
149 self.assertFalse(EmailConfirmation.objects.get(
150 pk = self.conf.pk).active)
153 class OptoutPreexistingTest(OptoutTest):
154 """Test that a duplicated opt-out behaves the same as the initial one"""
156 super(OptoutPreexistingTest, self).setUp()
157 EmailOptout(email = self.email).save()
159 class OptinRequestTest(TestCase):
160 view = 'patchwork.views.mail.optin'
164 self.email = u'foo@example.com'
165 EmailOptout(email = self.email).save()
167 def testOptInRequestGET(self):
168 response = self.client.get(self.url)
169 self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
171 def testOptInRequestValidPOST(self):
172 response = self.client.post(self.url, {'email': self.email})
174 # check for a confirmation object
175 self.assertEquals(EmailConfirmation.objects.count(), 1)
176 conf = EmailConfirmation.objects.get(email = self.email)
178 # check confirmation page
179 self.assertEquals(response.status_code, 200)
180 self.assertEquals(response.context['confirmation'], conf)
181 self.assertTrue(self.email in response.content)
184 url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
185 self.assertEquals(len(mail.outbox), 1)
187 self.assertEquals(msg.to, [self.email])
188 self.assertEquals(msg.subject, 'Patchwork opt-in confirmation')
189 self.assertTrue(url in msg.body)
191 def testOptoutRequestInvalidPOSTEmpty(self):
192 response = self.client.post(self.url, {'email': ''})
193 self.assertEquals(response.status_code, 200)
194 self.assertFormError(response, 'form', 'email',
195 'This field is required.')
196 self.assertTrue(response.context['error'])
197 self.assertTrue('email_sent' not in response.context)
198 self.assertEquals(len(mail.outbox), 0)
200 def testOptoutRequestInvalidPOSTNonEmail(self):
201 response = self.client.post(self.url, {'email': 'foo'})
202 self.assertEquals(response.status_code, 200)
203 self.assertFormError(response, 'form', 'email', error_strings['email'])
204 self.assertTrue(response.context['error'])
205 self.assertTrue('email_sent' not in response.context)
206 self.assertEquals(len(mail.outbox), 0)
208 class OptinTest(TestCase):
211 self.email = u'foo@example.com'
212 self.optout = EmailOptout(email = self.email)
214 self.conf = EmailConfirmation(type = 'optin', email = self.email)
217 def testOptinValidHash(self):
218 url = reverse('patchwork.views.confirm',
219 kwargs = {'key': self.conf.key})
220 response = self.client.get(url)
222 self.assertEquals(response.status_code, 200)
223 self.assertTemplateUsed(response, 'patchwork/optin.html')
224 self.assertTrue(self.email in response.content)
226 # check that there's no optout remaining
227 self.assertEquals(EmailOptout.objects.count(), 0)
229 # check that the confirmation is now inactive
230 self.assertFalse(EmailConfirmation.objects.get(
231 pk = self.conf.pk).active)
233 class OptinWithoutOptoutTest(TestCase):
234 """Test an opt-in with no existing opt-out"""
235 view = 'patchwork.views.mail.optin'
238 def testOptInWithoutOptout(self):
239 email = u'foo@example.com'
240 response = self.client.post(self.url, {'email': email})
242 # check for an error message
243 self.assertEquals(response.status_code, 200)
244 self.assertTrue(bool(response.context['error']))
245 self.assertTrue('not on the patchwork opt-out list' in response.content)
247 class UserProfileOptoutFormTest(TestCase):
248 """Test that the correct optin/optout forms appear on the user profile
249 page, for logged-in users"""
251 view = 'patchwork.views.user.profile'
253 optout_url = reverse('patchwork.views.mail.optout')
254 optin_url = reverse('patchwork.views.mail.optin')
255 form_re_template = ('<form\s+[^>]*action="%(url)s"[^>]*>'
256 '.*?<input\s+[^>]*value="%(email)s"[^>]*>.*?'
258 secondary_email = 'test2@example.com'
261 self.user = create_user()
262 self.client.login(username = self.user.username,
263 password = self.user.username)
265 def _form_re(self, url, email):
266 return re.compile(self.form_re_template % {'url': url, 'email': email},
269 def testMainEmailOptoutForm(self):
270 form_re = self._form_re(self.optout_url, self.user.email)
271 response = self.client.get(self.url)
272 self.assertEquals(response.status_code, 200)
273 self.assertTrue(form_re.search(response.content) is not None)
275 def testMainEmailOptinForm(self):
276 EmailOptout(email = self.user.email).save()
277 form_re = self._form_re(self.optin_url, self.user.email)
278 response = self.client.get(self.url)
279 self.assertEquals(response.status_code, 200)
280 self.assertTrue(form_re.search(response.content) is not None)
282 def testSecondaryEmailOptoutForm(self):
283 p = Person(email = self.secondary_email, user = self.user)
286 form_re = self._form_re(self.optout_url, p.email)
287 response = self.client.get(self.url)
288 self.assertEquals(response.status_code, 200)
289 self.assertTrue(form_re.search(response.content) is not None)
291 def testSecondaryEmailOptinForm(self):
292 p = Person(email = self.secondary_email, user = self.user)
294 EmailOptout(email = p.email).save()
296 form_re = self._form_re(self.optin_url, p.email)
297 response = self.client.get(self.url)
298 self.assertEquals(response.status_code, 200)
299 self.assertTrue(form_re.search(response.content) is not None)