1 # vim: set fileencoding=utf-8 :
3 # Patchwork - automated patch tracking system
4 # Copyright (C) 2009 Jeremy Kerr <jk@ozlabs.org>
6 # This file is part of the Patchwork package.
8 # Patchwork is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 2 of the License, or
11 # (at your option) any later version.
13 # Patchwork is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU General Public License for more details.
18 # You should have received a copy of the GNU General Public License
19 # along with Patchwork; if not, write to the Free Software
20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 import dateutil.parser, dateutil.tz
26 from django.test import TestCase
27 from django.test.client import Client
28 from patchwork.models import Patch, Comment, Person
29 from patchwork.tests.utils import defaults, create_user, find_in_context
31 class MboxPatchResponseTest(TestCase):
32 fixtures = ['default_states']
34 """ Test that the mbox view appends the Acked-by from a patch comment """
36 defaults.project.save()
38 self.person = defaults.patch_author_person
41 self.patch = Patch(project = defaults.project,
42 msgid = 'p1', name = 'testpatch',
43 submitter = self.person, content = '')
45 comment = Comment(patch = self.patch, msgid = 'p1',
46 submitter = self.person,
47 content = 'comment 1 text\nAcked-by: 1\n')
50 comment = Comment(patch = self.patch, msgid = 'p2',
51 submitter = self.person,
52 content = 'comment 2 text\nAcked-by: 2\n')
55 def testPatchResponse(self):
56 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
57 self.assertContains(response,
58 'Acked-by: 1\nAcked-by: 2\n')
60 class MboxPatchSplitResponseTest(TestCase):
61 fixtures = ['default_states']
63 """ Test that the mbox view appends the Acked-by from a patch comment,
64 and places it before an '---' update line. """
66 defaults.project.save()
68 self.person = defaults.patch_author_person
71 self.patch = Patch(project = defaults.project,
72 msgid = 'p1', name = 'testpatch',
73 submitter = self.person, content = '')
75 comment = Comment(patch = self.patch, msgid = 'p1',
76 submitter = self.person,
77 content = 'comment 1 text\nAcked-by: 1\n---\nupdate\n')
80 comment = Comment(patch = self.patch, msgid = 'p2',
81 submitter = self.person,
82 content = 'comment 2 text\nAcked-by: 2\n')
85 def testPatchResponse(self):
86 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
87 self.assertContains(response,
88 'Acked-by: 1\nAcked-by: 2\n')
90 class MboxPassThroughHeaderTest(TestCase):
91 fixtures = ['default_states']
93 """ Test that we see 'Cc' and 'To' headers passed through from original
94 message to mbox view """
97 defaults.project.save()
98 self.person = defaults.patch_author_person
101 self.cc_header = 'Cc: CC Person <cc@example.com>'
102 self.to_header = 'To: To Person <to@example.com>'
103 self.date_header = 'Date: Fri, 7 Jun 2013 15:42:54 +1000'
105 self.patch = Patch(project = defaults.project,
106 msgid = 'p1', name = 'testpatch',
107 submitter = self.person, content = '')
109 def testCCHeader(self):
110 self.patch.headers = self.cc_header + '\n'
113 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
114 self.assertContains(response, self.cc_header)
116 def testToHeader(self):
117 self.patch.headers = self.to_header + '\n'
120 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
121 self.assertContains(response, self.to_header)
123 def testDateHeader(self):
124 self.patch.headers = self.date_header + '\n'
127 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
128 self.assertContains(response, self.date_header)
130 class MboxBrokenFromHeaderTest(TestCase):
131 fixtures = ['default_states']
133 """ Test that a person with characters outside ASCII in his name do
134 produce correct From header. As RFC 2822 state we must retain the
135 <user@doamin.tld> format for the mail while the name part may be coded
139 defaults.project.save()
140 self.person = defaults.patch_author_person
141 self.person.name = u'©ool guŷ'
144 self.patch = Patch(project = defaults.project,
145 msgid = 'p1', name = 'testpatch',
146 submitter = self.person, content = '')
148 def testFromHeader(self):
150 from_email = '<' + self.person.email + '>'
152 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
153 self.assertContains(response, from_email)
155 class MboxDateHeaderTest(TestCase):
156 fixtures = ['default_states']
158 """ Test that the date provided in the patch mail view is correct """
161 defaults.project.save()
162 self.person = defaults.patch_author_person
165 self.patch = Patch(project = defaults.project,
166 msgid = 'p1', name = 'testpatch',
167 submitter = self.person, content = '')
170 def testDateHeader(self):
171 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
172 mail = email.message_from_string(response.content)
173 mail_date = dateutil.parser.parse(mail['Date'])
174 # patch dates are all in UTC
175 patch_date = self.patch.date.replace(tzinfo=dateutil.tz.tzutc(),
177 self.assertEqual(mail_date, patch_date)
179 def testSuppliedDateHeader(self):
181 tz = dateutil.tz.tzoffset(None, hour_offset * 60 * 60)
182 date = datetime.datetime.utcnow() - datetime.timedelta(days = 1)
183 date = date.replace(tzinfo=tz, microsecond=0)
185 self.patch.headers = 'Date: %s\n' % date.strftime("%a, %d %b %Y %T %z")
188 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
189 mail = email.message_from_string(response.content)
190 mail_date = dateutil.parser.parse(mail['Date'])
191 self.assertEqual(mail_date, date)
193 class MboxCommentPostcriptUnchangedTest(TestCase):
194 fixtures = ['default_states']
196 """ Test that the mbox view doesn't change the postscript part of a mail.
197 There where always a missing blank right after the postscript
198 delimiter '---' and an additional newline right before. """
200 defaults.project.save()
202 self.person = defaults.patch_author_person
205 self.patch = Patch(project = defaults.project,
206 msgid = 'p1', name = 'testpatch',
207 submitter = self.person, content = '')
210 self.txt = 'some comment\n---\n some/file | 1 +\n'
212 comment = Comment(patch = self.patch, msgid = 'p1',
213 submitter = self.person,
217 def testCommentUnchanged(self):
218 response = self.client.get('/patch/%d/mbox/' % self.patch.id)
219 self.assertContains(response, self.txt)
221 self.assertNotContains(response, self.txt)