e15e2928585e441f7fc3c6eb08000e3d6e056c6b
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
30 import memorydb
32 class Message(rfc822.Message):
33 """String-based Message class with equivalence test."""
34 def __init__(self, s):
35 rfc822.Message.__init__(self, StringIO(s.strip()))
37 def __eq__(self, other):
38 return (self.dict == other.dict and
39 self.fp.read() == other.fp.read())
41 class Tracker(object):
42 def open(self, journaltag):
43 return self.db
45 class DiffHelper:
46 def compareMessages(self, new, old):
47 """Compare messages for semantic equivalence."""
48 new, old = Message(new), Message(old)
50 # all Roundup-generated messages have "Precedence: bulk"
51 old['Precedence'] = 'bulk'
53 # don't try to compare the date
54 del new['date'], old['date']
56 if not new == old:
57 res = []
59 replace = {}
60 for key in new.keys():
61 if key.startswith('from '):
62 # skip the unix from line
63 continue
64 if key.lower() == 'x-roundup-version':
65 # version changes constantly, so handle it specially
66 if new[key] != __version__:
67 res.append(' %s: %r != %r' % (key, __version__,
68 new[key]))
69 elif key.lower() == 'content-type' and 'boundary=' in new[key]:
70 # handle mime messages
71 newmime = new[key].split('=',1)[-1].strip('"')
72 oldmime = old.get(key, '').split('=',1)[-1].strip('"')
73 replace ['--' + newmime] = '--' + oldmime
74 replace ['--' + newmime + '--'] = '--' + oldmime + '--'
75 elif new.get(key, '') != old.get(key, ''):
76 res.append(' %s: %r != %r' % (key, old.get(key, ''),
77 new.get(key, '')))
79 body_diff = self.compareStrings(new.fp.read(), old.fp.read(),
80 replace=replace)
81 if body_diff:
82 res.append('')
83 res.extend(body_diff)
85 if res:
86 res.insert(0, 'Generated message not correct (diff follows, expected vs. actual):')
87 raise AssertionError, '\n'.join(res)
89 def compareStrings(self, s2, s1, replace={}):
90 '''Note the reversal of s2 and s1 - difflib.SequenceMatcher wants
91 the first to be the "original" but in the calls in this file,
92 the second arg is the original. Ho hum.
93 Do replacements over the replace dict -- used for mime boundary
94 '''
95 l1 = s1.strip().split('\n')
96 l2 = [replace.get(i,i) for i in s2.strip().split('\n')]
97 if l1 == l2:
98 return
99 s = difflib.SequenceMatcher(None, l1, l2)
100 res = []
101 for value, s1s, s1e, s2s, s2e in s.get_opcodes():
102 if value == 'equal':
103 for i in range(s1s, s1e):
104 res.append(' %s'%l1[i])
105 elif value == 'delete':
106 for i in range(s1s, s1e):
107 res.append('- %s'%l1[i])
108 elif value == 'insert':
109 for i in range(s2s, s2e):
110 res.append('+ %s'%l2[i])
111 elif value == 'replace':
112 for i, j in zip(range(s1s, s1e), range(s2s, s2e)):
113 res.append('- %s'%l1[i])
114 res.append('+ %s'%l2[j])
116 return res
118 class MailgwTestCase(unittest.TestCase, DiffHelper):
119 count = 0
120 schema = 'classic'
121 def setUp(self):
122 MailgwTestCase.count = MailgwTestCase.count + 1
124 # and open the database / "instance"
125 self.db = memorydb.create('admin')
126 self.instance = Tracker()
127 self.instance.db = self.db
128 self.instance.config = self.db.config
129 self.instance.MailGW = MailGW
131 self.chef_id = self.db.user.create(username='Chef',
132 address='chef@bork.bork.bork', realname='Bork, Chef', roles='User')
133 self.richard_id = self.db.user.create(username='richard',
134 address='richard@test.test', roles='User')
135 self.mary_id = self.db.user.create(username='mary',
136 address='mary@test.test', roles='User', realname='Contrary, Mary')
137 self.john_id = self.db.user.create(username='john',
138 address='john@test.test', roles='User', realname='John Doe',
139 alternate_addresses='jondoe@test.test\njohn.doe@test.test')
141 def tearDown(self):
142 if os.path.exists(SENDMAILDEBUG):
143 os.remove(SENDMAILDEBUG)
144 self.db.close()
146 def _handle_mail(self, message):
147 handler = self.instance.MailGW(self.instance)
148 handler.trapExceptions = 0
149 return handler.main(StringIO(message))
151 def _get_mail(self):
152 f = open(SENDMAILDEBUG)
153 try:
154 return f.read()
155 finally:
156 f.close()
158 def testEmptyMessage(self):
159 nodeid = self._handle_mail('''Content-Type: text/plain;
160 charset="iso-8859-1"
161 From: Chef <chef@bork.bork.bork>
162 To: issue_tracker@your.tracker.email.domain.example
163 Cc: richard@test.test
164 Reply-To: chef@bork.bork.bork
165 Message-Id: <dummy_test_message_id>
166 Subject: [issue] Testing...
168 ''')
169 assert not os.path.exists(SENDMAILDEBUG)
170 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'Testing...')
172 def testMessageWithFromInIt(self):
173 nodeid = self._handle_mail('''Content-Type: text/plain;
174 charset="iso-8859-1"
175 From: Chef <chef@bork.bork.bork>
176 To: issue_tracker@your.tracker.email.domain.example
177 Cc: richard@test.test
178 Reply-To: chef@bork.bork.bork
179 Message-Id: <dummy_test_message_id>
180 Subject: [issue] Testing...
182 From here to there!
183 ''')
184 assert not os.path.exists(SENDMAILDEBUG)
185 msgid = self.db.issue.get(nodeid, 'msg')[0]
186 self.assertEqual(self.db.issue.get(msgid, 'content'), 'From here to there!')
188 def doNewIssue(self):
189 nodeid = self._handle_mail('''Content-Type: text/plain;
190 charset="iso-8859-1"
191 From: Chef <chef@bork.bork.bork>
192 To: issue_tracker@your.tracker.email.domain.example
193 Cc: richard@test.test
194 Message-Id: <dummy_test_message_id>
195 Subject: [issue] Testing...
197 This is a test submission of a new issue.
198 ''')
199 assert not os.path.exists(SENDMAILDEBUG)
200 l = self.db.issue.get(nodeid, 'nosy')
201 l.sort()
202 self.assertEqual(l, [self.chef_id, self.richard_id])
203 return nodeid
205 def testNewIssue(self):
206 self.doNewIssue()
208 def testNewIssueNosy(self):
209 self.instance.config.ADD_AUTHOR_TO_NOSY = 'yes'
210 nodeid = self._handle_mail('''Content-Type: text/plain;
211 charset="iso-8859-1"
212 From: Chef <chef@bork.bork.bork>
213 To: issue_tracker@your.tracker.email.domain.example
214 Cc: richard@test.test
215 Message-Id: <dummy_test_message_id>
216 Subject: [issue] Testing...
218 This is a test submission of a new issue.
219 ''')
220 assert not os.path.exists(SENDMAILDEBUG)
221 l = self.db.issue.get(nodeid, 'nosy')
222 l.sort()
223 self.assertEqual(l, [self.chef_id, self.richard_id])
225 def testAlternateAddress(self):
226 self._handle_mail('''Content-Type: text/plain;
227 charset="iso-8859-1"
228 From: John Doe <john.doe@test.test>
229 To: issue_tracker@your.tracker.email.domain.example
230 Message-Id: <dummy_test_message_id>
231 Subject: [issue] Testing...
233 This is a test submission of a new issue.
234 ''')
235 userlist = self.db.user.list()
236 assert not os.path.exists(SENDMAILDEBUG)
237 self.assertEqual(userlist, self.db.user.list(),
238 "user created when it shouldn't have been")
240 def testNewIssueNoClass(self):
241 self._handle_mail('''Content-Type: text/plain;
242 charset="iso-8859-1"
243 From: Chef <chef@bork.bork.bork>
244 To: issue_tracker@your.tracker.email.domain.example
245 Cc: richard@test.test
246 Message-Id: <dummy_test_message_id>
247 Subject: Testing...
249 This is a test submission of a new issue.
250 ''')
251 assert not os.path.exists(SENDMAILDEBUG)
253 def testNewIssueAuthMsg(self):
254 # TODO: fix the damn config - this is apalling
255 self.db.config.MESSAGES_TO_AUTHOR = 'yes'
256 self._handle_mail('''Content-Type: text/plain;
257 charset="iso-8859-1"
258 From: Chef <chef@bork.bork.bork>
259 To: issue_tracker@your.tracker.email.domain.example
260 Message-Id: <dummy_test_message_id>
261 Subject: [issue] Testing... [nosy=mary; assignedto=richard]
263 This is a test submission of a new issue.
264 ''')
265 self.compareMessages(self._get_mail(),
266 '''FROM: roundup-admin@your.tracker.email.domain.example
267 TO: chef@bork.bork.bork, mary@test.test, richard@test.test
268 Content-Type: text/plain; charset="utf-8"
269 Subject: [issue1] Testing...
270 To: chef@bork.bork.bork, mary@test.test, richard@test.test
271 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
272 Reply-To: Roundup issue tracker
273 <issue_tracker@your.tracker.email.domain.example>
274 MIME-Version: 1.0
275 Message-Id: <dummy_test_message_id>
276 X-Roundup-Name: Roundup issue tracker
277 X-Roundup-Loop: hello
278 X-Roundup-Issue-Status: unread
279 Content-Transfer-Encoding: quoted-printable
282 New submission from Bork, Chef <chef@bork.bork.bork>:
284 This is a test submission of a new issue.
286 ----------
287 assignedto: richard
288 messages: 1
289 nosy: Chef, mary, richard
290 status: unread
291 title: Testing...
293 _______________________________________________________________________
294 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
295 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
296 _______________________________________________________________________
297 ''')
299 def testNewIssueNoAuthorInfo(self):
300 self.db.config.MAIL_ADD_AUTHORINFO = 'no'
301 self._handle_mail('''Content-Type: text/plain;
302 charset="iso-8859-1"
303 From: Chef <chef@bork.bork.bork>
304 To: issue_tracker@your.tracker.email.domain.example
305 Message-Id: <dummy_test_message_id>
306 Subject: [issue] Testing... [nosy=mary; assignedto=richard]
308 This is a test submission of a new issue.
309 ''')
310 self.compareMessages(self._get_mail(),
311 '''FROM: roundup-admin@your.tracker.email.domain.example
312 TO: chef@bork.bork.bork, mary@test.test, richard@test.test
313 Content-Type: text/plain; charset="utf-8"
314 Subject: [issue1] Testing...
315 To: mary@test.test, richard@test.test
316 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
317 Reply-To: Roundup issue tracker
318 <issue_tracker@your.tracker.email.domain.example>
319 MIME-Version: 1.0
320 Message-Id: <dummy_test_message_id>
321 X-Roundup-Name: Roundup issue tracker
322 X-Roundup-Loop: hello
323 X-Roundup-Issue-Status: unread
324 Content-Transfer-Encoding: quoted-printable
326 This is a test submission of a new issue.
328 ----------
329 assignedto: richard
330 messages: 1
331 nosy: Chef, mary, richard
332 status: unread
333 title: Testing...
335 _______________________________________________________________________
336 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
337 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
338 _______________________________________________________________________
339 ''')
341 def testNewIssueNoAuthorEmail(self):
342 self.db.config.MAIL_ADD_AUTHOREMAIL = 'no'
343 self._handle_mail('''Content-Type: text/plain;
344 charset="iso-8859-1"
345 From: Chef <chef@bork.bork.bork>
346 To: issue_tracker@your.tracker.email.domain.example
347 Message-Id: <dummy_test_message_id>
348 Subject: [issue] Testing... [nosy=mary; assignedto=richard]
350 This is a test submission of a new issue.
351 ''')
352 self.compareMessages(self._get_mail(),
353 '''FROM: roundup-admin@your.tracker.email.domain.example
354 TO: chef@bork.bork.bork, mary@test.test, richard@test.test
355 Content-Type: text/plain; charset="utf-8"
356 Subject: [issue1] Testing...
357 To: mary@test.test, richard@test.test
358 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
359 Reply-To: Roundup issue tracker
360 <issue_tracker@your.tracker.email.domain.example>
361 MIME-Version: 1.0
362 Message-Id: <dummy_test_message_id>
363 X-Roundup-Name: Roundup issue tracker
364 X-Roundup-Loop: hello
365 X-Roundup-Issue-Status: unread
366 Content-Transfer-Encoding: quoted-printable
368 New submission from Bork, Chef:
370 This is a test submission of a new issue.
372 ----------
373 assignedto: richard
374 messages: 1
375 nosy: Chef, mary, richard
376 status: unread
377 title: Testing...
379 _______________________________________________________________________
380 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
381 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
382 _______________________________________________________________________
383 ''')
385 multipart_msg = '''From: mary <mary@test.test>
386 To: issue_tracker@your.tracker.email.domain.example
387 Message-Id: <followup_dummy_id>
388 In-Reply-To: <dummy_test_message_id>
389 Subject: [issue1] Testing...
390 Content-Type: multipart/mixed; boundary="bxyzzy"
391 Content-Disposition: inline
394 --bxyzzy
395 Content-Type: multipart/alternative; boundary="bCsyhTFzCvuiizWE"
396 Content-Disposition: inline
398 --bCsyhTFzCvuiizWE
399 Content-Type: text/plain; charset=us-ascii
400 Content-Disposition: inline
402 test attachment first text/plain
404 --bCsyhTFzCvuiizWE
405 Content-Type: application/octet-stream
406 Content-Disposition: attachment; filename="first.dvi"
407 Content-Transfer-Encoding: base64
409 SnVzdCBhIHRlc3QgAQo=
411 --bCsyhTFzCvuiizWE
412 Content-Type: text/plain; charset=us-ascii
413 Content-Disposition: inline
415 test attachment second text/plain
417 --bCsyhTFzCvuiizWE
418 Content-Type: text/html
419 Content-Disposition: inline
421 <html>
422 to be ignored.
423 </html>
425 --bCsyhTFzCvuiizWE--
427 --bxyzzy
428 Content-Type: multipart/alternative; boundary="bCsyhTFzCvuiizWF"
429 Content-Disposition: inline
431 --bCsyhTFzCvuiizWF
432 Content-Type: text/plain; charset=us-ascii
433 Content-Disposition: inline
435 test attachment third text/plain
437 --bCsyhTFzCvuiizWF
438 Content-Type: application/octet-stream
439 Content-Disposition: attachment; filename="second.dvi"
440 Content-Transfer-Encoding: base64
442 SnVzdCBhIHRlc3QK
444 --bCsyhTFzCvuiizWF--
446 --bxyzzy--
447 '''
449 def testMultipartKeepAlternatives(self):
450 self.doNewIssue()
451 self._handle_mail(self.multipart_msg)
452 messages = self.db.issue.get('1', 'messages')
453 messages.sort()
454 msg = self.db.msg.getnode (messages[-1])
455 assert(len(msg.files) == 5)
456 names = {0 : 'first.dvi', 4 : 'second.dvi'}
457 content = {3 : 'test attachment third text/plain\n',
458 4 : 'Just a test\n'}
459 for n, id in enumerate (msg.files):
460 f = self.db.file.getnode (id)
461 self.assertEqual(f.name, names.get (n, 'unnamed'))
462 if n in content :
463 self.assertEqual(f.content, content [n])
464 self.assertEqual(msg.content, 'test attachment second text/plain')
466 def testMultipartDropAlternatives(self):
467 self.doNewIssue()
468 self.db.config.MAILGW_IGNORE_ALTERNATIVES = True
469 self._handle_mail(self.multipart_msg)
470 messages = self.db.issue.get('1', 'messages')
471 messages.sort()
472 msg = self.db.msg.getnode (messages[-1])
473 assert(len(msg.files) == 2)
474 names = {1 : 'second.dvi'}
475 content = {0 : 'test attachment third text/plain\n',
476 1 : 'Just a test\n'}
477 for n, id in enumerate (msg.files):
478 f = self.db.file.getnode (id)
479 self.assertEqual(f.name, names.get (n, 'unnamed'))
480 if n in content :
481 self.assertEqual(f.content, content [n])
482 self.assertEqual(msg.content, 'test attachment second text/plain')
484 def testSimpleFollowup(self):
485 self.doNewIssue()
486 self._handle_mail('''Content-Type: text/plain;
487 charset="iso-8859-1"
488 From: mary <mary@test.test>
489 To: issue_tracker@your.tracker.email.domain.example
490 Message-Id: <followup_dummy_id>
491 In-Reply-To: <dummy_test_message_id>
492 Subject: [issue1] Testing...
494 This is a second followup
495 ''')
496 self.compareMessages(self._get_mail(),
497 '''FROM: roundup-admin@your.tracker.email.domain.example
498 TO: chef@bork.bork.bork, richard@test.test
499 Content-Type: text/plain; charset="utf-8"
500 Subject: [issue1] Testing...
501 To: chef@bork.bork.bork, richard@test.test
502 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
503 Reply-To: Roundup issue tracker
504 <issue_tracker@your.tracker.email.domain.example>
505 MIME-Version: 1.0
506 Message-Id: <followup_dummy_id>
507 In-Reply-To: <dummy_test_message_id>
508 X-Roundup-Name: Roundup issue tracker
509 X-Roundup-Loop: hello
510 X-Roundup-Issue-Status: chatting
511 Content-Transfer-Encoding: quoted-printable
514 Contrary, Mary <mary@test.test> added the comment:
516 This is a second followup
518 ----------
519 status: unread -> chatting
521 _______________________________________________________________________
522 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
523 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
524 _______________________________________________________________________
525 ''')
527 def testFollowup(self):
528 self.doNewIssue()
530 self._handle_mail('''Content-Type: text/plain;
531 charset="iso-8859-1"
532 From: richard <richard@test.test>
533 To: issue_tracker@your.tracker.email.domain.example
534 Message-Id: <followup_dummy_id>
535 In-Reply-To: <dummy_test_message_id>
536 Subject: [issue1] Testing... [assignedto=mary; nosy=+john]
538 This is a followup
539 ''')
540 l = self.db.issue.get('1', 'nosy')
541 l.sort()
542 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
543 self.john_id])
545 self.compareMessages(self._get_mail(),
546 '''FROM: roundup-admin@your.tracker.email.domain.example
547 TO: chef@bork.bork.bork, john@test.test, mary@test.test
548 Content-Type: text/plain; charset="utf-8"
549 Subject: [issue1] Testing...
550 To: chef@bork.bork.bork, john@test.test, mary@test.test
551 From: richard <issue_tracker@your.tracker.email.domain.example>
552 Reply-To: Roundup issue tracker
553 <issue_tracker@your.tracker.email.domain.example>
554 MIME-Version: 1.0
555 Message-Id: <followup_dummy_id>
556 In-Reply-To: <dummy_test_message_id>
557 X-Roundup-Name: Roundup issue tracker
558 X-Roundup-Loop: hello
559 X-Roundup-Issue-Status: chatting
560 Content-Transfer-Encoding: quoted-printable
563 richard <richard@test.test> added the comment:
565 This is a followup
567 ----------
568 assignedto: -> mary
569 nosy: +john, mary
570 status: unread -> chatting
572 _______________________________________________________________________
573 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
574 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
575 _______________________________________________________________________
576 ''')
578 def testPropertyChangeOnly(self):
579 self.doNewIssue()
580 oldvalues = self.db.getnode('issue', '1').copy()
581 oldvalues['assignedto'] = None
582 # reconstruct old behaviour: This would reuse the
583 # database-handle from the doNewIssue above which has committed
584 # as user "Chef". So we close and reopen the db as that user.
585 self.db.close()
586 self.db = self.instance.open('Chef')
587 self.db.issue.set('1', assignedto=self.chef_id)
588 self.db.commit()
589 self.db.issue.nosymessage('1', None, oldvalues)
591 new_mail = ""
592 for line in self._get_mail().split("\n"):
593 if "Message-Id: " in line:
594 continue
595 if "Date: " in line:
596 continue
597 new_mail += line+"\n"
599 self.compareMessages(new_mail, """
600 FROM: roundup-admin@your.tracker.email.domain.example
601 TO: chef@bork.bork.bork, richard@test.test
602 Content-Type: text/plain; charset="utf-8"
603 Subject: [issue1] Testing...
604 To: chef@bork.bork.bork, richard@test.test
605 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
606 X-Roundup-Name: Roundup issue tracker
607 X-Roundup-Loop: hello
608 X-Roundup-Issue-Status: unread
609 X-Roundup-Version: 1.3.3
610 MIME-Version: 1.0
611 Reply-To: Roundup issue tracker
612 <issue_tracker@your.tracker.email.domain.example>
613 Content-Transfer-Encoding: quoted-printable
616 Change by Bork, Chef <chef@bork.bork.bork>:
619 ----------
620 assignedto: -> Chef
622 _______________________________________________________________________
623 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
624 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
625 _______________________________________________________________________
626 """)
629 #
630 # FOLLOWUP TITLE MATCH
631 #
632 def testFollowupTitleMatch(self):
633 self.doNewIssue()
634 self._handle_mail('''Content-Type: text/plain;
635 charset="iso-8859-1"
636 From: richard <richard@test.test>
637 To: issue_tracker@your.tracker.email.domain.example
638 Message-Id: <followup_dummy_id>
639 Subject: Re: Testing... [assignedto=mary; nosy=+john]
641 This is a followup
642 ''')
643 self.compareMessages(self._get_mail(),
644 '''FROM: roundup-admin@your.tracker.email.domain.example
645 TO: chef@bork.bork.bork, john@test.test, mary@test.test
646 Content-Type: text/plain; charset="utf-8"
647 Subject: [issue1] Testing...
648 To: chef@bork.bork.bork, john@test.test, mary@test.test
649 From: richard <issue_tracker@your.tracker.email.domain.example>
650 Reply-To: Roundup issue tracker
651 <issue_tracker@your.tracker.email.domain.example>
652 MIME-Version: 1.0
653 Message-Id: <followup_dummy_id>
654 In-Reply-To: <dummy_test_message_id>
655 X-Roundup-Name: Roundup issue tracker
656 X-Roundup-Loop: hello
657 X-Roundup-Issue-Status: chatting
658 Content-Transfer-Encoding: quoted-printable
661 richard <richard@test.test> added the comment:
663 This is a followup
665 ----------
666 assignedto: -> mary
667 nosy: +john, mary
668 status: unread -> chatting
670 _______________________________________________________________________
671 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
672 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
673 _______________________________________________________________________
674 ''')
676 def testFollowupTitleMatchMultiRe(self):
677 nodeid1 = self.doNewIssue()
678 nodeid2 = self._handle_mail('''Content-Type: text/plain;
679 charset="iso-8859-1"
680 From: richard <richard@test.test>
681 To: issue_tracker@your.tracker.email.domain.example
682 Message-Id: <followup_dummy_id>
683 Subject: Re: Testing... [assignedto=mary; nosy=+john]
685 This is a followup
686 ''')
688 nodeid3 = self._handle_mail('''Content-Type: text/plain;
689 charset="iso-8859-1"
690 From: richard <richard@test.test>
691 To: issue_tracker@your.tracker.email.domain.example
692 Message-Id: <followup2_dummy_id>
693 Subject: Ang: Re: Testing...
695 This is a followup
696 ''')
697 self.assertEqual(nodeid1, nodeid2)
698 self.assertEqual(nodeid1, nodeid3)
700 def testFollowupTitleMatchNever(self):
701 nodeid = self.doNewIssue()
702 self.db.config.MAILGW_SUBJECT_CONTENT_MATCH = 'never'
703 self.assertNotEqual(self._handle_mail('''Content-Type: text/plain;
704 charset="iso-8859-1"
705 From: richard <richard@test.test>
706 To: issue_tracker@your.tracker.email.domain.example
707 Message-Id: <followup_dummy_id>
708 Subject: Re: Testing...
710 This is a followup
711 '''), nodeid)
713 def testFollowupTitleMatchNeverInterval(self):
714 nodeid = self.doNewIssue()
715 # force failure of the interval
716 time.sleep(2)
717 self.db.config.MAILGW_SUBJECT_CONTENT_MATCH = 'creation 00:00:01'
718 self.assertNotEqual(self._handle_mail('''Content-Type: text/plain;
719 charset="iso-8859-1"
720 From: richard <richard@test.test>
721 To: issue_tracker@your.tracker.email.domain.example
722 Message-Id: <followup_dummy_id>
723 Subject: Re: Testing...
725 This is a followup
726 '''), nodeid)
729 def testFollowupTitleMatchInterval(self):
730 nodeid = self.doNewIssue()
731 self.db.config.MAILGW_SUBJECT_CONTENT_MATCH = 'creation +1d'
732 self.assertEqual(self._handle_mail('''Content-Type: text/plain;
733 charset="iso-8859-1"
734 From: richard <richard@test.test>
735 To: issue_tracker@your.tracker.email.domain.example
736 Message-Id: <followup_dummy_id>
737 Subject: Re: Testing...
739 This is a followup
740 '''), nodeid)
743 def testFollowupNosyAuthor(self):
744 self.doNewIssue()
745 self.db.config.ADD_AUTHOR_TO_NOSY = 'yes'
746 self._handle_mail('''Content-Type: text/plain;
747 charset="iso-8859-1"
748 From: john@test.test
749 To: issue_tracker@your.tracker.email.domain.example
750 Message-Id: <followup_dummy_id>
751 In-Reply-To: <dummy_test_message_id>
752 Subject: [issue1] Testing...
754 This is a followup
755 ''')
757 self.compareMessages(self._get_mail(),
758 '''FROM: roundup-admin@your.tracker.email.domain.example
759 TO: chef@bork.bork.bork, richard@test.test
760 Content-Type: text/plain; charset="utf-8"
761 Subject: [issue1] Testing...
762 To: chef@bork.bork.bork, richard@test.test
763 From: John Doe <issue_tracker@your.tracker.email.domain.example>
764 Reply-To: Roundup issue tracker
765 <issue_tracker@your.tracker.email.domain.example>
766 MIME-Version: 1.0
767 Message-Id: <followup_dummy_id>
768 In-Reply-To: <dummy_test_message_id>
769 X-Roundup-Name: Roundup issue tracker
770 X-Roundup-Loop: hello
771 X-Roundup-Issue-Status: chatting
772 Content-Transfer-Encoding: quoted-printable
775 John Doe <john@test.test> added the comment:
777 This is a followup
779 ----------
780 nosy: +john
781 status: unread -> chatting
783 _______________________________________________________________________
784 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
785 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
786 _______________________________________________________________________
788 ''')
790 def testFollowupNosyRecipients(self):
791 self.doNewIssue()
792 self.db.config.ADD_RECIPIENTS_TO_NOSY = 'yes'
793 self._handle_mail('''Content-Type: text/plain;
794 charset="iso-8859-1"
795 From: richard@test.test
796 To: issue_tracker@your.tracker.email.domain.example
797 Cc: john@test.test
798 Message-Id: <followup_dummy_id>
799 In-Reply-To: <dummy_test_message_id>
800 Subject: [issue1] Testing...
802 This is a followup
803 ''')
804 self.compareMessages(self._get_mail(),
805 '''FROM: roundup-admin@your.tracker.email.domain.example
806 TO: chef@bork.bork.bork
807 Content-Type: text/plain; charset="utf-8"
808 Subject: [issue1] Testing...
809 To: chef@bork.bork.bork
810 From: richard <issue_tracker@your.tracker.email.domain.example>
811 Reply-To: Roundup issue tracker
812 <issue_tracker@your.tracker.email.domain.example>
813 MIME-Version: 1.0
814 Message-Id: <followup_dummy_id>
815 In-Reply-To: <dummy_test_message_id>
816 X-Roundup-Name: Roundup issue tracker
817 X-Roundup-Loop: hello
818 X-Roundup-Issue-Status: chatting
819 Content-Transfer-Encoding: quoted-printable
822 richard <richard@test.test> added the comment:
824 This is a followup
826 ----------
827 nosy: +john
828 status: unread -> chatting
830 _______________________________________________________________________
831 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
832 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
833 _______________________________________________________________________
835 ''')
837 def testFollowupNosyAuthorAndCopy(self):
838 self.doNewIssue()
839 self.db.config.ADD_AUTHOR_TO_NOSY = 'yes'
840 self.db.config.MESSAGES_TO_AUTHOR = 'yes'
841 self._handle_mail('''Content-Type: text/plain;
842 charset="iso-8859-1"
843 From: john@test.test
844 To: issue_tracker@your.tracker.email.domain.example
845 Message-Id: <followup_dummy_id>
846 In-Reply-To: <dummy_test_message_id>
847 Subject: [issue1] Testing...
849 This is a followup
850 ''')
851 self.compareMessages(self._get_mail(),
852 '''FROM: roundup-admin@your.tracker.email.domain.example
853 TO: chef@bork.bork.bork, john@test.test, richard@test.test
854 Content-Type: text/plain; charset="utf-8"
855 Subject: [issue1] Testing...
856 To: chef@bork.bork.bork, john@test.test, richard@test.test
857 From: John Doe <issue_tracker@your.tracker.email.domain.example>
858 Reply-To: Roundup issue tracker
859 <issue_tracker@your.tracker.email.domain.example>
860 MIME-Version: 1.0
861 Message-Id: <followup_dummy_id>
862 In-Reply-To: <dummy_test_message_id>
863 X-Roundup-Name: Roundup issue tracker
864 X-Roundup-Loop: hello
865 X-Roundup-Issue-Status: chatting
866 Content-Transfer-Encoding: quoted-printable
869 John Doe <john@test.test> added the comment:
871 This is a followup
873 ----------
874 nosy: +john
875 status: unread -> chatting
877 _______________________________________________________________________
878 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
879 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
880 _______________________________________________________________________
882 ''')
884 def testFollowupNoNosyAuthor(self):
885 self.doNewIssue()
886 self.instance.config.ADD_AUTHOR_TO_NOSY = 'no'
887 self._handle_mail('''Content-Type: text/plain;
888 charset="iso-8859-1"
889 From: john@test.test
890 To: issue_tracker@your.tracker.email.domain.example
891 Message-Id: <followup_dummy_id>
892 In-Reply-To: <dummy_test_message_id>
893 Subject: [issue1] Testing...
895 This is a followup
896 ''')
897 self.compareMessages(self._get_mail(),
898 '''FROM: roundup-admin@your.tracker.email.domain.example
899 TO: chef@bork.bork.bork, richard@test.test
900 Content-Type: text/plain; charset="utf-8"
901 Subject: [issue1] Testing...
902 To: chef@bork.bork.bork, richard@test.test
903 From: John Doe <issue_tracker@your.tracker.email.domain.example>
904 Reply-To: Roundup issue tracker
905 <issue_tracker@your.tracker.email.domain.example>
906 MIME-Version: 1.0
907 Message-Id: <followup_dummy_id>
908 In-Reply-To: <dummy_test_message_id>
909 X-Roundup-Name: Roundup issue tracker
910 X-Roundup-Loop: hello
911 X-Roundup-Issue-Status: chatting
912 Content-Transfer-Encoding: quoted-printable
915 John Doe <john@test.test> added the comment:
917 This is a followup
919 ----------
920 status: unread -> chatting
922 _______________________________________________________________________
923 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
924 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
925 _______________________________________________________________________
927 ''')
929 def testFollowupNoNosyRecipients(self):
930 self.doNewIssue()
931 self.instance.config.ADD_RECIPIENTS_TO_NOSY = 'no'
932 self._handle_mail('''Content-Type: text/plain;
933 charset="iso-8859-1"
934 From: richard@test.test
935 To: issue_tracker@your.tracker.email.domain.example
936 Cc: john@test.test
937 Message-Id: <followup_dummy_id>
938 In-Reply-To: <dummy_test_message_id>
939 Subject: [issue1] Testing...
941 This is a followup
942 ''')
943 self.compareMessages(self._get_mail(),
944 '''FROM: roundup-admin@your.tracker.email.domain.example
945 TO: chef@bork.bork.bork
946 Content-Type: text/plain; charset="utf-8"
947 Subject: [issue1] Testing...
948 To: chef@bork.bork.bork
949 From: richard <issue_tracker@your.tracker.email.domain.example>
950 Reply-To: Roundup issue tracker
951 <issue_tracker@your.tracker.email.domain.example>
952 MIME-Version: 1.0
953 Message-Id: <followup_dummy_id>
954 In-Reply-To: <dummy_test_message_id>
955 X-Roundup-Name: Roundup issue tracker
956 X-Roundup-Loop: hello
957 X-Roundup-Issue-Status: chatting
958 Content-Transfer-Encoding: quoted-printable
961 richard <richard@test.test> added the comment:
963 This is a followup
965 ----------
966 status: unread -> chatting
968 _______________________________________________________________________
969 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
970 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
971 _______________________________________________________________________
973 ''')
975 def testFollowupEmptyMessage(self):
976 self.doNewIssue()
978 self._handle_mail('''Content-Type: text/plain;
979 charset="iso-8859-1"
980 From: richard <richard@test.test>
981 To: issue_tracker@your.tracker.email.domain.example
982 Message-Id: <followup_dummy_id>
983 In-Reply-To: <dummy_test_message_id>
984 Subject: [issue1] Testing... [assignedto=mary; nosy=+john]
986 ''')
987 l = self.db.issue.get('1', 'nosy')
988 l.sort()
989 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
990 self.john_id])
992 # should be no file created (ie. no message)
993 assert not os.path.exists(SENDMAILDEBUG)
995 def testFollowupEmptyMessageNoSubject(self):
996 self.doNewIssue()
998 self._handle_mail('''Content-Type: text/plain;
999 charset="iso-8859-1"
1000 From: richard <richard@test.test>
1001 To: issue_tracker@your.tracker.email.domain.example
1002 Message-Id: <followup_dummy_id>
1003 In-Reply-To: <dummy_test_message_id>
1004 Subject: [issue1] [assignedto=mary; nosy=+john]
1006 ''')
1007 l = self.db.issue.get('1', 'nosy')
1008 l.sort()
1009 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
1010 self.john_id])
1012 # should be no file created (ie. no message)
1013 assert not os.path.exists(SENDMAILDEBUG)
1015 def testNosyRemove(self):
1016 self.doNewIssue()
1018 self._handle_mail('''Content-Type: text/plain;
1019 charset="iso-8859-1"
1020 From: richard <richard@test.test>
1021 To: issue_tracker@your.tracker.email.domain.example
1022 Message-Id: <followup_dummy_id>
1023 In-Reply-To: <dummy_test_message_id>
1024 Subject: [issue1] Testing... [nosy=-richard]
1026 ''')
1027 l = self.db.issue.get('1', 'nosy')
1028 l.sort()
1029 self.assertEqual(l, [self.chef_id])
1031 # NO NOSY MESSAGE SHOULD BE SENT!
1032 assert not os.path.exists(SENDMAILDEBUG)
1034 def testNewUserAuthor(self):
1035 l = self.db.user.list()
1036 l.sort()
1037 message = '''Content-Type: text/plain;
1038 charset="iso-8859-1"
1039 From: fubar <fubar@bork.bork.bork>
1040 To: issue_tracker@your.tracker.email.domain.example
1041 Message-Id: <dummy_test_message_id>
1042 Subject: [issue] Testing...
1044 This is a test submission of a new issue.
1045 '''
1046 self.db.security.role['anonymous'].permissions=[]
1047 anonid = self.db.user.lookup('anonymous')
1048 self.db.user.set(anonid, roles='Anonymous')
1049 try:
1050 self._handle_mail(message)
1051 except Unauthorized, value:
1052 body_diff = self.compareMessages(str(value), """
1053 You are not a registered user.
1055 Unknown address: fubar@bork.bork.bork
1056 """)
1057 assert not body_diff, body_diff
1058 else:
1059 raise AssertionError, "Unathorized not raised when handling mail"
1061 # Add Web Access role to anonymous, and try again to make sure
1062 # we get a "please register at:" message this time.
1063 p = [
1064 self.db.security.getPermission('Register', 'user'),
1065 self.db.security.getPermission('Web Access', None),
1066 ]
1067 self.db.security.role['anonymous'].permissions=p
1068 try:
1069 self._handle_mail(message)
1070 except Unauthorized, value:
1071 body_diff = self.compareMessages(str(value), """
1072 You are not a registered user. Please register at:
1074 http://tracker.example/cgi-bin/roundup.cgi/bugs/user?template=register
1076 ...before sending mail to the tracker.
1078 Unknown address: fubar@bork.bork.bork
1079 """)
1080 assert not body_diff, body_diff
1081 else:
1082 raise AssertionError, "Unathorized not raised when handling mail"
1084 # Make sure list of users is the same as before.
1085 m = self.db.user.list()
1086 m.sort()
1087 self.assertEqual(l, m)
1089 # now with the permission
1090 p = [
1091 self.db.security.getPermission('Register', 'user'),
1092 self.db.security.getPermission('Email Access', None),
1093 ]
1094 self.db.security.role['anonymous'].permissions=p
1095 self._handle_mail(message)
1096 m = self.db.user.list()
1097 m.sort()
1098 self.assertNotEqual(l, m)
1100 def testNewUserAuthorEncodedName(self):
1101 l = set(self.db.user.list())
1102 # From: name has Euro symbol in it
1103 message = '''Content-Type: text/plain;
1104 charset="iso-8859-1"
1105 From: =?utf8?b?SOKCrGxsbw==?= <fubar@bork.bork.bork>
1106 To: issue_tracker@your.tracker.email.domain.example
1107 Message-Id: <dummy_test_message_id>
1108 Subject: [issue] Testing...
1110 This is a test submission of a new issue.
1111 '''
1112 p = [
1113 self.db.security.getPermission('Register', 'user'),
1114 self.db.security.getPermission('Email Access', None),
1115 self.db.security.getPermission('Create', 'issue'),
1116 self.db.security.getPermission('Create', 'msg'),
1117 ]
1118 self.db.security.role['anonymous'].permissions = p
1119 self._handle_mail(message)
1120 m = set(self.db.user.list())
1121 new = list(m - l)[0]
1122 name = self.db.user.get(new, 'realname')
1123 self.assertEquals(name, 'H€llo')
1125 def testUnknownUser(self):
1126 l = set(self.db.user.list())
1127 message = '''Content-Type: text/plain;
1128 charset="iso-8859-1"
1129 From: Nonexisting User <nonexisting@bork.bork.bork>
1130 To: issue_tracker@your.tracker.email.domain.example
1131 Message-Id: <dummy_test_message_id>
1132 Subject: [issue] Testing nonexisting user...
1134 This is a test submission of a new issue.
1135 '''
1136 self.db.close()
1137 handler = self.instance.MailGW(self.instance)
1138 # we want a bounce message:
1139 handler.trapExceptions = 1
1140 ret = handler.main(StringIO(message))
1141 self.compareMessages(self._get_mail(),
1142 '''FROM: Roundup issue tracker <roundup-admin@your.tracker.email.domain.example>
1143 TO: nonexisting@bork.bork.bork
1144 From nobody Tue Jul 14 12:04:11 2009
1145 Content-Type: multipart/mixed; boundary="===============0639262320=="
1146 MIME-Version: 1.0
1147 Subject: Failed issue tracker submission
1148 To: nonexisting@bork.bork.bork
1149 From: Roundup issue tracker <roundup-admin@your.tracker.email.domain.example>
1150 Date: Tue, 14 Jul 2009 12:04:11 +0000
1151 Precedence: bulk
1152 X-Roundup-Name: Roundup issue tracker
1153 X-Roundup-Loop: hello
1154 X-Roundup-Version: 1.4.8
1155 MIME-Version: 1.0
1157 --===============0639262320==
1158 Content-Type: text/plain; charset="us-ascii"
1159 MIME-Version: 1.0
1160 Content-Transfer-Encoding: 7bit
1164 You are not a registered user. Please register at:
1166 http://tracker.example/cgi-bin/roundup.cgi/bugs/user?template=register
1168 ...before sending mail to the tracker.
1170 Unknown address: nonexisting@bork.bork.bork
1172 --===============0639262320==
1173 Content-Type: text/plain; charset="us-ascii"
1174 MIME-Version: 1.0
1175 Content-Transfer-Encoding: 7bit
1177 Content-Type: text/plain;
1178 charset="iso-8859-1"
1179 From: Nonexisting User <nonexisting@bork.bork.bork>
1180 To: issue_tracker@your.tracker.email.domain.example
1181 Message-Id: <dummy_test_message_id>
1182 Subject: [issue] Testing nonexisting user...
1184 This is a test submission of a new issue.
1186 --===============0639262320==--
1187 ''')
1189 def testEnc01(self):
1190 self.db.user.set(self.mary_id,
1191 realname='\xe4\xf6\xfc\xc4\xd6\xdc\xdf, Mary'.decode
1192 ('latin-1').encode('utf-8'))
1193 self.doNewIssue()
1194 self._handle_mail('''Content-Type: text/plain;
1195 charset="iso-8859-1"
1196 From: mary <mary@test.test>
1197 To: issue_tracker@your.tracker.email.domain.example
1198 Message-Id: <followup_dummy_id>
1199 In-Reply-To: <dummy_test_message_id>
1200 Subject: [issue1] Testing...
1201 Content-Type: text/plain;
1202 charset="iso-8859-1"
1203 Content-Transfer-Encoding: quoted-printable
1205 A message with encoding (encoded oe =F6)
1207 ''')
1208 self.compareMessages(self._get_mail(),
1209 '''FROM: roundup-admin@your.tracker.email.domain.example
1210 TO: chef@bork.bork.bork, richard@test.test
1211 Content-Type: text/plain; charset="utf-8"
1212 Subject: [issue1] Testing...
1213 To: chef@bork.bork.bork, richard@test.test
1214 From: =?utf-8?b?w6TDtsO8w4TDlsOcw58sIE1hcnk=?=
1215 <issue_tracker@your.tracker.email.domain.example>
1216 Reply-To: Roundup issue tracker
1217 <issue_tracker@your.tracker.email.domain.example>
1218 MIME-Version: 1.0
1219 Message-Id: <followup_dummy_id>
1220 In-Reply-To: <dummy_test_message_id>
1221 X-Roundup-Name: Roundup issue tracker
1222 X-Roundup-Loop: hello
1223 X-Roundup-Issue-Status: chatting
1224 Content-Transfer-Encoding: quoted-printable
1227 =C3=A4=C3=B6=C3=BC=C3=84=C3=96=C3=9C=C3=9F, Mary <mary@test.test> added the=
1228 comment:
1230 A message with encoding (encoded oe =C3=B6)
1232 ----------
1233 status: unread -> chatting
1235 _______________________________________________________________________
1236 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1237 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1238 _______________________________________________________________________
1239 ''')
1241 def testEncNonUTF8(self):
1242 self.doNewIssue()
1243 self.instance.config.EMAIL_CHARSET = 'iso-8859-1'
1244 self._handle_mail('''Content-Type: text/plain;
1245 charset="iso-8859-1"
1246 From: mary <mary@test.test>
1247 To: issue_tracker@your.tracker.email.domain.example
1248 Message-Id: <followup_dummy_id>
1249 In-Reply-To: <dummy_test_message_id>
1250 Subject: [issue1] Testing...
1251 Content-Type: text/plain;
1252 charset="iso-8859-1"
1253 Content-Transfer-Encoding: quoted-printable
1255 A message with encoding (encoded oe =F6)
1257 ''')
1258 self.compareMessages(self._get_mail(),
1259 '''FROM: roundup-admin@your.tracker.email.domain.example
1260 TO: chef@bork.bork.bork, richard@test.test
1261 Content-Type: text/plain; charset="iso-8859-1"
1262 Subject: [issue1] Testing...
1263 To: chef@bork.bork.bork, richard@test.test
1264 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
1265 Reply-To: Roundup issue tracker
1266 <issue_tracker@your.tracker.email.domain.example>
1267 MIME-Version: 1.0
1268 Message-Id: <followup_dummy_id>
1269 In-Reply-To: <dummy_test_message_id>
1270 X-Roundup-Name: Roundup issue tracker
1271 X-Roundup-Loop: hello
1272 X-Roundup-Issue-Status: chatting
1273 Content-Transfer-Encoding: quoted-printable
1276 Contrary, Mary <mary@test.test> added the comment:
1278 A message with encoding (encoded oe =F6)
1280 ----------
1281 status: unread -> chatting
1283 _______________________________________________________________________
1284 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1285 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1286 _______________________________________________________________________
1287 ''')
1290 def testMultipartEnc01(self):
1291 self.doNewIssue()
1292 self._handle_mail('''Content-Type: text/plain;
1293 charset="iso-8859-1"
1294 From: mary <mary@test.test>
1295 To: issue_tracker@your.tracker.email.domain.example
1296 Message-Id: <followup_dummy_id>
1297 In-Reply-To: <dummy_test_message_id>
1298 Subject: [issue1] Testing...
1299 Content-Type: multipart/mixed;
1300 boundary="----_=_NextPart_000_01"
1302 This message is in MIME format. Since your mail reader does not understand
1303 this format, some or all of this message may not be legible.
1305 ------_=_NextPart_000_01
1306 Content-Type: text/plain;
1307 charset="iso-8859-1"
1308 Content-Transfer-Encoding: quoted-printable
1310 A message with first part encoded (encoded oe =F6)
1312 ''')
1313 self.compareMessages(self._get_mail(),
1314 '''FROM: roundup-admin@your.tracker.email.domain.example
1315 TO: chef@bork.bork.bork, richard@test.test
1316 Content-Type: text/plain; charset="utf-8"
1317 Subject: [issue1] Testing...
1318 To: chef@bork.bork.bork, richard@test.test
1319 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
1320 Reply-To: Roundup issue tracker
1321 <issue_tracker@your.tracker.email.domain.example>
1322 MIME-Version: 1.0
1323 Message-Id: <followup_dummy_id>
1324 In-Reply-To: <dummy_test_message_id>
1325 X-Roundup-Name: Roundup issue tracker
1326 X-Roundup-Loop: hello
1327 X-Roundup-Issue-Status: chatting
1328 Content-Transfer-Encoding: quoted-printable
1331 Contrary, Mary <mary@test.test> added the comment:
1333 A message with first part encoded (encoded oe =C3=B6)
1335 ----------
1336 status: unread -> chatting
1338 _______________________________________________________________________
1339 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1340 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1341 _______________________________________________________________________
1342 ''')
1344 def testContentDisposition(self):
1345 self.doNewIssue()
1346 self._handle_mail('''Content-Type: text/plain;
1347 charset="iso-8859-1"
1348 From: mary <mary@test.test>
1349 To: issue_tracker@your.tracker.email.domain.example
1350 Message-Id: <followup_dummy_id>
1351 In-Reply-To: <dummy_test_message_id>
1352 Subject: [issue1] Testing...
1353 Content-Type: multipart/mixed; boundary="bCsyhTFzCvuiizWE"
1354 Content-Disposition: inline
1357 --bCsyhTFzCvuiizWE
1358 Content-Type: text/plain; charset=us-ascii
1359 Content-Disposition: inline
1361 test attachment binary
1363 --bCsyhTFzCvuiizWE
1364 Content-Type: application/octet-stream
1365 Content-Disposition: attachment; filename="main.dvi"
1366 Content-Transfer-Encoding: base64
1368 SnVzdCBhIHRlc3QgAQo=
1370 --bCsyhTFzCvuiizWE--
1371 ''')
1372 messages = self.db.issue.get('1', 'messages')
1373 messages.sort()
1374 file = self.db.file.getnode (self.db.msg.get(messages[-1], 'files')[0])
1375 self.assertEqual(file.name, 'main.dvi')
1376 self.assertEqual(file.content, 'Just a test \001\n')
1378 def testFollowupStupidQuoting(self):
1379 self.doNewIssue()
1381 self._handle_mail('''Content-Type: text/plain;
1382 charset="iso-8859-1"
1383 From: richard <richard@test.test>
1384 To: issue_tracker@your.tracker.email.domain.example
1385 Message-Id: <followup_dummy_id>
1386 In-Reply-To: <dummy_test_message_id>
1387 Subject: Re: "[issue1] Testing... "
1389 This is a followup
1390 ''')
1391 self.compareMessages(self._get_mail(),
1392 '''FROM: roundup-admin@your.tracker.email.domain.example
1393 TO: chef@bork.bork.bork
1394 Content-Type: text/plain; charset="utf-8"
1395 Subject: [issue1] Testing...
1396 To: chef@bork.bork.bork
1397 From: richard <issue_tracker@your.tracker.email.domain.example>
1398 Reply-To: Roundup issue tracker
1399 <issue_tracker@your.tracker.email.domain.example>
1400 MIME-Version: 1.0
1401 Message-Id: <followup_dummy_id>
1402 In-Reply-To: <dummy_test_message_id>
1403 X-Roundup-Name: Roundup issue tracker
1404 X-Roundup-Loop: hello
1405 X-Roundup-Issue-Status: chatting
1406 Content-Transfer-Encoding: quoted-printable
1409 richard <richard@test.test> added the comment:
1411 This is a followup
1413 ----------
1414 status: unread -> chatting
1416 _______________________________________________________________________
1417 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1418 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1419 _______________________________________________________________________
1420 ''')
1422 def testEmailQuoting(self):
1423 self.instance.config.EMAIL_KEEP_QUOTED_TEXT = 'no'
1424 self.innerTestQuoting('''This is a followup
1425 ''')
1427 def testEmailQuotingRemove(self):
1428 self.instance.config.EMAIL_KEEP_QUOTED_TEXT = 'yes'
1429 self.innerTestQuoting('''Blah blah wrote:
1430 > Blah bklaskdfj sdf asdf jlaskdf skj sdkfjl asdf
1431 > skdjlkjsdfalsdkfjasdlfkj dlfksdfalksd fj
1432 >
1434 This is a followup
1435 ''')
1437 def innerTestQuoting(self, expect):
1438 nodeid = self.doNewIssue()
1440 messages = self.db.issue.get(nodeid, 'messages')
1442 self._handle_mail('''Content-Type: text/plain;
1443 charset="iso-8859-1"
1444 From: richard <richard@test.test>
1445 To: issue_tracker@your.tracker.email.domain.example
1446 Message-Id: <followup_dummy_id>
1447 In-Reply-To: <dummy_test_message_id>
1448 Subject: Re: [issue1] Testing...
1450 Blah blah wrote:
1451 > Blah bklaskdfj sdf asdf jlaskdf skj sdkfjl asdf
1452 > skdjlkjsdfalsdkfjasdlfkj dlfksdfalksd fj
1453 >
1455 This is a followup
1456 ''')
1457 # figure the new message id
1458 newmessages = self.db.issue.get(nodeid, 'messages')
1459 for msg in messages:
1460 newmessages.remove(msg)
1461 messageid = newmessages[0]
1463 self.compareMessages(self.db.msg.get(messageid, 'content'), expect)
1465 def testUserLookup(self):
1466 i = self.db.user.create(username='user1', address='user1@foo.com')
1467 self.assertEqual(uidFromAddress(self.db, ('', 'user1@foo.com'), 0), i)
1468 self.assertEqual(uidFromAddress(self.db, ('', 'USER1@foo.com'), 0), i)
1469 i = self.db.user.create(username='user2', address='USER2@foo.com')
1470 self.assertEqual(uidFromAddress(self.db, ('', 'USER2@foo.com'), 0), i)
1471 self.assertEqual(uidFromAddress(self.db, ('', 'user2@foo.com'), 0), i)
1473 def testUserAlternateLookup(self):
1474 i = self.db.user.create(username='user1', address='user1@foo.com',
1475 alternate_addresses='user1@bar.com')
1476 self.assertEqual(uidFromAddress(self.db, ('', 'user1@bar.com'), 0), i)
1477 self.assertEqual(uidFromAddress(self.db, ('', 'USER1@bar.com'), 0), i)
1479 def testUserCreate(self):
1480 i = uidFromAddress(self.db, ('', 'user@foo.com'), 1)
1481 self.assertNotEqual(uidFromAddress(self.db, ('', 'user@bar.com'), 1), i)
1483 def testRFC2822(self):
1484 ascii_header = "[issue243] This is a \"test\" - with 'quotation' marks"
1485 unicode_header = '[issue244] \xd0\xb0\xd0\xbd\xd0\xb4\xd1\x80\xd0\xb5\xd0\xb9'
1486 unicode_encoded = '=?utf-8?q?[issue244]_=D0=B0=D0=BD=D0=B4=D1=80=D0=B5=D0=B9?='
1487 self.assertEqual(rfc2822.encode_header(ascii_header), ascii_header)
1488 self.assertEqual(rfc2822.encode_header(unicode_header), unicode_encoded)
1490 def testRegistrationConfirmation(self):
1491 otk = "Aj4euk4LZSAdwePohj90SME5SpopLETL"
1492 self.db.getOTKManager().set(otk, username='johannes')
1493 self._handle_mail('''Content-Type: text/plain;
1494 charset="iso-8859-1"
1495 From: Chef <chef@bork.bork.bork>
1496 To: issue_tracker@your.tracker.email.domain.example
1497 Cc: richard@test.test
1498 Message-Id: <dummy_test_message_id>
1499 Subject: Re: Complete your registration to Roundup issue tracker
1500 -- key %s
1502 This is a test confirmation of registration.
1503 ''' % otk)
1504 self.db.user.lookup('johannes')
1506 def testFollowupOnNonIssue(self):
1507 self.db.keyword.create(name='Foo')
1508 self._handle_mail('''Content-Type: text/plain;
1509 charset="iso-8859-1"
1510 From: richard <richard@test.test>
1511 To: issue_tracker@your.tracker.email.domain.example
1512 Message-Id: <followup_dummy_id>
1513 In-Reply-To: <dummy_test_message_id>
1514 Subject: [keyword1] Testing... [name=Bar]
1516 ''')
1517 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1519 def testResentFrom(self):
1520 nodeid = self._handle_mail('''Content-Type: text/plain;
1521 charset="iso-8859-1"
1522 From: Chef <chef@bork.bork.bork>
1523 Resent-From: mary <mary@test.test>
1524 To: issue_tracker@your.tracker.email.domain.example
1525 Cc: richard@test.test
1526 Message-Id: <dummy_test_message_id>
1527 Subject: [issue] Testing...
1529 This is a test submission of a new issue.
1530 ''')
1531 assert not os.path.exists(SENDMAILDEBUG)
1532 l = self.db.issue.get(nodeid, 'nosy')
1533 l.sort()
1534 self.assertEqual(l, [self.richard_id, self.mary_id])
1535 return nodeid
1537 def testDejaVu(self):
1538 self.assertRaises(IgnoreLoop, self._handle_mail,
1539 '''Content-Type: text/plain;
1540 charset="iso-8859-1"
1541 From: Chef <chef@bork.bork.bork>
1542 X-Roundup-Loop: hello
1543 To: issue_tracker@your.tracker.email.domain.example
1544 Cc: richard@test.test
1545 Message-Id: <dummy_test_message_id>
1546 Subject: Re: [issue] Testing...
1548 Hi, I've been mis-configured to loop messages back to myself.
1549 ''')
1551 def testItsBulkStupid(self):
1552 self.assertRaises(IgnoreBulk, self._handle_mail,
1553 '''Content-Type: text/plain;
1554 charset="iso-8859-1"
1555 From: Chef <chef@bork.bork.bork>
1556 Precedence: bulk
1557 To: issue_tracker@your.tracker.email.domain.example
1558 Cc: richard@test.test
1559 Message-Id: <dummy_test_message_id>
1560 Subject: Re: [issue] Testing...
1562 Hi, I'm on holidays, and this is a dumb auto-responder.
1563 ''')
1565 def testAutoReplyEmailsAreIgnored(self):
1566 self.assertRaises(IgnoreBulk, self._handle_mail,
1567 '''Content-Type: text/plain;
1568 charset="iso-8859-1"
1569 From: Chef <chef@bork.bork.bork>
1570 To: issue_tracker@your.tracker.email.domain.example
1571 Cc: richard@test.test
1572 Message-Id: <dummy_test_message_id>
1573 Subject: Re: [issue] Out of office AutoReply: Back next week
1575 Hi, I am back in the office next week
1576 ''')
1578 def testNoSubject(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 Cc: richard@test.test
1585 Reply-To: chef@bork.bork.bork
1586 Message-Id: <dummy_test_message_id>
1588 ''')
1590 #
1591 # TEST FOR INVALID DESIGNATOR HANDLING
1592 #
1593 def testInvalidDesignator(self):
1594 self.assertRaises(MailUsageError, self._handle_mail,
1595 '''Content-Type: text/plain;
1596 charset="iso-8859-1"
1597 From: Chef <chef@bork.bork.bork>
1598 To: issue_tracker@your.tracker.email.domain.example
1599 Subject: [frobulated] testing
1600 Cc: richard@test.test
1601 Reply-To: chef@bork.bork.bork
1602 Message-Id: <dummy_test_message_id>
1604 ''')
1605 self.assertRaises(MailUsageError, self._handle_mail,
1606 '''Content-Type: text/plain;
1607 charset="iso-8859-1"
1608 From: Chef <chef@bork.bork.bork>
1609 To: issue_tracker@your.tracker.email.domain.example
1610 Subject: [issue12345] testing
1611 Cc: richard@test.test
1612 Reply-To: chef@bork.bork.bork
1613 Message-Id: <dummy_test_message_id>
1615 ''')
1617 def testInvalidClassLoose(self):
1618 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1619 nodeid = self._handle_mail('''Content-Type: text/plain;
1620 charset="iso-8859-1"
1621 From: Chef <chef@bork.bork.bork>
1622 To: issue_tracker@your.tracker.email.domain.example
1623 Subject: [frobulated] testing
1624 Cc: richard@test.test
1625 Reply-To: chef@bork.bork.bork
1626 Message-Id: <dummy_test_message_id>
1628 ''')
1629 assert not os.path.exists(SENDMAILDEBUG)
1630 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1631 '[frobulated] testing')
1633 def testInvalidClassLooseReply(self):
1634 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1635 nodeid = self._handle_mail('''Content-Type: text/plain;
1636 charset="iso-8859-1"
1637 From: Chef <chef@bork.bork.bork>
1638 To: issue_tracker@your.tracker.email.domain.example
1639 Subject: Re: [frobulated] testing
1640 Cc: richard@test.test
1641 Reply-To: chef@bork.bork.bork
1642 Message-Id: <dummy_test_message_id>
1644 ''')
1645 assert not os.path.exists(SENDMAILDEBUG)
1646 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1647 '[frobulated] testing')
1649 def testInvalidClassLoose(self):
1650 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1651 nodeid = self._handle_mail('''Content-Type: text/plain;
1652 charset="iso-8859-1"
1653 From: Chef <chef@bork.bork.bork>
1654 To: issue_tracker@your.tracker.email.domain.example
1655 Subject: [issue1234] testing
1656 Cc: richard@test.test
1657 Reply-To: chef@bork.bork.bork
1658 Message-Id: <dummy_test_message_id>
1660 ''')
1661 assert not os.path.exists(SENDMAILDEBUG)
1662 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1663 '[issue1234] testing')
1665 def testClassLooseOK(self):
1666 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1667 self.db.keyword.create(name='Foo')
1668 nodeid = self._handle_mail('''Content-Type: text/plain;
1669 charset="iso-8859-1"
1670 From: Chef <chef@bork.bork.bork>
1671 To: issue_tracker@your.tracker.email.domain.example
1672 Subject: [keyword1] Testing... [name=Bar]
1673 Cc: richard@test.test
1674 Reply-To: chef@bork.bork.bork
1675 Message-Id: <dummy_test_message_id>
1677 ''')
1678 assert not os.path.exists(SENDMAILDEBUG)
1679 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1681 def testClassStrictInvalid(self):
1682 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'strict'
1683 self.instance.config.MAILGW_DEFAULT_CLASS = ''
1685 message = '''Content-Type: text/plain;
1686 charset="iso-8859-1"
1687 From: Chef <chef@bork.bork.bork>
1688 To: issue_tracker@your.tracker.email.domain.example
1689 Subject: Testing...
1690 Cc: richard@test.test
1691 Reply-To: chef@bork.bork.bork
1692 Message-Id: <dummy_test_message_id>
1694 '''
1695 self.assertRaises(MailUsageError, self._handle_mail, message)
1697 def testClassStrictValid(self):
1698 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'strict'
1699 self.instance.config.MAILGW_DEFAULT_CLASS = ''
1701 nodeid = self._handle_mail('''Content-Type: text/plain;
1702 charset="iso-8859-1"
1703 From: Chef <chef@bork.bork.bork>
1704 To: issue_tracker@your.tracker.email.domain.example
1705 Subject: [issue] Testing...
1706 Cc: richard@test.test
1707 Reply-To: chef@bork.bork.bork
1708 Message-Id: <dummy_test_message_id>
1710 ''')
1712 assert not os.path.exists(SENDMAILDEBUG)
1713 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'Testing...')
1715 #
1716 # TEST FOR INVALID COMMANDS HANDLING
1717 #
1718 def testInvalidCommands(self):
1719 self.assertRaises(MailUsageError, self._handle_mail,
1720 '''Content-Type: text/plain;
1721 charset="iso-8859-1"
1722 From: Chef <chef@bork.bork.bork>
1723 To: issue_tracker@your.tracker.email.domain.example
1724 Subject: testing [frobulated]
1725 Cc: richard@test.test
1726 Reply-To: chef@bork.bork.bork
1727 Message-Id: <dummy_test_message_id>
1729 ''')
1731 def testInvalidCommandPassthrough(self):
1732 self.instance.config.MAILGW_SUBJECT_SUFFIX_PARSING = 'none'
1733 nodeid = self._handle_mail('''Content-Type: text/plain;
1734 charset="iso-8859-1"
1735 From: Chef <chef@bork.bork.bork>
1736 To: issue_tracker@your.tracker.email.domain.example
1737 Subject: testing [frobulated]
1738 Cc: richard@test.test
1739 Reply-To: chef@bork.bork.bork
1740 Message-Id: <dummy_test_message_id>
1742 ''')
1743 assert not os.path.exists(SENDMAILDEBUG)
1744 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1745 'testing [frobulated]')
1747 def testInvalidCommandPassthroughLoose(self):
1748 self.instance.config.MAILGW_SUBJECT_SUFFIX_PARSING = 'loose'
1749 nodeid = self._handle_mail('''Content-Type: text/plain;
1750 charset="iso-8859-1"
1751 From: Chef <chef@bork.bork.bork>
1752 To: issue_tracker@your.tracker.email.domain.example
1753 Subject: testing [frobulated]
1754 Cc: richard@test.test
1755 Reply-To: chef@bork.bork.bork
1756 Message-Id: <dummy_test_message_id>
1758 ''')
1759 assert not os.path.exists(SENDMAILDEBUG)
1760 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1761 'testing [frobulated]')
1763 def testInvalidCommandPassthroughLooseOK(self):
1764 self.instance.config.MAILGW_SUBJECT_SUFFIX_PARSING = 'loose'
1765 nodeid = self._handle_mail('''Content-Type: text/plain;
1766 charset="iso-8859-1"
1767 From: Chef <chef@bork.bork.bork>
1768 To: issue_tracker@your.tracker.email.domain.example
1769 Subject: testing [assignedto=mary]
1770 Cc: richard@test.test
1771 Reply-To: chef@bork.bork.bork
1772 Message-Id: <dummy_test_message_id>
1774 ''')
1775 assert not os.path.exists(SENDMAILDEBUG)
1776 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'testing')
1777 self.assertEqual(self.db.issue.get(nodeid, 'assignedto'), self.mary_id)
1779 def testCommandDelimiters(self):
1780 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '{}'
1781 nodeid = self._handle_mail('''Content-Type: text/plain;
1782 charset="iso-8859-1"
1783 From: Chef <chef@bork.bork.bork>
1784 To: issue_tracker@your.tracker.email.domain.example
1785 Subject: testing {assignedto=mary}
1786 Cc: richard@test.test
1787 Reply-To: chef@bork.bork.bork
1788 Message-Id: <dummy_test_message_id>
1790 ''')
1791 assert not os.path.exists(SENDMAILDEBUG)
1792 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'testing')
1793 self.assertEqual(self.db.issue.get(nodeid, 'assignedto'), self.mary_id)
1795 def testPrefixDelimiters(self):
1796 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '{}'
1797 self.db.keyword.create(name='Foo')
1798 self._handle_mail('''Content-Type: text/plain;
1799 charset="iso-8859-1"
1800 From: richard <richard@test.test>
1801 To: issue_tracker@your.tracker.email.domain.example
1802 Message-Id: <followup_dummy_id>
1803 In-Reply-To: <dummy_test_message_id>
1804 Subject: {keyword1} Testing... {name=Bar}
1806 ''')
1807 assert not os.path.exists(SENDMAILDEBUG)
1808 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1810 def testCommandDelimitersIgnore(self):
1811 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '{}'
1812 nodeid = self._handle_mail('''Content-Type: text/plain;
1813 charset="iso-8859-1"
1814 From: Chef <chef@bork.bork.bork>
1815 To: issue_tracker@your.tracker.email.domain.example
1816 Subject: testing [assignedto=mary]
1817 Cc: richard@test.test
1818 Reply-To: chef@bork.bork.bork
1819 Message-Id: <dummy_test_message_id>
1821 ''')
1822 assert not os.path.exists(SENDMAILDEBUG)
1823 self.assertEqual(self.db.issue.get(nodeid, 'title'),
1824 'testing [assignedto=mary]')
1825 self.assertEqual(self.db.issue.get(nodeid, 'assignedto'), None)
1827 def testReplytoMatch(self):
1828 self.instance.config.MAILGW_SUBJECT_PREFIX_PARSING = 'loose'
1829 nodeid = self.doNewIssue()
1830 nodeid2 = self._handle_mail('''Content-Type: text/plain;
1831 charset="iso-8859-1"
1832 From: Chef <chef@bork.bork.bork>
1833 To: issue_tracker@your.tracker.email.domain.example
1834 Message-Id: <dummy_test_message_id2>
1835 In-Reply-To: <dummy_test_message_id>
1836 Subject: Testing...
1838 Followup message.
1839 ''')
1841 nodeid3 = self._handle_mail('''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_id3>
1846 In-Reply-To: <dummy_test_message_id2>
1847 Subject: Testing...
1849 Yet another message in the same thread/issue.
1850 ''')
1852 self.assertEqual(nodeid, nodeid2)
1853 self.assertEqual(nodeid, nodeid3)
1855 def testHelpSubject(self):
1856 message = '''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 Message-Id: <dummy_test_message_id2>
1861 In-Reply-To: <dummy_test_message_id>
1862 Subject: hElp
1865 '''
1866 self.assertRaises(MailUsageHelp, self._handle_mail, message)
1868 def testMaillistSubject(self):
1869 self.instance.config.MAILGW_SUBJECT_SUFFIX_DELIMITERS = '[]'
1870 self.db.keyword.create(name='Foo')
1871 self._handle_mail('''Content-Type: text/plain;
1872 charset="iso-8859-1"
1873 From: Chef <chef@bork.bork.bork>
1874 To: issue_tracker@your.tracker.email.domain.example
1875 Subject: [mailinglist-name] [keyword1] Testing.. [name=Bar]
1876 Cc: richard@test.test
1877 Reply-To: chef@bork.bork.bork
1878 Message-Id: <dummy_test_message_id>
1880 ''')
1882 assert not os.path.exists(SENDMAILDEBUG)
1883 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1885 def testUnknownPrefixSubject(self):
1886 self.db.keyword.create(name='Foo')
1887 self._handle_mail('''Content-Type: text/plain;
1888 charset="iso-8859-1"
1889 From: Chef <chef@bork.bork.bork>
1890 To: issue_tracker@your.tracker.email.domain.example
1891 Subject: VeryStrangeRe: [keyword1] Testing.. [name=Bar]
1892 Cc: richard@test.test
1893 Reply-To: chef@bork.bork.bork
1894 Message-Id: <dummy_test_message_id>
1896 ''')
1898 assert not os.path.exists(SENDMAILDEBUG)
1899 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
1901 def testIssueidLast(self):
1902 nodeid1 = self.doNewIssue()
1903 nodeid2 = self._handle_mail('''Content-Type: text/plain;
1904 charset="iso-8859-1"
1905 From: mary <mary@test.test>
1906 To: issue_tracker@your.tracker.email.domain.example
1907 Message-Id: <followup_dummy_id>
1908 In-Reply-To: <dummy_test_message_id>
1909 Subject: New title [issue1]
1911 This is a second followup
1912 ''')
1914 assert nodeid1 == nodeid2
1915 self.assertEqual(self.db.issue.get(nodeid2, 'title'), "Testing...")
1917 def testSecurityMessagePermissionContent(self):
1918 id = self.doNewIssue()
1919 issue = self.db.issue.getnode (id)
1920 self.db.security.addRole(name='Nomsg')
1921 self.db.security.addPermissionToRole('Nomsg', 'Email Access')
1922 for cl in 'issue', 'file', 'keyword':
1923 for p in 'View', 'Edit', 'Create':
1924 self.db.security.addPermissionToRole('Nomsg', p, cl)
1925 self.db.user.set(self.mary_id, roles='Nomsg')
1926 nodeid = self._handle_mail('''Content-Type: text/plain;
1927 charset="iso-8859-1"
1928 From: Chef <chef@bork.bork.bork>
1929 To: issue_tracker@your.tracker.email.domain.example
1930 Message-Id: <dummy_test_message_id>
1931 Subject: [issue%(id)s] Testing... [nosy=+mary]
1933 Just a test reply
1934 '''%locals())
1935 assert os.path.exists(SENDMAILDEBUG)
1936 self.compareMessages(self._get_mail(),
1937 '''FROM: roundup-admin@your.tracker.email.domain.example
1938 TO: chef@bork.bork.bork, richard@test.test
1939 Content-Type: text/plain; charset="utf-8"
1940 Subject: [issue1] Testing...
1941 To: richard@test.test
1942 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
1943 Reply-To: Roundup issue tracker
1944 <issue_tracker@your.tracker.email.domain.example>
1945 MIME-Version: 1.0
1946 Message-Id: <dummy_test_message_id>
1947 X-Roundup-Name: Roundup issue tracker
1948 X-Roundup-Loop: hello
1949 X-Roundup-Issue-Status: chatting
1950 Content-Transfer-Encoding: quoted-printable
1953 Bork, Chef <chef@bork.bork.bork> added the comment:
1955 Just a test reply
1957 ----------
1958 nosy: +mary
1959 status: unread -> chatting
1961 _______________________________________________________________________
1962 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
1963 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
1964 _______________________________________________________________________
1965 ''')
1968 def test_suite():
1969 suite = unittest.TestSuite()
1970 suite.addTest(unittest.makeSuite(MailgwTestCase))
1971 return suite
1973 if __name__ == '__main__':
1974 runner = unittest.TextTestRunner()
1975 unittest.main(testRunner=runner)
1977 # vim: set filetype=python sts=4 sw=4 et si :