]> git.ozlabs.org Git - patchwork/blob - apps/patchwork/tests/test_mail_settings.py
a193c9711375920d08a27fc131e6816f31b2a0ce
[patchwork] / apps / patchwork / tests / test_mail_settings.py
1 # Patchwork - automated patch tracking system
2 # Copyright (C) 2010 Jeremy Kerr <jk@ozlabs.org>
3 #
4 # This file is part of the Patchwork package.
5 #
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.
10 #
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.
15 #
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
19
20 import unittest
21 import re
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
29
30 class MailSettingsTest(TestCase):
31     view = 'patchwork.views.mail.settings'
32     url = reverse(view)
33
34     def testMailSettingsGET(self):
35         response = self.client.get(self.url)
36         self.assertEquals(response.status_code, 200)
37         self.assertTrue(response.context['form'])
38
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)
45
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.')
52
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'])
58
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)
68
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)
79
80 class OptoutRequestTest(TestCase):
81     view = 'patchwork.views.mail.optout'
82     url = reverse(view)
83
84     def testOptOutRequestGET(self):
85         response = self.client.get(self.url)
86         self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
87
88     def testOptoutRequestValidPOST(self):
89         email = u'foo@example.com'
90         response = self.client.post(self.url, {'email': email})
91
92         # check for a confirmation object
93         self.assertEquals(EmailConfirmation.objects.count(), 1)
94         conf = EmailConfirmation.objects.get(email = email)
95
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)
100
101         # check email
102         url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
103         self.assertEquals(len(mail.outbox), 1)
104         msg = mail.outbox[0]
105         self.assertEquals(msg.to, [email])
106         self.assertEquals(msg.subject, 'Patchwork opt-out confirmation')
107         self.assertTrue(url in msg.body)
108
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)
117
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)
125
126 class OptoutTest(TestCase):
127     view = 'patchwork.views.mail.optout'
128     url = reverse(view)
129
130     def setUp(self):
131         self.email = u'foo@example.com'
132         self.conf = EmailConfirmation(type = 'optout', email = self.email)
133         self.conf.save()
134
135     def testOptoutValidHash(self):
136         url = reverse('patchwork.views.confirm',
137                         kwargs = {'key': self.conf.key})
138         response = self.client.get(url)
139
140         self.assertEquals(response.status_code, 200)
141         self.assertTemplateUsed(response, 'patchwork/optout.html')
142         self.assertTrue(self.email in response.content)
143
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)
147
148         # check that the confirmation is now inactive
149         self.assertFalse(EmailConfirmation.objects.get(
150                                     pk = self.conf.pk).active)
151
152
153 class OptoutPreexistingTest(OptoutTest):
154     """Test that a duplicated opt-out behaves the same as the initial one"""
155     def setUp(self):
156         super(OptoutPreexistingTest, self).setUp()
157         EmailOptout(email = self.email).save()
158
159 class OptinRequestTest(TestCase):
160     view = 'patchwork.views.mail.optin'
161     url = reverse(view)
162
163     def setUp(self):
164         self.email = u'foo@example.com'
165         EmailOptout(email = self.email).save()
166
167     def testOptInRequestGET(self):
168         response = self.client.get(self.url)
169         self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
170
171     def testOptInRequestValidPOST(self):
172         response = self.client.post(self.url, {'email': self.email})
173
174         # check for a confirmation object
175         self.assertEquals(EmailConfirmation.objects.count(), 1)
176         conf = EmailConfirmation.objects.get(email = self.email)
177
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)
182
183         # check email
184         url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
185         self.assertEquals(len(mail.outbox), 1)
186         msg = mail.outbox[0]
187         self.assertEquals(msg.to, [self.email])
188         self.assertEquals(msg.subject, 'Patchwork opt-in confirmation')
189         self.assertTrue(url in msg.body)
190
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)
199
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)
207
208 class OptinTest(TestCase):
209
210     def setUp(self):
211         self.email = u'foo@example.com'
212         self.optout = EmailOptout(email = self.email)
213         self.optout.save()
214         self.conf = EmailConfirmation(type = 'optin', email = self.email)
215         self.conf.save()
216
217     def testOptinValidHash(self):
218         url = reverse('patchwork.views.confirm',
219                         kwargs = {'key': self.conf.key})
220         response = self.client.get(url)
221
222         self.assertEquals(response.status_code, 200)
223         self.assertTemplateUsed(response, 'patchwork/optin.html')
224         self.assertTrue(self.email in response.content)
225
226         # check that there's no optout remaining
227         self.assertEquals(EmailOptout.objects.count(), 0)
228
229         # check that the confirmation is now inactive
230         self.assertFalse(EmailConfirmation.objects.get(
231                                     pk = self.conf.pk).active)
232
233 class OptinWithoutOptoutTest(TestCase):
234     """Test an opt-in with no existing opt-out"""
235     view = 'patchwork.views.mail.optin'
236     url = reverse(view)
237
238     def testOptInWithoutOptout(self):
239         email = u'foo@example.com'
240         response = self.client.post(self.url, {'email': email})
241
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)
246
247 class UserProfileOptoutFormTest(TestCase):
248     """Test that the correct optin/optout forms appear on the user profile
249        page, for logged-in users"""
250
251     view = 'patchwork.views.user.profile'
252     url = reverse(view)
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"[^>]*>.*?'
257                         '</form>')
258     secondary_email = 'test2@example.com'
259
260     def setUp(self):
261         self.user = create_user()
262         self.client.login(username = self.user.username,
263                 password = self.user.username)
264
265     def _form_re(self, url, email):
266         return re.compile(self.form_re_template % {'url': url, 'email': email},
267                           re.DOTALL)
268
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)
274
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)
281
282     def testSecondaryEmailOptoutForm(self):
283         p = Person(email = self.secondary_email, user = self.user)
284         p.save()
285         
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)
290
291     def testSecondaryEmailOptinForm(self):
292         p = Person(email = self.secondary_email, user = self.user)
293         p.save()
294         EmailOptout(email = p.email).save()
295
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)