]> git.ozlabs.org Git - patchwork/blob - patchwork/tests/test_mail_settings.py
35c832ae7136ed0d32794a0b638c40d6d30a7cf1
[patchwork] / 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 re
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
26
27 class MailSettingsTest(TestCase):
28     view = 'patchwork.views.mail.settings'
29     url = reverse(view)
30
31     def testMailSettingsGET(self):
32         response = self.client.get(self.url)
33         self.assertEquals(response.status_code, 200)
34         self.assertTrue(response.context['form'])
35
36     def testMailSettingsPOST(self):
37         email = u'foo@example.com'
38         response = self.client.post(self.url, {'email': email})
39         self.assertEquals(response.status_code, 200)
40         self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
41         self.assertEquals(response.context['email'], email)
42
43     def testMailSettingsPOSTEmpty(self):
44         response = self.client.post(self.url, {'email': ''})
45         self.assertEquals(response.status_code, 200)
46         self.assertTemplateUsed(response, 'patchwork/mail-form.html')
47         self.assertFormError(response, 'form', 'email',
48                 'This field is required.')
49
50     def testMailSettingsPOSTInvalid(self):
51         response = self.client.post(self.url, {'email': 'foo'})
52         self.assertEquals(response.status_code, 200)
53         self.assertTemplateUsed(response, 'patchwork/mail-form.html')
54         self.assertFormError(response, 'form', 'email', error_strings['email'])
55
56     def testMailSettingsPOSTOptedIn(self):
57         email = u'foo@example.com'
58         response = self.client.post(self.url, {'email': email})
59         self.assertEquals(response.status_code, 200)
60         self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
61         self.assertEquals(response.context['is_optout'], False)
62         self.assertTrue('<strong>may</strong>' in response.content)
63         optout_url = reverse('patchwork.views.mail.optout')
64         self.assertTrue(('action="%s"' % optout_url) in response.content)
65
66     def testMailSettingsPOSTOptedOut(self):
67         email = u'foo@example.com'
68         EmailOptout(email = email).save()
69         response = self.client.post(self.url, {'email': email})
70         self.assertEquals(response.status_code, 200)
71         self.assertTemplateUsed(response, 'patchwork/mail-settings.html')
72         self.assertEquals(response.context['is_optout'], True)
73         self.assertTrue('<strong>may not</strong>' in response.content)
74         optin_url = reverse('patchwork.views.mail.optin')
75         self.assertTrue(('action="%s"' % optin_url) in response.content)
76
77 class OptoutRequestTest(TestCase):
78     view = 'patchwork.views.mail.optout'
79     url = reverse(view)
80
81     def testOptOutRequestGET(self):
82         response = self.client.get(self.url)
83         self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
84
85     def testOptoutRequestValidPOST(self):
86         email = u'foo@example.com'
87         response = self.client.post(self.url, {'email': email})
88
89         # check for a confirmation object
90         self.assertEquals(EmailConfirmation.objects.count(), 1)
91         conf = EmailConfirmation.objects.get(email = email)
92
93         # check confirmation page
94         self.assertEquals(response.status_code, 200)
95         self.assertEquals(response.context['confirmation'], conf)
96         self.assertTrue(email in response.content)
97
98         # check email
99         url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
100         self.assertEquals(len(mail.outbox), 1)
101         msg = mail.outbox[0]
102         self.assertEquals(msg.to, [email])
103         self.assertEquals(msg.subject, 'Patchwork opt-out confirmation')
104         self.assertTrue(url in msg.body)
105
106     def testOptoutRequestInvalidPOSTEmpty(self):
107         response = self.client.post(self.url, {'email': ''})
108         self.assertEquals(response.status_code, 200)
109         self.assertFormError(response, 'form', 'email',
110                 'This field is required.')
111         self.assertTrue(response.context['error'])
112         self.assertTrue('email_sent' not in response.context)
113         self.assertEquals(len(mail.outbox), 0)
114
115     def testOptoutRequestInvalidPOSTNonEmail(self):
116         response = self.client.post(self.url, {'email': 'foo'})
117         self.assertEquals(response.status_code, 200)
118         self.assertFormError(response, 'form', 'email', error_strings['email'])
119         self.assertTrue(response.context['error'])
120         self.assertTrue('email_sent' not in response.context)
121         self.assertEquals(len(mail.outbox), 0)
122
123 class OptoutTest(TestCase):
124     view = 'patchwork.views.mail.optout'
125     url = reverse(view)
126
127     def setUp(self):
128         self.email = u'foo@example.com'
129         self.conf = EmailConfirmation(type = 'optout', email = self.email)
130         self.conf.save()
131
132     def testOptoutValidHash(self):
133         url = reverse('patchwork.views.confirm',
134                         kwargs = {'key': self.conf.key})
135         response = self.client.get(url)
136
137         self.assertEquals(response.status_code, 200)
138         self.assertTemplateUsed(response, 'patchwork/optout.html')
139         self.assertTrue(self.email in response.content)
140
141         # check that we've got an optout in the list
142         self.assertEquals(EmailOptout.objects.count(), 1)
143         self.assertEquals(EmailOptout.objects.all()[0].email, self.email)
144
145         # check that the confirmation is now inactive
146         self.assertFalse(EmailConfirmation.objects.get(
147                                     pk = self.conf.pk).active)
148
149
150 class OptoutPreexistingTest(OptoutTest):
151     """Test that a duplicated opt-out behaves the same as the initial one"""
152     def setUp(self):
153         super(OptoutPreexistingTest, self).setUp()
154         EmailOptout(email = self.email).save()
155
156 class OptinRequestTest(TestCase):
157     view = 'patchwork.views.mail.optin'
158     url = reverse(view)
159
160     def setUp(self):
161         self.email = u'foo@example.com'
162         EmailOptout(email = self.email).save()
163
164     def testOptInRequestGET(self):
165         response = self.client.get(self.url)
166         self.assertRedirects(response, reverse('patchwork.views.mail.settings'))
167
168     def testOptInRequestValidPOST(self):
169         response = self.client.post(self.url, {'email': self.email})
170
171         # check for a confirmation object
172         self.assertEquals(EmailConfirmation.objects.count(), 1)
173         conf = EmailConfirmation.objects.get(email = self.email)
174
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)
179
180         # check email
181         url = reverse('patchwork.views.confirm', kwargs = {'key': conf.key})
182         self.assertEquals(len(mail.outbox), 1)
183         msg = mail.outbox[0]
184         self.assertEquals(msg.to, [self.email])
185         self.assertEquals(msg.subject, 'Patchwork opt-in confirmation')
186         self.assertTrue(url in msg.body)
187
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)
196
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)
204
205 class OptinTest(TestCase):
206
207     def setUp(self):
208         self.email = u'foo@example.com'
209         self.optout = EmailOptout(email = self.email)
210         self.optout.save()
211         self.conf = EmailConfirmation(type = 'optin', email = self.email)
212         self.conf.save()
213
214     def testOptinValidHash(self):
215         url = reverse('patchwork.views.confirm',
216                         kwargs = {'key': self.conf.key})
217         response = self.client.get(url)
218
219         self.assertEquals(response.status_code, 200)
220         self.assertTemplateUsed(response, 'patchwork/optin.html')
221         self.assertTrue(self.email in response.content)
222
223         # check that there's no optout remaining
224         self.assertEquals(EmailOptout.objects.count(), 0)
225
226         # check that the confirmation is now inactive
227         self.assertFalse(EmailConfirmation.objects.get(
228                                     pk = self.conf.pk).active)
229
230 class OptinWithoutOptoutTest(TestCase):
231     """Test an opt-in with no existing opt-out"""
232     view = 'patchwork.views.mail.optin'
233     url = reverse(view)
234
235     def testOptInWithoutOptout(self):
236         email = u'foo@example.com'
237         response = self.client.post(self.url, {'email': email})
238
239         # check for an error message
240         self.assertEquals(response.status_code, 200)
241         self.assertTrue(bool(response.context['error']))
242         self.assertTrue('not on the patchwork opt-out list' in response.content)
243
244 class UserProfileOptoutFormTest(TestCase):
245     """Test that the correct optin/optout forms appear on the user profile
246        page, for logged-in users"""
247
248     view = 'patchwork.views.user.profile'
249     url = reverse(view)
250     optout_url = reverse('patchwork.views.mail.optout')
251     optin_url = reverse('patchwork.views.mail.optin')
252     form_re_template = ('<form\s+[^>]*action="%(url)s"[^>]*>'
253                         '.*?<input\s+[^>]*value="%(email)s"[^>]*>.*?'
254                         '</form>')
255     secondary_email = 'test2@example.com'
256
257     def setUp(self):
258         self.user = create_user()
259         self.client.login(username = self.user.username,
260                 password = self.user.username)
261
262     def _form_re(self, url, email):
263         return re.compile(self.form_re_template % {'url': url, 'email': email},
264                           re.DOTALL)
265
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)
271
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)
278
279     def testSecondaryEmailOptoutForm(self):
280         p = Person(email = self.secondary_email, user = self.user)
281         p.save()
282         
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)
287
288     def testSecondaryEmailOptinForm(self):
289         p = Person(email = self.secondary_email, user = self.user)
290         p.save()
291         EmailOptout(email = p.email).save()
292
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)