251b47cde591f84dbf720ffbf94d4ad2dd305be5
1 # -*- encoding: utf-8 -*-
2 #
3 # Copyright (c) 2001 Richard Jones, richard@bofh.asn.au.
4 # This module is free software, and you may redistribute it and/or modify
5 # under the same terms as Python, so long as this copyright message and
6 # disclaimer are retained in their original form.
7 #
8 # This module is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11 #
12 # $Id: test_mailgw.py,v 1.96 2008-08-19 01:40:59 richard Exp $
14 # TODO: test bcc
16 import unittest, tempfile, os, shutil, errno, imp, sys, difflib, rfc822, time
18 from cStringIO import StringIO
20 if not os.environ.has_key('SENDMAILDEBUG'):
21 os.environ['SENDMAILDEBUG'] = 'mail-test.log'
22 SENDMAILDEBUG = os.environ['SENDMAILDEBUG']
24 from roundup.mailgw import MailGW, Unauthorized, uidFromAddress, \
25 parseContent, IgnoreLoop, IgnoreBulk, MailUsageError, MailUsageHelp
26 from roundup import init, instance, password, rfc2822, __version__
27 from roundup.anypy.sets_ import set
29 import db_test_base
31 class Message(rfc822.Message):
32 """String-based Message class with equivalence test."""
33 def __init__(self, s):
34 rfc822.Message.__init__(self, StringIO(s.strip()))
36 def __eq__(self, other):
37 return (self.dict == other.dict and
38 self.fp.read() == other.fp.read())
40 class DiffHelper:
41 def compareMessages(self, new, old):
42 """Compare messages for semantic equivalence."""
43 new, old = Message(new), Message(old)
45 # all Roundup-generated messages have "Precedence: bulk"
46 old['Precedence'] = 'bulk'
48 # don't try to compare the date
49 del new['date'], old['date']
51 if not new == old:
52 res = []
54 replace = {}
55 for key in new.keys():
56 if key.startswith('from '):
57 # skip the unix from line
58 continue
59 if key.lower() == 'x-roundup-version':
60 # version changes constantly, so handle it specially
61 if new[key] != __version__:
62 res.append(' %s: %r != %r' % (key, __version__,
63 new[key]))
64 elif key.lower() == 'content-type' and 'boundary=' in new[key]:
65 # handle mime messages
66 newmime = new[key].split('=',1)[-1].strip('"')
67 oldmime = old.get(key, '').split('=',1)[-1].strip('"')
68 replace ['--' + newmime] = '--' + oldmime
69 replace ['--' + newmime + '--'] = '--' + oldmime + '--'
70 elif new.get(key, '') != old.get(key, ''):
71 res.append(' %s: %r != %r' % (key, old.get(key, ''),
72 new.get(key, '')))
74 body_diff = self.compareStrings(new.fp.read(), old.fp.read(),
75 replace=replace)
76 if body_diff:
77 res.append('')
78 res.extend(body_diff)
80 if res:
81 res.insert(0, 'Generated message not correct (diff follows):')
82 raise AssertionError, '\n'.join(res)
84 def compareStrings(self, s2, s1, replace={}):
85 '''Note the reversal of s2 and s1 - difflib.SequenceMatcher wants
86 the first to be the "original" but in the calls in this file,
87 the second arg is the original. Ho hum.
88 Do replacements over the replace dict -- used for mime boundary
89 '''
90 l1 = s1.strip().split('\n')
91 l2 = [replace.get(i,i) for i in s2.strip().split('\n')]
92 if l1 == l2:
93 return
94 s = difflib.SequenceMatcher(None, l1, l2)
95 res = []
96 for value, s1s, s1e, s2s, s2e in s.get_opcodes():
97 if value == 'equal':
98 for i in range(s1s, s1e):
99 res.append(' %s'%l1[i])
100 elif value == 'delete':
101 for i in range(s1s, s1e):
102 res.append('- %s'%l1[i])
103 elif value == 'insert':
104 for i in range(s2s, s2e):
105 res.append('+ %s'%l2[i])
106 elif value == 'replace':
107 for i, j in zip(range(s1s, s1e), range(s2s, s2e)):
108 res.append('- %s'%l1[i])
109 res.append('+ %s'%l2[j])
111 return res
113 class MailgwTestCase(unittest.TestCase, DiffHelper):
114 count = 0
115 schema = 'classic'
116 def setUp(self):
117 MailgwTestCase.count = MailgwTestCase.count + 1
118 self.dirname = '_test_mailgw_%s'%self.count
119 # set up and open a tracker
120 self.instance = db_test_base.setupTracker(self.dirname)
122 # and open the database
123 self.db = self.instance.open('admin')
124 self.chef_id = self.db.user.create(username='Chef',
125 address='chef@bork.bork.bork', realname='Bork, Chef', roles='User')
126 self.richard_id = self.db.user.create(username='richard',
127 address='richard@test.test', roles='User')
128 self.mary_id = self.db.user.create(username='mary',
129 address='mary@test.test', roles='User', realname='Contrary, Mary')
130 self.john_id = self.db.user.create(username='john',
131 address='john@test.test', roles='User', realname='John Doe',
132 alternate_addresses='jondoe@test.test\njohn.doe@test.test')
134 def tearDown(self):
135 if os.path.exists(SENDMAILDEBUG):
136 os.remove(SENDMAILDEBUG)
137 self.db.close()
138 try:
139 shutil.rmtree(self.dirname)
140 except OSError, error:
141 if error.errno not in (errno.ENOENT, errno.ESRCH): raise
143 def _handle_mail(self, message):
144 # handler will open a new db handle. On single-threaded
145 # databases we'll have to close our current connection
146 self.db.commit()
147 self.db.close()
148 handler = self.instance.MailGW(self.instance)
149 handler.trapExceptions = 0
150 ret = handler.main(StringIO(message))
151 # handler had its own database, open new connection
152 self.db = self.instance.open('admin')
153 return ret
155 def _get_mail(self):
156 f = open(SENDMAILDEBUG)
157 try:
158 return f.read()
159 finally:
160 f.close()
162 def testEmptyMessage(self):
163 nodeid = self._handle_mail('''Content-Type: text/plain;
164 charset="iso-8859-1"
165 From: Chef <chef@bork.bork.bork>
166 To: issue_tracker@your.tracker.email.domain.example
167 Cc: richard@test.test
168 Reply-To: chef@bork.bork.bork
169 Message-Id: <dummy_test_message_id>
170 Subject: [issue] Testing...
172 ''')
173 assert not os.path.exists(SENDMAILDEBUG)
174 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'Testing...')
176 def doNewIssue(self):
177 nodeid = self._handle_mail('''Content-Type: text/plain;
178 charset="iso-8859-1"
179 From: Chef <chef@bork.bork.bork>
180 To: issue_tracker@your.tracker.email.domain.example
181 Cc: richard@test.test
182 Message-Id: <dummy_test_message_id>
183 Subject: [issue] Testing...
185 This is a test submission of a new issue.
186 ''')
187 assert not os.path.exists(SENDMAILDEBUG)
188 l = self.db.issue.get(nodeid, 'nosy')
189 l.sort()
190 self.assertEqual(l, [self.chef_id, self.richard_id])
191 return nodeid
193 def testNewIssue(self):
194 self.doNewIssue()
196 def testNewIssueNosy(self):
197 self.instance.config.ADD_AUTHOR_TO_NOSY = 'yes'
198 nodeid = self._handle_mail('''Content-Type: text/plain;
199 charset="iso-8859-1"
200 From: Chef <chef@bork.bork.bork>
201 To: issue_tracker@your.tracker.email.domain.example
202 Cc: richard@test.test
203 Message-Id: <dummy_test_message_id>
204 Subject: [issue] Testing...
206 This is a test submission of a new issue.
207 ''')
208 assert not os.path.exists(SENDMAILDEBUG)
209 l = self.db.issue.get(nodeid, 'nosy')
210 l.sort()
211 self.assertEqual(l, [self.chef_id, self.richard_id])
213 def testAlternateAddress(self):
214 self._handle_mail('''Content-Type: text/plain;
215 charset="iso-8859-1"
216 From: John Doe <john.doe@test.test>
217 To: issue_tracker@your.tracker.email.domain.example
218 Message-Id: <dummy_test_message_id>
219 Subject: [issue] Testing...
221 This is a test submission of a new issue.
222 ''')
223 userlist = self.db.user.list()
224 assert not os.path.exists(SENDMAILDEBUG)
225 self.assertEqual(userlist, self.db.user.list(),
226 "user created when it shouldn't have been")
228 def testNewIssueNoClass(self):
229 self._handle_mail('''Content-Type: text/plain;
230 charset="iso-8859-1"
231 From: Chef <chef@bork.bork.bork>
232 To: issue_tracker@your.tracker.email.domain.example
233 Cc: richard@test.test
234 Message-Id: <dummy_test_message_id>
235 Subject: Testing...
237 This is a test submission of a new issue.
238 ''')
239 assert not os.path.exists(SENDMAILDEBUG)
241 def testNewIssueAuthMsg(self):
242 # TODO: fix the damn config - this is apalling
243 self.db.config.MESSAGES_TO_AUTHOR = 'yes'
244 self._handle_mail('''Content-Type: text/plain;
245 charset="iso-8859-1"
246 From: Chef <chef@bork.bork.bork>
247 To: issue_tracker@your.tracker.email.domain.example
248 Message-Id: <dummy_test_message_id>
249 Subject: [issue] Testing... [nosy=mary; assignedto=richard]
251 This is a test submission of a new issue.
252 ''')
253 self.compareMessages(self._get_mail(),
254 '''FROM: roundup-admin@your.tracker.email.domain.example
255 TO: chef@bork.bork.bork, mary@test.test, richard@test.test
256 Content-Type: text/plain; charset="utf-8"
257 Subject: [issue1] Testing...
258 To: chef@bork.bork.bork, mary@test.test, richard@test.test
259 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
260 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
261 MIME-Version: 1.0
262 Message-Id: <dummy_test_message_id>
263 X-Roundup-Name: Roundup issue tracker
264 X-Roundup-Loop: hello
265 X-Roundup-Issue-Status: unread
266 Content-Transfer-Encoding: quoted-printable
269 New submission from Bork, Chef <chef@bork.bork.bork>:
271 This is a test submission of a new issue.
273 ----------
274 assignedto: richard
275 messages: 1
276 nosy: Chef, mary, richard
277 status: unread
278 title: Testing...
280 _______________________________________________________________________
281 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
282 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
283 _______________________________________________________________________
284 ''')
286 def testNewIssueNoAuthorInfo(self):
287 self.db.config.MAIL_ADD_AUTHORINFO = 'no'
288 self._handle_mail('''Content-Type: text/plain;
289 charset="iso-8859-1"
290 From: Chef <chef@bork.bork.bork>
291 To: issue_tracker@your.tracker.email.domain.example
292 Message-Id: <dummy_test_message_id>
293 Subject: [issue] Testing... [nosy=mary; assignedto=richard]
295 This is a test submission of a new issue.
296 ''')
297 self.compareMessages(self._get_mail(),
298 '''FROM: roundup-admin@your.tracker.email.domain.example
299 TO: chef@bork.bork.bork, mary@test.test, richard@test.test
300 Content-Type: text/plain; charset="utf-8"
301 Subject: [issue1] Testing...
302 To: mary@test.test, richard@test.test
303 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
304 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
305 MIME-Version: 1.0
306 Message-Id: <dummy_test_message_id>
307 X-Roundup-Name: Roundup issue tracker
308 X-Roundup-Loop: hello
309 X-Roundup-Issue-Status: unread
310 Content-Transfer-Encoding: quoted-printable
312 This is a test submission of a new issue.
314 ----------
315 assignedto: richard
316 messages: 1
317 nosy: Chef, mary, richard
318 status: unread
319 title: Testing...
321 _______________________________________________________________________
322 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
323 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
324 _______________________________________________________________________
325 ''')
327 def testNewIssueNoAuthorEmail(self):
328 self.db.config.MAIL_ADD_AUTHOREMAIL = 'no'
329 self._handle_mail('''Content-Type: text/plain;
330 charset="iso-8859-1"
331 From: Chef <chef@bork.bork.bork>
332 To: issue_tracker@your.tracker.email.domain.example
333 Message-Id: <dummy_test_message_id>
334 Subject: [issue] Testing... [nosy=mary; assignedto=richard]
336 This is a test submission of a new issue.
337 ''')
338 self.compareMessages(self._get_mail(),
339 '''FROM: roundup-admin@your.tracker.email.domain.example
340 TO: chef@bork.bork.bork, mary@test.test, richard@test.test
341 Content-Type: text/plain; charset="utf-8"
342 Subject: [issue1] Testing...
343 To: mary@test.test, richard@test.test
344 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
345 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
346 MIME-Version: 1.0
347 Message-Id: <dummy_test_message_id>
348 X-Roundup-Name: Roundup issue tracker
349 X-Roundup-Loop: hello
350 X-Roundup-Issue-Status: unread
351 Content-Transfer-Encoding: quoted-printable
353 New submission from Bork, Chef:
355 This is a test submission of a new issue.
357 ----------
358 assignedto: richard
359 messages: 1
360 nosy: Chef, mary, richard
361 status: unread
362 title: Testing...
364 _______________________________________________________________________
365 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
366 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
367 _______________________________________________________________________
368 ''')
370 multipart_msg = '''From: mary <mary@test.test>
371 To: issue_tracker@your.tracker.email.domain.example
372 Message-Id: <followup_dummy_id>
373 In-Reply-To: <dummy_test_message_id>
374 Subject: [issue1] Testing...
375 Content-Type: multipart/mixed; boundary="bxyzzy"
376 Content-Disposition: inline
379 --bxyzzy
380 Content-Type: multipart/alternative; boundary="bCsyhTFzCvuiizWE"
381 Content-Disposition: inline
383 --bCsyhTFzCvuiizWE
384 Content-Type: text/plain; charset=us-ascii
385 Content-Disposition: inline
387 test attachment first text/plain
389 --bCsyhTFzCvuiizWE
390 Content-Type: application/octet-stream
391 Content-Disposition: attachment; filename="first.dvi"
392 Content-Transfer-Encoding: base64
394 SnVzdCBhIHRlc3QgAQo=
396 --bCsyhTFzCvuiizWE
397 Content-Type: text/plain; charset=us-ascii
398 Content-Disposition: inline
400 test attachment second text/plain
402 --bCsyhTFzCvuiizWE
403 Content-Type: text/html
404 Content-Disposition: inline
406 <html>
407 to be ignored.
408 </html>
410 --bCsyhTFzCvuiizWE--
412 --bxyzzy
413 Content-Type: multipart/alternative; boundary="bCsyhTFzCvuiizWF"
414 Content-Disposition: inline
416 --bCsyhTFzCvuiizWF
417 Content-Type: text/plain; charset=us-ascii
418 Content-Disposition: inline
420 test attachment third text/plain
422 --bCsyhTFzCvuiizWF
423 Content-Type: application/octet-stream
424 Content-Disposition: attachment; filename="second.dvi"
425 Content-Transfer-Encoding: base64
427 SnVzdCBhIHRlc3QK
429 --bCsyhTFzCvuiizWF--
431 --bxyzzy--
432 '''
434 def testMultipartKeepAlternatives(self):
435 self.doNewIssue()
436 self._handle_mail(self.multipart_msg)
437 messages = self.db.issue.get('1', 'messages')
438 messages.sort()
439 msg = self.db.msg.getnode (messages[-1])
440 assert(len(msg.files) == 5)
441 names = {0 : 'first.dvi', 4 : 'second.dvi'}
442 content = {3 : 'test attachment third text/plain\n',
443 4 : 'Just a test\n'}
444 for n, id in enumerate (msg.files):
445 f = self.db.file.getnode (id)
446 self.assertEqual(f.name, names.get (n, 'unnamed'))
447 if n in content :
448 self.assertEqual(f.content, content [n])
449 self.assertEqual(msg.content, 'test attachment second text/plain')
451 def testMultipartDropAlternatives(self):
452 self.doNewIssue()
453 self.db.config.MAILGW_IGNORE_ALTERNATIVES = True
454 self._handle_mail(self.multipart_msg)
455 messages = self.db.issue.get('1', 'messages')
456 messages.sort()
457 msg = self.db.msg.getnode (messages[-1])
458 assert(len(msg.files) == 2)
459 names = {1 : 'second.dvi'}
460 content = {0 : 'test attachment third text/plain\n',
461 1 : 'Just a test\n'}
462 for n, id in enumerate (msg.files):
463 f = self.db.file.getnode (id)
464 self.assertEqual(f.name, names.get (n, 'unnamed'))
465 if n in content :
466 self.assertEqual(f.content, content [n])
467 self.assertEqual(msg.content, 'test attachment second text/plain')
469 def testSimpleFollowup(self):
470 self.doNewIssue()
471 self._handle_mail('''Content-Type: text/plain;
472 charset="iso-8859-1"
473 From: mary <mary@test.test>
474 To: issue_tracker@your.tracker.email.domain.example
475 Message-Id: <followup_dummy_id>
476 In-Reply-To: <dummy_test_message_id>
477 Subject: [issue1] Testing...
479 This is a second followup
480 ''')
481 self.compareMessages(self._get_mail(),
482 '''FROM: roundup-admin@your.tracker.email.domain.example
483 TO: chef@bork.bork.bork, richard@test.test
484 Content-Type: text/plain; charset="utf-8"
485 Subject: [issue1] Testing...
486 To: chef@bork.bork.bork, richard@test.test
487 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
488 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
489 MIME-Version: 1.0
490 Message-Id: <followup_dummy_id>
491 In-Reply-To: <dummy_test_message_id>
492 X-Roundup-Name: Roundup issue tracker
493 X-Roundup-Loop: hello
494 X-Roundup-Issue-Status: chatting
495 Content-Transfer-Encoding: quoted-printable
498 Contrary, Mary <mary@test.test> added the comment:
500 This is a second followup
502 ----------
503 status: unread -> chatting
505 _______________________________________________________________________
506 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
507 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
508 _______________________________________________________________________
509 ''')
511 def testFollowup(self):
512 self.doNewIssue()
514 self._handle_mail('''Content-Type: text/plain;
515 charset="iso-8859-1"
516 From: richard <richard@test.test>
517 To: issue_tracker@your.tracker.email.domain.example
518 Message-Id: <followup_dummy_id>
519 In-Reply-To: <dummy_test_message_id>
520 Subject: [issue1] Testing... [assignedto=mary; nosy=+john]
522 This is a followup
523 ''')
524 l = self.db.issue.get('1', 'nosy')
525 l.sort()
526 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
527 self.john_id])
529 self.compareMessages(self._get_mail(),
530 '''FROM: roundup-admin@your.tracker.email.domain.example
531 TO: chef@bork.bork.bork, john@test.test, mary@test.test
532 Content-Type: text/plain; charset="utf-8"
533 Subject: [issue1] Testing...
534 To: chef@bork.bork.bork, john@test.test, mary@test.test
535 From: richard <issue_tracker@your.tracker.email.domain.example>
536 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
537 MIME-Version: 1.0
538 Message-Id: <followup_dummy_id>
539 In-Reply-To: <dummy_test_message_id>
540 X-Roundup-Name: Roundup issue tracker
541 X-Roundup-Loop: hello
542 X-Roundup-Issue-Status: chatting
543 Content-Transfer-Encoding: quoted-printable
546 richard <richard@test.test> added the comment:
548 This is a followup
550 ----------
551 assignedto: -> mary
552 nosy: +john, mary
553 status: unread -> chatting
555 _______________________________________________________________________
556 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
557 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
558 _______________________________________________________________________
559 ''')
561 def testPropertyChangeOnly(self):
562 self.doNewIssue()
563 oldvalues = self.db.getnode('issue', '1').copy()
564 oldvalues['assignedto'] = None
565 # reconstruct old behaviour: This would reuse the
566 # database-handle from the doNewIssue above which has committed
567 # as user "Chef". So we close and reopen the db as that user.
568 self.db.close()
569 self.db = self.instance.open('Chef')
570 self.db.issue.set('1', assignedto=self.chef_id)
571 self.db.commit()
572 self.db.issue.nosymessage('1', None, oldvalues)
574 new_mail = ""
575 for line in self._get_mail().split("\n"):
576 if "Message-Id: " in line:
577 continue
578 if "Date: " in line:
579 continue
580 new_mail += line+"\n"
582 self.compareMessages(new_mail, """
583 FROM: roundup-admin@your.tracker.email.domain.example
584 TO: chef@bork.bork.bork, richard@test.test
585 Content-Type: text/plain; charset="utf-8"
586 Subject: [issue1] Testing...
587 To: chef@bork.bork.bork, richard@test.test
588 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
589 X-Roundup-Name: Roundup issue tracker
590 X-Roundup-Loop: hello
591 X-Roundup-Issue-Status: unread
592 X-Roundup-Version: 1.3.3
593 MIME-Version: 1.0
594 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
595 Content-Transfer-Encoding: quoted-printable
598 Change by Bork, Chef <chef@bork.bork.bork>:
601 ----------
602 assignedto: -> Chef
604 _______________________________________________________________________
605 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
606 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
607 _______________________________________________________________________
608 """)
611 #
612 # FOLLOWUP TITLE MATCH
613 #
614 def testFollowupTitleMatch(self):
615 self.doNewIssue()
616 self._handle_mail('''Content-Type: text/plain;
617 charset="iso-8859-1"
618 From: richard <richard@test.test>
619 To: issue_tracker@your.tracker.email.domain.example
620 Message-Id: <followup_dummy_id>
621 Subject: Re: Testing... [assignedto=mary; nosy=+john]
623 This is a followup
624 ''')
625 self.compareMessages(self._get_mail(),
626 '''FROM: roundup-admin@your.tracker.email.domain.example
627 TO: chef@bork.bork.bork, john@test.test, mary@test.test
628 Content-Type: text/plain; charset="utf-8"
629 Subject: [issue1] Testing...
630 To: chef@bork.bork.bork, john@test.test, mary@test.test
631 From: richard <issue_tracker@your.tracker.email.domain.example>
632 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
633 MIME-Version: 1.0
634 Message-Id: <followup_dummy_id>
635 In-Reply-To: <dummy_test_message_id>
636 X-Roundup-Name: Roundup issue tracker
637 X-Roundup-Loop: hello
638 X-Roundup-Issue-Status: chatting
639 Content-Transfer-Encoding: quoted-printable
642 richard <richard@test.test> added the comment:
644 This is a followup
646 ----------
647 assignedto: -> mary
648 nosy: +john, mary
649 status: unread -> chatting
651 _______________________________________________________________________
652 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
653 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
654 _______________________________________________________________________
655 ''')
657 def testFollowupTitleMatchMultiRe(self):
658 nodeid1 = self.doNewIssue()
659 nodeid2 = self._handle_mail('''Content-Type: text/plain;
660 charset="iso-8859-1"
661 From: richard <richard@test.test>
662 To: issue_tracker@your.tracker.email.domain.example
663 Message-Id: <followup_dummy_id>
664 Subject: Re: Testing... [assignedto=mary; nosy=+john]
666 This is a followup
667 ''')
669 nodeid3 = self._handle_mail('''Content-Type: text/plain;
670 charset="iso-8859-1"
671 From: richard <richard@test.test>
672 To: issue_tracker@your.tracker.email.domain.example
673 Message-Id: <followup2_dummy_id>
674 Subject: Ang: Re: Testing...
676 This is a followup
677 ''')
678 self.assertEqual(nodeid1, nodeid2)
679 self.assertEqual(nodeid1, nodeid3)
681 def testFollowupTitleMatchNever(self):
682 nodeid = self.doNewIssue()
683 self.db.config.MAILGW_SUBJECT_CONTENT_MATCH = 'never'
684 self.assertNotEqual(self._handle_mail('''Content-Type: text/plain;
685 charset="iso-8859-1"
686 From: richard <richard@test.test>
687 To: issue_tracker@your.tracker.email.domain.example
688 Message-Id: <followup_dummy_id>
689 Subject: Re: Testing...
691 This is a followup
692 '''), nodeid)
694 def testFollowupTitleMatchNeverInterval(self):
695 nodeid = self.doNewIssue()
696 # force failure of the interval
697 time.sleep(2)
698 self.db.config.MAILGW_SUBJECT_CONTENT_MATCH = 'creation 00:00:01'
699 self.assertNotEqual(self._handle_mail('''Content-Type: text/plain;
700 charset="iso-8859-1"
701 From: richard <richard@test.test>
702 To: issue_tracker@your.tracker.email.domain.example
703 Message-Id: <followup_dummy_id>
704 Subject: Re: Testing...
706 This is a followup
707 '''), nodeid)
710 def testFollowupTitleMatchInterval(self):
711 nodeid = self.doNewIssue()
712 self.db.config.MAILGW_SUBJECT_CONTENT_MATCH = 'creation +1d'
713 self.assertEqual(self._handle_mail('''Content-Type: text/plain;
714 charset="iso-8859-1"
715 From: richard <richard@test.test>
716 To: issue_tracker@your.tracker.email.domain.example
717 Message-Id: <followup_dummy_id>
718 Subject: Re: Testing...
720 This is a followup
721 '''), nodeid)
724 def testFollowupNosyAuthor(self):
725 self.doNewIssue()
726 self.db.config.ADD_AUTHOR_TO_NOSY = 'yes'
727 self._handle_mail('''Content-Type: text/plain;
728 charset="iso-8859-1"
729 From: john@test.test
730 To: issue_tracker@your.tracker.email.domain.example
731 Message-Id: <followup_dummy_id>
732 In-Reply-To: <dummy_test_message_id>
733 Subject: [issue1] Testing...
735 This is a followup
736 ''')
738 self.compareMessages(self._get_mail(),
739 '''FROM: roundup-admin@your.tracker.email.domain.example
740 TO: chef@bork.bork.bork, richard@test.test
741 Content-Type: text/plain; charset="utf-8"
742 Subject: [issue1] Testing...
743 To: chef@bork.bork.bork, richard@test.test
744 From: John Doe <issue_tracker@your.tracker.email.domain.example>
745 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
746 MIME-Version: 1.0
747 Message-Id: <followup_dummy_id>
748 In-Reply-To: <dummy_test_message_id>
749 X-Roundup-Name: Roundup issue tracker
750 X-Roundup-Loop: hello
751 X-Roundup-Issue-Status: chatting
752 Content-Transfer-Encoding: quoted-printable
755 John Doe <john@test.test> added the comment:
757 This is a followup
759 ----------
760 nosy: +john
761 status: unread -> chatting
763 _______________________________________________________________________
764 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
765 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
766 _______________________________________________________________________
768 ''')
770 def testFollowupNosyRecipients(self):
771 self.doNewIssue()
772 self.db.config.ADD_RECIPIENTS_TO_NOSY = 'yes'
773 self._handle_mail('''Content-Type: text/plain;
774 charset="iso-8859-1"
775 From: richard@test.test
776 To: issue_tracker@your.tracker.email.domain.example
777 Cc: john@test.test
778 Message-Id: <followup_dummy_id>
779 In-Reply-To: <dummy_test_message_id>
780 Subject: [issue1] Testing...
782 This is a followup
783 ''')
784 self.compareMessages(self._get_mail(),
785 '''FROM: roundup-admin@your.tracker.email.domain.example
786 TO: chef@bork.bork.bork
787 Content-Type: text/plain; charset="utf-8"
788 Subject: [issue1] Testing...
789 To: chef@bork.bork.bork
790 From: richard <issue_tracker@your.tracker.email.domain.example>
791 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
792 MIME-Version: 1.0
793 Message-Id: <followup_dummy_id>
794 In-Reply-To: <dummy_test_message_id>
795 X-Roundup-Name: Roundup issue tracker
796 X-Roundup-Loop: hello
797 X-Roundup-Issue-Status: chatting
798 Content-Transfer-Encoding: quoted-printable
801 richard <richard@test.test> added the comment:
803 This is a followup
805 ----------
806 nosy: +john
807 status: unread -> chatting
809 _______________________________________________________________________
810 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
811 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
812 _______________________________________________________________________
814 ''')
816 def testFollowupNosyAuthorAndCopy(self):
817 self.doNewIssue()
818 self.db.config.ADD_AUTHOR_TO_NOSY = 'yes'
819 self.db.config.MESSAGES_TO_AUTHOR = 'yes'
820 self._handle_mail('''Content-Type: text/plain;
821 charset="iso-8859-1"
822 From: john@test.test
823 To: issue_tracker@your.tracker.email.domain.example
824 Message-Id: <followup_dummy_id>
825 In-Reply-To: <dummy_test_message_id>
826 Subject: [issue1] Testing...
828 This is a followup
829 ''')
830 self.compareMessages(self._get_mail(),
831 '''FROM: roundup-admin@your.tracker.email.domain.example
832 TO: chef@bork.bork.bork, john@test.test, richard@test.test
833 Content-Type: text/plain; charset="utf-8"
834 Subject: [issue1] Testing...
835 To: chef@bork.bork.bork, john@test.test, richard@test.test
836 From: John Doe <issue_tracker@your.tracker.email.domain.example>
837 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
838 MIME-Version: 1.0
839 Message-Id: <followup_dummy_id>
840 In-Reply-To: <dummy_test_message_id>
841 X-Roundup-Name: Roundup issue tracker
842 X-Roundup-Loop: hello
843 X-Roundup-Issue-Status: chatting
844 Content-Transfer-Encoding: quoted-printable
847 John Doe <john@test.test> added the comment:
849 This is a followup
851 ----------
852 nosy: +john
853 status: unread -> chatting
855 _______________________________________________________________________
856 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
857 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
858 _______________________________________________________________________
860 ''')
862 def testFollowupNoNosyAuthor(self):
863 self.doNewIssue()
864 self.instance.config.ADD_AUTHOR_TO_NOSY = 'no'
865 self._handle_mail('''Content-Type: text/plain;
866 charset="iso-8859-1"
867 From: john@test.test
868 To: issue_tracker@your.tracker.email.domain.example
869 Message-Id: <followup_dummy_id>
870 In-Reply-To: <dummy_test_message_id>
871 Subject: [issue1] Testing...
873 This is a followup
874 ''')
875 self.compareMessages(self._get_mail(),
876 '''FROM: roundup-admin@your.tracker.email.domain.example
877 TO: chef@bork.bork.bork, richard@test.test
878 Content-Type: text/plain; charset="utf-8"
879 Subject: [issue1] Testing...
880 To: chef@bork.bork.bork, richard@test.test
881 From: John Doe <issue_tracker@your.tracker.email.domain.example>
882 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
883 MIME-Version: 1.0
884 Message-Id: <followup_dummy_id>
885 In-Reply-To: <dummy_test_message_id>
886 X-Roundup-Name: Roundup issue tracker
887 X-Roundup-Loop: hello
888 X-Roundup-Issue-Status: chatting
889 Content-Transfer-Encoding: quoted-printable
892 John Doe <john@test.test> added the comment:
894 This is a followup
896 ----------
897 status: unread -> chatting
899 _______________________________________________________________________
900 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
901 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
902 _______________________________________________________________________
904 ''')
906 def testFollowupNoNosyRecipients(self):
907 self.doNewIssue()
908 self.instance.config.ADD_RECIPIENTS_TO_NOSY = 'no'
909 self._handle_mail('''Content-Type: text/plain;
910 charset="iso-8859-1"
911 From: richard@test.test
912 To: issue_tracker@your.tracker.email.domain.example
913 Cc: john@test.test
914 Message-Id: <followup_dummy_id>
915 In-Reply-To: <dummy_test_message_id>
916 Subject: [issue1] Testing...
918 This is a followup
919 ''')
920 self.compareMessages(self._get_mail(),
921 '''FROM: roundup-admin@your.tracker.email.domain.example
922 TO: chef@bork.bork.bork
923 Content-Type: text/plain; charset="utf-8"
924 Subject: [issue1] Testing...
925 To: chef@bork.bork.bork
926 From: richard <issue_tracker@your.tracker.email.domain.example>
927 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
928 MIME-Version: 1.0
929 Message-Id: <followup_dummy_id>
930 In-Reply-To: <dummy_test_message_id>
931 X-Roundup-Name: Roundup issue tracker
932 X-Roundup-Loop: hello
933 X-Roundup-Issue-Status: chatting
934 Content-Transfer-Encoding: quoted-printable
937 richard <richard@test.test> added the comment:
939 This is a followup
941 ----------
942 status: unread -> chatting
944 _______________________________________________________________________
945 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
946 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
947 _______________________________________________________________________
949 ''')
951 def testFollowupEmptyMessage(self):
952 self.doNewIssue()
954 self._handle_mail('''Content-Type: text/plain;
955 charset="iso-8859-1"
956 From: richard <richard@test.test>
957 To: issue_tracker@your.tracker.email.domain.example
958 Message-Id: <followup_dummy_id>
959 In-Reply-To: <dummy_test_message_id>
960 Subject: [issue1] Testing... [assignedto=mary; nosy=+john]
962 ''')
963 l = self.db.issue.get('1', 'nosy')
964 l.sort()
965 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
966 self.john_id])
968 # should be no file created (ie. no message)
969 assert not os.path.exists(SENDMAILDEBUG)
971 def testFollowupEmptyMessageNoSubject(self):
972 self.doNewIssue()
974 self._handle_mail('''Content-Type: text/plain;
975 charset="iso-8859-1"
976 From: richard <richard@test.test>
977 To: issue_tracker@your.tracker.email.domain.example
978 Message-Id: <followup_dummy_id>
979 In-Reply-To: <dummy_test_message_id>
980 Subject: [issue1] [assignedto=mary; nosy=+john]
982 ''')
983 l = self.db.issue.get('1', 'nosy')
984 l.sort()
985 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
986 self.john_id])
988 # should be no file created (ie. no message)
989 assert not os.path.exists(SENDMAILDEBUG)
991 def testNosyRemove(self):
992 self.doNewIssue()
994 self._handle_mail('''Content-Type: text/plain;
995 charset="iso-8859-1"
996 From: richard <richard@test.test>
997 To: issue_tracker@your.tracker.email.domain.example
998 Message-Id: <followup_dummy_id>
999 In-Reply-To: <dummy_test_message_id>
1000 Subject: [issue1] Testing... [nosy=-richard]
1002 ''')
1003 l = self.db.issue.get('1', 'nosy')
1004 l.sort()
1005 self.assertEqual(l, [self.chef_id])
1007 # NO NOSY MESSAGE SHOULD BE SENT!
1008 assert not os.path.exists(SENDMAILDEBUG)
1010 def testNewUserAuthor(self):
1012 l = self.db.user.list()
1013 l.sort()
1014 message = '''Content-Type: text/plain;
1015 charset="iso-8859-1"
1016 From: fubar <fubar@bork.bork.bork>
1017 To: issue_tracker@your.tracker.email.domain.example
1018 Message-Id: <dummy_test_message_id>
1019 Subject: [issue] Testing...
1021 This is a test submission of a new issue.
1022 '''
1023 def hook (db, **kw):
1024 ''' set up callback for db open '''
1025 db.security.role['anonymous'].permissions=[]
1026 anonid = db.user.lookup('anonymous')
1027 db.user.set(anonid, roles='Anonymous')
1028 self.instance.schema_hook = hook
1029 try:
1030 self._handle_mail(message)
1031 except Unauthorized, value:
1032 body_diff = self.compareMessages(str(value), """
1033 You are not a registered user.
1035 Unknown address: fubar@bork.bork.bork
1036 """)
1038 assert not body_diff, body_diff
1040 else:
1041 raise AssertionError, "Unathorized not raised when handling mail"
1044 def hook (db, **kw):
1045 ''' set up callback for db open '''
1046 # Add Web Access role to anonymous, and try again to make sure
1047 # we get a "please register at:" message this time.
1048 p = [
1049 db.security.getPermission('Register', 'user'),
1050 db.security.getPermission('Web Access', None),
1051 ]
1052 db.security.role['anonymous'].permissions=p
1053 self.instance.schema_hook = hook
1054 try:
1055 self._handle_mail(message)
1056 except Unauthorized, value:
1057 body_diff = self.compareMessages(str(value), """
1058 You are not a registered user. Please register at:
1060 http://tracker.example/cgi-bin/roundup.cgi/bugs/user?template=register
1062 ...before sending mail to the tracker.
1064 Unknown address: fubar@bork.bork.bork
1065 """)
1067 assert not body_diff, body_diff
1069 else:
1070 raise AssertionError, "Unathorized not raised when handling mail"
1072 # Make sure list of users is the same as before.
1073 m = self.db.user.list()
1074 m.sort()
1075 self.assertEqual(l, m)
1077 def hook (db, **kw):
1078 ''' set up callback for db open '''
1079 # now with the permission
1080 p = [
1081 db.security.getPermission('Register', 'user'),
1082 db.security.getPermission('Email Access', None),
1083 ]
1084 db.security.role['anonymous'].permissions=p
1085 self.instance.schema_hook = hook
1086 self._handle_mail(message)
1087 m = self.db.user.list()
1088 m.sort()
1089 self.assertNotEqual(l, m)
1091 def testNewUserAuthorEncodedName(self):
1092 l = set(self.db.user.list())
1093 # From: name has Euro symbol in it
1094 message = '''Content-Type: text/plain;
1095 charset="iso-8859-1"
1096 From: =?utf8?b?SOKCrGxsbw==?= <fubar@bork.bork.bork>
1097 To: issue_tracker@your.tracker.email.domain.example
1098 Message-Id: <dummy_test_message_id>
1099 Subject: [issue] Testing...
1101 This is a test submission of a new issue.
1102 '''
1103 def hook (db, **kw):
1104 ''' set up callback for db open '''
1105 p = [
1106 db.security.getPermission('Register', 'user'),
1107 db.security.getPermission('Email Access', None),
1108 db.security.getPermission('Create', 'issue'),
1109 db.security.getPermission('Create', 'msg'),
1110 ]
1111 db.security.role['anonymous'].permissions = p
1112 self.instance.schema_hook = hook
1113 self._handle_mail(message)
1114 m = set(self.db.user.list())
1115 new = list(m - l)[0]
1116 name = self.db.user.get(new, 'realname')
1117 self.assertEquals(name, 'H€llo')
1119 def testUnknownUser(self):
1120 l = set(self.db.user.list())
1121 message = '''Content-Type: text/plain;
1122 charset="iso-8859-1"
1123 From: Nonexisting User <nonexisting@bork.bork.bork>
1124 To: issue_tracker@your.tracker.email.domain.example
1125 Message-Id: <dummy_test_message_id>
1126 Subject: [issue] Testing nonexisting user...
1128 This is a test submission of a new issue.
1129 '''
1130 self.db.close()
1131 handler = self.instance.MailGW(self.instance)
1132 # we want a bounce message:
1133 handler.trapExceptions = 1
1134 ret = handler.main(StringIO(message))
1135 self.compareMessages(self._get_mail(),
1136 '''FROM: Roundup issue tracker <roundup-admin@your.tracker.email.domain.example>
1137 TO: nonexisting@bork.bork.bork
1138 From nobody Tue Jul 14 12:04:11 2009
1139 Content-Type: multipart/mixed; boundary="===============0639262320=="
1140 MIME-Version: 1.0
1141 Subject: Failed issue tracker submission
1142 To: nonexisting@bork.bork.bork
1143 From: Roundup issue tracker <roundup-admin@your.tracker.email.domain.example>
1144 Date: Tue, 14 Jul 2009 12:04:11 +0000
1145 Precedence: bulk
1146 X-Roundup-Name: Roundup issue tracker
1147 X-Roundup-Loop: hello
1148 X-Roundup-Version: 1.4.8
1149 MIME-Version: 1.0
1151 --===============0639262320==
1152 Content-Type: text/plain; charset="us-ascii"
1153 MIME-Version: 1.0
1154 Content-Transfer-Encoding: 7bit
1158 You are not a registered user. Please register at:
1160 http://tracker.example/cgi-bin/roundup.cgi/bugs/user?template=register
1162 ...before sending mail to the tracker.
1164 Unknown address: nonexisting@bork.bork.bork
1166 --===============0639262320==
1167 Content-Type: text/plain; charset="us-ascii"
1168 MIME-Version: 1.0
1169 Content-Transfer-Encoding: 7bit
1171 Content-Type: text/plain;
1172 charset="iso-8859-1"
1173 From: Nonexisting User <nonexisting@bork.bork.bork>
1174 To: issue_tracker@your.tracker.email.domain.example
1175 Message-Id: <dummy_test_message_id>
1176 Subject: [issue] Testing nonexisting user...
1178 This is a test submission of a new issue.
1180 --===============0639262320==--
1181 ''')
1183 def testEnc01(self):
1184 self.doNewIssue()
1185 self._handle_mail('''Content-Type: text/plain;
1186 charset="iso-8859-1"
1187 From: mary <mary@test.test>
1188 To: issue_tracker@your.tracker.email.domain.example
1189 Message-Id: <followup_dummy_id>
1190 In-Reply-To: <dummy_test_message_id>
1191 Subject: [issue1] Testing...
1192 Content-Type: text/plain;
1193 charset="iso-8859-1"
1194 Content-Transfer-Encoding: quoted-printable
1196 A message with encoding (encoded oe =F6)
1198 ''')
1199 self.compareMessages(self._get_mail(),
1200 '''FROM: roundup-admin@your.tracker.email.domain.example
1201 TO: chef@bork.bork.bork, richard@test.test
1202 Content-Type: text/plain; charset="utf-8"
1203 Subject: [issue1] Testing...
1204 To: chef@bork.bork.bork, richard@test.test
1205 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
1206 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1207 MIME-Version: 1.0
1208 Message-Id: <followup_dummy_id>
1209 In-Reply-To: <dummy_test_message_id>
1210 X-Roundup-Name: Roundup issue tracker
1211 X-Roundup-Loop: hello
1212 X-Roundup-Issue-Status: chatting
1213 Content-Transfer-Encoding: quoted-printable
1216 Contrary, Mary <mary@test.test> added the comment:
1218 A message with encoding (encoded oe =C3=B6)
1220 ----------
1221 status: unread -> chatting
1223 _______________________________________________________________________
1224 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1225 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1226 _______________________________________________________________________
1227 ''')
1229 def testEncNonUTF8(self):
1230 self.doNewIssue()
1231 self.instance.config.EMAIL_CHARSET = 'iso-8859-1'
1232 self._handle_mail('''Content-Type: text/plain;
1233 charset="iso-8859-1"
1234 From: mary <mary@test.test>
1235 To: issue_tracker@your.tracker.email.domain.example
1236 Message-Id: <followup_dummy_id>
1237 In-Reply-To: <dummy_test_message_id>
1238 Subject: [issue1] Testing...
1239 Content-Type: text/plain;
1240 charset="iso-8859-1"
1241 Content-Transfer-Encoding: quoted-printable
1243 A message with encoding (encoded oe =F6)
1245 ''')
1246 self.compareMessages(self._get_mail(),
1247 '''FROM: roundup-admin@your.tracker.email.domain.example
1248 TO: chef@bork.bork.bork, richard@test.test
1249 Content-Type: text/plain; charset="iso-8859-1"
1250 Subject: [issue1] Testing...
1251 To: chef@bork.bork.bork, richard@test.test
1252 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
1253 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1254 MIME-Version: 1.0
1255 Message-Id: <followup_dummy_id>
1256 In-Reply-To: <dummy_test_message_id>
1257 X-Roundup-Name: Roundup issue tracker
1258 X-Roundup-Loop: hello
1259 X-Roundup-Issue-Status: chatting
1260 Content-Transfer-Encoding: quoted-printable
1263 Contrary, Mary <mary@test.test> added the comment:
1265 A message with encoding (encoded oe =F6)
1267 ----------
1268 status: unread -> chatting
1270 _______________________________________________________________________
1271 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1272 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1273 _______________________________________________________________________
1274 ''')
1277 def testMultipartEnc01(self):
1278 self.doNewIssue()
1279 self._handle_mail('''Content-Type: text/plain;
1280 charset="iso-8859-1"
1281 From: mary <mary@test.test>
1282 To: issue_tracker@your.tracker.email.domain.example
1283 Message-Id: <followup_dummy_id>
1284 In-Reply-To: <dummy_test_message_id>
1285 Subject: [issue1] Testing...
1286 Content-Type: multipart/mixed;
1287 boundary="----_=_NextPart_000_01"
1289 This message is in MIME format. Since your mail reader does not understand
1290 this format, some or all of this message may not be legible.
1292 ------_=_NextPart_000_01
1293 Content-Type: text/plain;
1294 charset="iso-8859-1"
1295 Content-Transfer-Encoding: quoted-printable
1297 A message with first part encoded (encoded oe =F6)
1299 ''')
1300 self.compareMessages(self._get_mail(),
1301 '''FROM: roundup-admin@your.tracker.email.domain.example
1302 TO: chef@bork.bork.bork, richard@test.test
1303 Content-Type: text/plain; charset="utf-8"
1304 Subject: [issue1] Testing...
1305 To: chef@bork.bork.bork, richard@test.test
1306 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
1307 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1308 MIME-Version: 1.0
1309 Message-Id: <followup_dummy_id>
1310 In-Reply-To: <dummy_test_message_id>
1311 X-Roundup-Name: Roundup issue tracker
1312 X-Roundup-Loop: hello
1313 X-Roundup-Issue-Status: chatting
1314 Content-Transfer-Encoding: quoted-printable
1317 Contrary, Mary <mary@test.test> added the comment:
1319 A message with first part encoded (encoded oe =C3=B6)
1321 ----------
1322 status: unread -> chatting
1324 _______________________________________________________________________
1325 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1326 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1327 _______________________________________________________________________
1328 ''')
1330 def testContentDisposition(self):
1331 self.doNewIssue()
1332 self._handle_mail('''Content-Type: text/plain;
1333 charset="iso-8859-1"
1334 From: mary <mary@test.test>
1335 To: issue_tracker@your.tracker.email.domain.example
1336 Message-Id: <followup_dummy_id>
1337 In-Reply-To: <dummy_test_message_id>
1338 Subject: [issue1] Testing...
1339 Content-Type: multipart/mixed; boundary="bCsyhTFzCvuiizWE"
1340 Content-Disposition: inline
1343 --bCsyhTFzCvuiizWE
1344 Content-Type: text/plain; charset=us-ascii
1345 Content-Disposition: inline
1347 test attachment binary
1349 --bCsyhTFzCvuiizWE
1350 Content-Type: application/octet-stream
1351 Content-Disposition: attachment; filename="main.dvi"
1352 Content-Transfer-Encoding: base64
1354 SnVzdCBhIHRlc3QgAQo=
1356 --bCsyhTFzCvuiizWE--
1357 ''')
1358 messages = self.db.issue.get('1', 'messages')
1359 messages.sort()
1360 file = self.db.file.getnode (self.db.msg.get(messages[-1], 'files')[0])
1361 self.assertEqual(file.name, 'main.dvi')
1362 self.assertEqual(file.content, 'Just a test \001\n')
1364 def testFollowupStupidQuoting(self):
1365 self.doNewIssue()
1367 self._handle_mail('''Content-Type: text/plain;
1368 charset="iso-8859-1"
1369 From: richard <richard@test.test>
1370 To: issue_tracker@your.tracker.email.domain.example
1371 Message-Id: <followup_dummy_id>
1372 In-Reply-To: <dummy_test_message_id>
1373 Subject: Re: "[issue1] Testing... "
1375 This is a followup
1376 ''')
1377 self.compareMessages(self._get_mail(),
1378 '''FROM: roundup-admin@your.tracker.email.domain.example
1379 TO: chef@bork.bork.bork
1380 Content-Type: text/plain; charset="utf-8"
1381 Subject: [issue1] Testing...
1382 To: chef@bork.bork.bork
1383 From: richard <issue_tracker@your.tracker.email.domain.example>
1384 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1385 MIME-Version: 1.0
1386 Message-Id: <followup_dummy_id>
1387 In-Reply-To: <dummy_test_message_id>
1388 X-Roundup-Name: Roundup issue tracker
1389 X-Roundup-Loop: hello
1390 X-Roundup-Issue-Status: chatting
1391 Content-Transfer-Encoding: quoted-printable
1394 richard <richard@test.test> added the comment:
1396 This is a followup
1398 ----------
1399 status: unread -> chatting
1401 _______________________________________________________________________
1402 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1403 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1404 _______________________________________________________________________
1405 ''')
1407 def testEmailQuoting(self):
1408 self.instance.config.EMAIL_KEEP_QUOTED_TEXT = 'no'
1409 self.innerTestQuoting('''This is a followup
1410 ''')
1412 def testEmailQuotingRemove(self):
1413 self.instance.config.EMAIL_KEEP_QUOTED_TEXT = 'yes'
1414 self.innerTestQuoting('''Blah blah wrote:
1415 > Blah bklaskdfj sdf asdf jlaskdf skj sdkfjl asdf
1416 > skdjlkjsdfalsdkfjasdlfkj dlfksdfalksd fj
1417 >
1419 This is a followup
1420 ''')
1422 def innerTestQuoting(self, expect):
1423 nodeid = self.doNewIssue()
1425 messages = self.db.issue.get(nodeid, 'messages')
1427 self._handle_mail('''Content-Type: text/plain;
1428 charset="iso-8859-1"
1429 From: richard <richard@test.test>
1430 To: issue_tracker@your.tracker.email.domain.example
1431 Message-Id: <followup_dummy_id>
1432 In-Reply-To: <dummy_test_message_id>
1433 Subject: Re: [issue1] Testing...
1435 Blah blah wrote:
1436 > Blah bklaskdfj sdf asdf jlaskdf skj sdkfjl asdf
1437 > skdjlkjsdfalsdkfjasdlfkj dlfksdfalksd fj
1438 >
1440 This is a followup
1441 ''')
1442 # figure the new message id
1443 newmessages = self.db.issue.get(nodeid, 'messages')
1444 for msg in messages:
1445 newmessages.remove(msg)
1446 messageid = newmessages[0]
1448 self.compareMessages(self.db.msg.get(messageid, 'content'), expect)
1450 def testUserLookup(self):
1451 i = self.db.user.create(username='user1', address='user1@foo.com')
1452 self.assertEqual(uidFromAddress(self.db, ('', 'user1@foo.com'), 0), i)
1453 self.assertEqual(uidFromAddress(self.db, ('', 'USER1@foo.com'), 0), i)
1454 i = self.db.user.create(username='user2', address='USER2@foo.com')
1455 self.assertEqual(uidFromAddress(self.db, ('', 'USER2@foo.com'), 0), i)
1456 self.assertEqual(uidFromAddress(self.db, ('', 'user2@foo.com'), 0), i)
1458 def testUserAlternateLookup(self):
1459 i = self.db.user.create(username='user1', address='user1@foo.com',
1460 alternate_addresses='user1@bar.com')
1461 self.assertEqual(uidFromAddress(self.db, ('', 'user1@bar.com'), 0), i)
1462 self.assertEqual(uidFromAddress(self.db, ('', 'USER1@bar.com'), 0), i)
1464 def testUserCreate(self):
1465 i = uidFromAddress(self.db, ('', 'user@foo.com'), 1)
1466 self.assertNotEqual(uidFromAddress(self.db, ('', 'user@bar.com'), 1), i)
1468 def testRFC2822(self):
1469 ascii_header = "[issue243] This is a \"test\" - with 'quotation' marks"
1470 unicode_header = '[issue244] \xd0\xb0\xd0\xbd\xd0\xb4\xd1\x80\xd0\xb5\xd0\xb9'
1471 unicode_encoded = '=?utf-8?q?[issue244]_=D0=B0=D0=BD=D0=B4=D1=80=D0=B5=D0=B9?='
1472 self.assertEqual(rfc2822.encode_header(ascii_header), ascii_header)
1473 self.assertEqual(rfc2822.encode_header(unicode_header), unicode_encoded)
1475 def testRegistrationConfirmation(self):
1476 otk = "Aj4euk4LZSAdwePohj90SME5SpopLETL"
1477 self.db.getOTKManager().set(otk, username='johannes')
1478 self._handle_mail('''Content-Type: text/plain;
1479 charset="iso-8859-1"
1480 From: Chef <chef@bork.bork.bork>
1481 To: issue_tracker@your.tracker.email.domain.example
1482 Cc: richard@test.test
1483 Message-Id: <dummy_test_message_id>
1484 Subject: Re: Complete your registration to Roundup issue tracker
1485 -- key %s
1487 This is a test confirmation of registration.
1488 ''' % otk)
1489 self.db.user.lookup('johannes')
1491 def testFollowupOnNonIssue(self):
1492 self.db.keyword.create(name='Foo')
1493 self._handle_mail('''Content-Type: text/plain;
1494 charset="iso-8859-1"
1495 From: richard <richard@test.test>
1496 To: issue_tracker@your.tracker.email.domain.example
1497 Message-Id: <followup_dummy_id>
1498 In-Reply-To: <dummy_test_message_id>
1499 Subject: [keyword1] Testing... [name=Bar]
1501 ''')
1502 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1504 def testResentFrom(self):
1505 nodeid = self._handle_mail('''Content-Type: text/plain;
1506 charset="iso-8859-1"
1507 From: Chef <chef@bork.bork.bork>
1508 Resent-From: mary <mary@test.test>
1509 To: issue_tracker@your.tracker.email.domain.example
1510 Cc: richard@test.test
1511 Message-Id: <dummy_test_message_id>
1512 Subject: [issue] Testing...
1514 This is a test submission of a new issue.
1515 ''')
1516 assert not os.path.exists(SENDMAILDEBUG)
1517 l = self.db.issue.get(nodeid, 'nosy')
1518 l.sort()
1519 self.assertEqual(l, [self.richard_id, self.mary_id])
1520 return nodeid
1522 def testDejaVu(self):
1523 self.assertRaises(IgnoreLoop, self._handle_mail,
1524 '''Content-Type: text/plain;
1525 charset="iso-8859-1"
1526 From: Chef <chef@bork.bork.bork>
1527 X-Roundup-Loop: hello
1528 To: issue_tracker@your.tracker.email.domain.example
1529 Cc: richard@test.test
1530 Message-Id: <dummy_test_message_id>
1531 Subject: Re: [issue] Testing...
1533 Hi, I've been mis-configured to loop messages back to myself.
1534 ''')
1536 def testItsBulkStupid(self):
1537 self.assertRaises(IgnoreBulk, self._handle_mail,
1538 '''Content-Type: text/plain;
1539 charset="iso-8859-1"
1540 From: Chef <chef@bork.bork.bork>
1541 Precedence: bulk
1542 To: issue_tracker@your.tracker.email.domain.example
1543 Cc: richard@test.test
1544 Message-Id: <dummy_test_message_id>
1545 Subject: Re: [issue] Testing...
1547 Hi, I'm on holidays, and this is a dumb auto-responder.
1548 ''')
1550 def testAutoReplyEmailsAreIgnored(self):
1551 self.assertRaises(IgnoreBulk, self._handle_mail,
1552 '''Content-Type: text/plain;
1553 charset="iso-8859-1"
1554 From: Chef <chef@bork.bork.bork>
1555 To: issue_tracker@your.tracker.email.domain.example
1556 Cc: richard@test.test
1557 Message-Id: <dummy_test_message_id>
1558 Subject: Re: [issue] Out of office AutoReply: Back next week
1560 Hi, I am back in the office next week
1561 ''')
1563 def testNoSubject(self):
1564 self.assertRaises(MailUsageError, self._handle_mail,
1565 '''Content-Type: text/plain;
1566 charset="iso-8859-1"
1567 From: Chef <chef@bork.bork.bork>
1568 To: issue_tracker@your.tracker.email.domain.example
1569 Cc: richard@test.test
1570 Reply-To: chef@bork.bork.bork
1571 Message-Id: <dummy_test_message_id>
1573 ''')
1575 #
1576 # TEST FOR INVALID DESIGNATOR HANDLING
1577 #
1578 def testInvalidDesignator(self):
1579 self.assertRaises(MailUsageError, self._handle_mail,
1580 '''Content-Type: text/plain;
1581 charset="iso-8859-1"
1582 From: Chef <chef@bork.bork.bork>
1583 To: issue_tracker@your.tracker.email.domain.example
1584 Subject: [frobulated] testing
1585 Cc: richard@test.test
1586 Reply-To: chef@bork.bork.bork
1587 Message-Id: <dummy_test_message_id>
1589 ''')
1590 self.assertRaises(MailUsageError, self._handle_mail,
1591 '''Content-Type: text/plain;
1592 charset="iso-8859-1"
1593 From: Chef <chef@bork.bork.bork>
1594 To: issue_tracker@your.tracker.email.domain.example
1595 Subject: [issue12345] testing
1596 Cc: richard@test.test
1597 Reply-To: chef@bork.bork.bork
1598 Message-Id: <dummy_test_message_id>
1600 ''')
1602 def testInvalidClassLoose(self):
1603 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1604 nodeid = self._handle_mail('''Content-Type: text/plain;
1605 charset="iso-8859-1"
1606 From: Chef <chef@bork.bork.bork>
1607 To: issue_tracker@your.tracker.email.domain.example
1608 Subject: [frobulated] testing
1609 Cc: richard@test.test
1610 Reply-To: chef@bork.bork.bork
1611 Message-Id: <dummy_test_message_id>
1613 ''')
1614 assert not os.path.exists(SENDMAILDEBUG)
1615 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1616 '[frobulated] testing')
1618 def testInvalidClassLooseReply(self):
1619 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1620 nodeid = self._handle_mail('''Content-Type: text/plain;
1621 charset="iso-8859-1"
1622 From: Chef <chef@bork.bork.bork>
1623 To: issue_tracker@your.tracker.email.domain.example
1624 Subject: Re: [frobulated] testing
1625 Cc: richard@test.test
1626 Reply-To: chef@bork.bork.bork
1627 Message-Id: <dummy_test_message_id>
1629 ''')
1630 assert not os.path.exists(SENDMAILDEBUG)
1631 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1632 '[frobulated] testing')
1634 def testInvalidClassLoose(self):
1635 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1636 nodeid = self._handle_mail('''Content-Type: text/plain;
1637 charset="iso-8859-1"
1638 From: Chef <chef@bork.bork.bork>
1639 To: issue_tracker@your.tracker.email.domain.example
1640 Subject: [issue1234] testing
1641 Cc: richard@test.test
1642 Reply-To: chef@bork.bork.bork
1643 Message-Id: <dummy_test_message_id>
1645 ''')
1646 assert not os.path.exists(SENDMAILDEBUG)
1647 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1648 '[issue1234] testing')
1650 def testClassLooseOK(self):
1651 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1652 self.db.keyword.create(name='Foo')
1653 nodeid = self._handle_mail('''Content-Type: text/plain;
1654 charset="iso-8859-1"
1655 From: Chef <chef@bork.bork.bork>
1656 To: issue_tracker@your.tracker.email.domain.example
1657 Subject: [keyword1] Testing... [name=Bar]
1658 Cc: richard@test.test
1659 Reply-To: chef@bork.bork.bork
1660 Message-Id: <dummy_test_message_id>
1662 ''')
1663 assert not os.path.exists(SENDMAILDEBUG)
1664 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1666 def testClassStrictInvalid(self):
1667 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'strict'
1668 self.instance.config.MAILGW_DEFAULT_CLASS = ''
1670 message = '''Content-Type: text/plain;
1671 charset="iso-8859-1"
1672 From: Chef <chef@bork.bork.bork>
1673 To: issue_tracker@your.tracker.email.domain.example
1674 Subject: Testing...
1675 Cc: richard@test.test
1676 Reply-To: chef@bork.bork.bork
1677 Message-Id: <dummy_test_message_id>
1679 '''
1680 self.assertRaises(MailUsageError, self._handle_mail, message)
1682 def testClassStrictValid(self):
1683 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'strict'
1684 self.instance.config.MAILGW_DEFAULT_CLASS = ''
1686 nodeid = self._handle_mail('''Content-Type: text/plain;
1687 charset="iso-8859-1"
1688 From: Chef <chef@bork.bork.bork>
1689 To: issue_tracker@your.tracker.email.domain.example
1690 Subject: [issue] Testing...
1691 Cc: richard@test.test
1692 Reply-To: chef@bork.bork.bork
1693 Message-Id: <dummy_test_message_id>
1695 ''')
1697 assert not os.path.exists(SENDMAILDEBUG)
1698 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'Testing...')
1700 #
1701 # TEST FOR INVALID COMMANDS HANDLING
1702 #
1703 def testInvalidCommands(self):
1704 self.assertRaises(MailUsageError, self._handle_mail,
1705 '''Content-Type: text/plain;
1706 charset="iso-8859-1"
1707 From: Chef <chef@bork.bork.bork>
1708 To: issue_tracker@your.tracker.email.domain.example
1709 Subject: testing [frobulated]
1710 Cc: richard@test.test
1711 Reply-To: chef@bork.bork.bork
1712 Message-Id: <dummy_test_message_id>
1714 ''')
1716 def testInvalidCommandPassthrough(self):
1717 self.instance.config.MAILGW_SUBJECT_SUFFIX_PARSING = 'none'
1718 nodeid = self._handle_mail('''Content-Type: text/plain;
1719 charset="iso-8859-1"
1720 From: Chef <chef@bork.bork.bork>
1721 To: issue_tracker@your.tracker.email.domain.example
1722 Subject: testing [frobulated]
1723 Cc: richard@test.test
1724 Reply-To: chef@bork.bork.bork
1725 Message-Id: <dummy_test_message_id>
1727 ''')
1728 assert not os.path.exists(SENDMAILDEBUG)
1729 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1730 'testing [frobulated]')
1732 def testInvalidCommandPassthroughLoose(self):
1733 self.instance.config.MAILGW_SUBJECT_SUFFIX_PARSING = 'loose'
1734 nodeid = self._handle_mail('''Content-Type: text/plain;
1735 charset="iso-8859-1"
1736 From: Chef <chef@bork.bork.bork>
1737 To: issue_tracker@your.tracker.email.domain.example
1738 Subject: testing [frobulated]
1739 Cc: richard@test.test
1740 Reply-To: chef@bork.bork.bork
1741 Message-Id: <dummy_test_message_id>
1743 ''')
1744 assert not os.path.exists(SENDMAILDEBUG)
1745 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1746 'testing [frobulated]')
1748 def testInvalidCommandPassthroughLooseOK(self):
1749 self.instance.config.MAILGW_SUBJECT_SUFFIX_PARSING = 'loose'
1750 nodeid = self._handle_mail('''Content-Type: text/plain;
1751 charset="iso-8859-1"
1752 From: Chef <chef@bork.bork.bork>
1753 To: issue_tracker@your.tracker.email.domain.example
1754 Subject: testing [assignedto=mary]
1755 Cc: richard@test.test
1756 Reply-To: chef@bork.bork.bork
1757 Message-Id: <dummy_test_message_id>
1759 ''')
1760 assert not os.path.exists(SENDMAILDEBUG)
1761 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'testing')
1762 self.assertEqual(self.db.issue.get(nodeid, 'assignedto'), self.mary_id)
1764 def testCommandDelimiters(self):
1765 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '{}'
1766 nodeid = self._handle_mail('''Content-Type: text/plain;
1767 charset="iso-8859-1"
1768 From: Chef <chef@bork.bork.bork>
1769 To: issue_tracker@your.tracker.email.domain.example
1770 Subject: testing {assignedto=mary}
1771 Cc: richard@test.test
1772 Reply-To: chef@bork.bork.bork
1773 Message-Id: <dummy_test_message_id>
1775 ''')
1776 assert not os.path.exists(SENDMAILDEBUG)
1777 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'testing')
1778 self.assertEqual(self.db.issue.get(nodeid, 'assignedto'), self.mary_id)
1780 def testPrefixDelimiters(self):
1781 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '{}'
1782 self.db.keyword.create(name='Foo')
1783 self._handle_mail('''Content-Type: text/plain;
1784 charset="iso-8859-1"
1785 From: richard <richard@test.test>
1786 To: issue_tracker@your.tracker.email.domain.example
1787 Message-Id: <followup_dummy_id>
1788 In-Reply-To: <dummy_test_message_id>
1789 Subject: {keyword1} Testing... {name=Bar}
1791 ''')
1792 assert not os.path.exists(SENDMAILDEBUG)
1793 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1795 def testCommandDelimitersIgnore(self):
1796 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '{}'
1797 nodeid = self._handle_mail('''Content-Type: text/plain;
1798 charset="iso-8859-1"
1799 From: Chef <chef@bork.bork.bork>
1800 To: issue_tracker@your.tracker.email.domain.example
1801 Subject: testing [assignedto=mary]
1802 Cc: richard@test.test
1803 Reply-To: chef@bork.bork.bork
1804 Message-Id: <dummy_test_message_id>
1806 ''')
1807 assert not os.path.exists(SENDMAILDEBUG)
1808 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1809 'testing [assignedto=mary]')
1810 self.assertEqual(self.db.issue.get(nodeid, 'assignedto'), None)
1812 def testReplytoMatch(self):
1813 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1814 nodeid = self.doNewIssue()
1815 nodeid2 = self._handle_mail('''Content-Type: text/plain;
1816 charset="iso-8859-1"
1817 From: Chef <chef@bork.bork.bork>
1818 To: issue_tracker@your.tracker.email.domain.example
1819 Message-Id: <dummy_test_message_id2>
1820 In-Reply-To: <dummy_test_message_id>
1821 Subject: Testing...
1823 Followup message.
1824 ''')
1826 nodeid3 = self._handle_mail('''Content-Type: text/plain;
1827 charset="iso-8859-1"
1828 From: Chef <chef@bork.bork.bork>
1829 To: issue_tracker@your.tracker.email.domain.example
1830 Message-Id: <dummy_test_message_id3>
1831 In-Reply-To: <dummy_test_message_id2>
1832 Subject: Testing...
1834 Yet another message in the same thread/issue.
1835 ''')
1837 self.assertEqual(nodeid, nodeid2)
1838 self.assertEqual(nodeid, nodeid3)
1840 def testHelpSubject(self):
1841 message = '''Content-Type: text/plain;
1842 charset="iso-8859-1"
1843 From: Chef <chef@bork.bork.bork>
1844 To: issue_tracker@your.tracker.email.domain.example
1845 Message-Id: <dummy_test_message_id2>
1846 In-Reply-To: <dummy_test_message_id>
1847 Subject: hElp
1850 '''
1851 self.assertRaises(MailUsageHelp, self._handle_mail, message)
1853 def testMaillistSubject(self):
1854 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '[]'
1855 self.db.keyword.create(name='Foo')
1856 self._handle_mail('''Content-Type: text/plain;
1857 charset="iso-8859-1"
1858 From: Chef <chef@bork.bork.bork>
1859 To: issue_tracker@your.tracker.email.domain.example
1860 Subject: [mailinglist-name] [keyword1] Testing.. [name=Bar]
1861 Cc: richard@test.test
1862 Reply-To: chef@bork.bork.bork
1863 Message-Id: <dummy_test_message_id>
1865 ''')
1867 assert not os.path.exists(SENDMAILDEBUG)
1868 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1870 def testUnknownPrefixSubject(self):
1871 self.db.keyword.create(name='Foo')
1872 self._handle_mail('''Content-Type: text/plain;
1873 charset="iso-8859-1"
1874 From: Chef <chef@bork.bork.bork>
1875 To: issue_tracker@your.tracker.email.domain.example
1876 Subject: VeryStrangeRe: [keyword1] Testing.. [name=Bar]
1877 Cc: richard@test.test
1878 Reply-To: chef@bork.bork.bork
1879 Message-Id: <dummy_test_message_id>
1881 ''')
1883 assert not os.path.exists(SENDMAILDEBUG)
1884 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1886 def testIssueidLast(self):
1887 nodeid1 = self.doNewIssue()
1888 nodeid2 = self._handle_mail('''Content-Type: text/plain;
1889 charset="iso-8859-1"
1890 From: mary <mary@test.test>
1891 To: issue_tracker@your.tracker.email.domain.example
1892 Message-Id: <followup_dummy_id>
1893 In-Reply-To: <dummy_test_message_id>
1894 Subject: New title [issue1]
1896 This is a second followup
1897 ''')
1899 assert nodeid1 == nodeid2
1900 self.assertEqual(self.db.issue.get(nodeid2, 'title'), "Testing...")
1902 def testSecurityMessagePermissionContent(self):
1903 id = self.doNewIssue()
1904 issue = self.db.issue.getnode (id)
1905 self.db.security.addRole(name='Nomsg')
1906 self.db.security.addPermissionToRole('Nomsg', 'Email Access')
1907 for cl in 'issue', 'file', 'keyword':
1908 for p in 'View', 'Edit', 'Create':
1909 self.db.security.addPermissionToRole('Nomsg', p, cl)
1910 self.db.user.set(self.mary_id, roles='Nomsg')
1911 nodeid = self._handle_mail('''Content-Type: text/plain;
1912 charset="iso-8859-1"
1913 From: Chef <chef@bork.bork.bork>
1914 To: issue_tracker@your.tracker.email.domain.example
1915 Message-Id: <dummy_test_message_id>
1916 Subject: [issue%(id)s] Testing... [nosy=+mary]
1918 Just a test reply
1919 '''%locals())
1920 assert os.path.exists(SENDMAILDEBUG)
1921 self.compareMessages(self._get_mail(),
1922 '''FROM: roundup-admin@your.tracker.email.domain.example
1923 TO: chef@bork.bork.bork, richard@test.test
1924 Content-Type: text/plain; charset="utf-8"
1925 Subject: [issue1] Testing...
1926 To: richard@test.test
1927 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
1928 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1929 MIME-Version: 1.0
1930 Message-Id: <dummy_test_message_id>
1931 X-Roundup-Name: Roundup issue tracker
1932 X-Roundup-Loop: hello
1933 X-Roundup-Issue-Status: chatting
1934 Content-Transfer-Encoding: quoted-printable
1937 Bork, Chef <chef@bork.bork.bork> added the comment:
1939 Just a test reply
1941 ----------
1942 nosy: +mary
1943 status: unread -> chatting
1945 _______________________________________________________________________
1946 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1947 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1948 _______________________________________________________________________
1949 ''')
1952 def test_suite():
1953 suite = unittest.TestSuite()
1954 suite.addTest(unittest.makeSuite(MailgwTestCase))
1955 return suite
1957 if __name__ == '__main__':
1958 runner = unittest.TextTestRunner()
1959 unittest.main(testRunner=runner)
1961 # vim: set filetype=python sts=4 sw=4 et si :