7599aba9b6e2c4ee3c966ccba499c80648ba8d95
1 #
2 # Copyright (c) 2001 Richard Jones, richard@bofh.asn.au.
3 # This module is free software, and you may redistribute it and/or modify
4 # under the same terms as Python, so long as this copyright message and
5 # disclaimer are retained in their original form.
6 #
7 # This module is distributed in the hope that it will be useful,
8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 #
11 # $Id: test_mailgw.py,v 1.67 2004-04-09 01:32:58 richard Exp $
13 import unittest, tempfile, os, shutil, errno, imp, sys, difflib, rfc822
15 from cStringIO import StringIO
17 if not os.environ.has_key('SENDMAILDEBUG'):
18 os.environ['SENDMAILDEBUG'] = 'mail-test.log'
19 SENDMAILDEBUG = os.environ['SENDMAILDEBUG']
21 from roundup.mailgw import MailGW, Unauthorized, uidFromAddress, \
22 parseContent, IgnoreLoop, IgnoreBulk
23 from roundup import init, instance, rfc2822, __version__
26 class Message(rfc822.Message):
27 """String-based Message class with equivalence test."""
28 def __init__(self, s):
29 rfc822.Message.__init__(self, StringIO(s.strip()))
31 def __eq__(self, other):
32 return (self.dict == other.dict and
33 self.fp.read() == other.fp.read())
35 class DiffHelper:
36 def compareMessages(self, new, old):
37 """Compare messages for semantic equivalence."""
38 new, old = Message(new), Message(old)
39 del new['date'], old['date']
41 if not new == old:
42 res = []
44 for key in new.keys():
45 if key.lower() == 'x-roundup-version':
46 # version changes constantly, so handle it specially
47 if new[key] != __version__:
48 res.append(' %s: %s != %s' % (key, __version__,
49 new[key]))
50 elif new[key] != old[key]:
51 res.append(' %s: %s != %s' % (key, old[key], new[key]))
53 body_diff = self.compareStrings(new.fp.read(), old.fp.read())
54 if body_diff:
55 res.append('')
56 res.extend(body_diff)
58 if res:
59 res.insert(0, 'Generated message not correct (diff follows):')
60 raise AssertionError, '\n'.join(res)
62 def compareStrings(self, s2, s1):
63 '''Note the reversal of s2 and s1 - difflib.SequenceMatcher wants
64 the first to be the "original" but in the calls in this file,
65 the second arg is the original. Ho hum.
66 '''
67 l1 = s1.strip().split('\n')
68 l2 = s2.strip().split('\n')
69 if l1 == l2:
70 return
71 s = difflib.SequenceMatcher(None, l1, l2)
72 res = []
73 for value, s1s, s1e, s2s, s2e in s.get_opcodes():
74 if value == 'equal':
75 for i in range(s1s, s1e):
76 res.append(' %s'%l1[i])
77 elif value == 'delete':
78 for i in range(s1s, s1e):
79 res.append('- %s'%l1[i])
80 elif value == 'insert':
81 for i in range(s2s, s2e):
82 res.append('+ %s'%l2[i])
83 elif value == 'replace':
84 for i, j in zip(range(s1s, s1e), range(s2s, s2e)):
85 res.append('- %s'%l1[i])
86 res.append('+ %s'%l2[j])
88 return res
90 class MailgwTestCase(unittest.TestCase, DiffHelper):
91 count = 0
92 schema = 'classic'
93 def setUp(self):
94 MailgwTestCase.count = MailgwTestCase.count + 1
95 self.dirname = '_test_mailgw_%s'%self.count
96 try:
97 shutil.rmtree(self.dirname)
98 except OSError, error:
99 if error.errno not in (errno.ENOENT, errno.ESRCH): raise
100 # create the instance
101 init.install(self.dirname, 'templates/classic')
102 init.write_select_db(self.dirname, 'sqlite')
103 init.initialise(self.dirname, 'sekrit')
105 # check we can load the package
106 self.instance = instance.open(self.dirname)
108 # and open the database
109 self.db = self.instance.open('admin')
110 self.chef_id = self.db.user.create(username='Chef',
111 address='chef@bork.bork.bork', realname='Bork, Chef', roles='User')
112 self.richard_id = self.db.user.create(username='richard',
113 address='richard@test', roles='User')
114 self.mary_id = self.db.user.create(username='mary', address='mary@test',
115 roles='User', realname='Contrary, Mary')
116 self.john_id = self.db.user.create(username='john', address='john@test',
117 alternate_addresses='jondoe@test\njohn.doe@test', roles='User',
118 realname='John Doe')
120 def tearDown(self):
121 if os.path.exists(SENDMAILDEBUG):
122 os.remove(SENDMAILDEBUG)
123 self.db.close()
124 try:
125 shutil.rmtree(self.dirname)
126 except OSError, error:
127 if error.errno not in (errno.ENOENT, errno.ESRCH): raise
129 def _handle_mail(self, message):
130 handler = self.instance.MailGW(self.instance, self.db)
131 handler.trapExceptions = 0
132 ret = handler.main(StringIO(message))
133 # handler can close the db on us and open a new one
134 self.db = handler.db
135 return ret
137 def _get_mail(self):
138 f = open(SENDMAILDEBUG)
139 try:
140 return f.read()
141 finally:
142 f.close()
144 def testEmptyMessage(self):
145 nodeid = self._handle_mail('''Content-Type: text/plain;
146 charset="iso-8859-1"
147 From: Chef <chef@bork.bork.bork>
148 To: issue_tracker@your.tracker.email.domain.example
149 Cc: richard@test
150 Reply-To: chef@bork.bork.bork
151 Message-Id: <dummy_test_message_id>
152 Subject: [issue] Testing...
154 ''')
155 assert not os.path.exists(SENDMAILDEBUG)
156 self.assertEqual(self.db.issue.get(nodeid, 'title'), 'Testing...')
158 def doNewIssue(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
164 Message-Id: <dummy_test_message_id>
165 Subject: [issue] Testing...
167 This is a test submission of a new issue.
168 ''')
169 assert not os.path.exists(SENDMAILDEBUG)
170 l = self.db.issue.get(nodeid, 'nosy')
171 l.sort()
172 self.assertEqual(l, [self.chef_id, self.richard_id])
173 return nodeid
175 def testNewIssue(self):
176 self.doNewIssue()
178 def testNewIssueNosy(self):
179 self.instance.config.ADD_AUTHOR_TO_NOSY = 'yes'
180 nodeid = self._handle_mail('''Content-Type: text/plain;
181 charset="iso-8859-1"
182 From: Chef <chef@bork.bork.bork>
183 To: issue_tracker@your.tracker.email.domain.example
184 Cc: richard@test
185 Message-Id: <dummy_test_message_id>
186 Subject: [issue] Testing...
188 This is a test submission of a new issue.
189 ''')
190 assert not os.path.exists(SENDMAILDEBUG)
191 l = self.db.issue.get(nodeid, 'nosy')
192 l.sort()
193 self.assertEqual(l, [self.chef_id, self.richard_id])
195 def testAlternateAddress(self):
196 self._handle_mail('''Content-Type: text/plain;
197 charset="iso-8859-1"
198 From: John Doe <john.doe@test>
199 To: issue_tracker@your.tracker.email.domain.example
200 Message-Id: <dummy_test_message_id>
201 Subject: [issue] Testing...
203 This is a test submission of a new issue.
204 ''')
205 userlist = self.db.user.list()
206 assert not os.path.exists(SENDMAILDEBUG)
207 self.assertEqual(userlist, self.db.user.list(),
208 "user created when it shouldn't have been")
210 def testNewIssueNoClass(self):
211 self._handle_mail('''Content-Type: text/plain;
212 charset="iso-8859-1"
213 From: Chef <chef@bork.bork.bork>
214 To: issue_tracker@your.tracker.email.domain.example
215 Cc: richard@test
216 Message-Id: <dummy_test_message_id>
217 Subject: Testing...
219 This is a test submission of a new issue.
220 ''')
221 assert not os.path.exists(SENDMAILDEBUG)
223 def testNewIssueAuthMsg(self):
224 # TODO: fix the damn config - this is apalling
225 self.db.config.MESSAGES_TO_AUTHOR = 'yes'
226 self._handle_mail('''Content-Type: text/plain;
227 charset="iso-8859-1"
228 From: Chef <chef@bork.bork.bork>
229 To: issue_tracker@your.tracker.email.domain.example
230 Message-Id: <dummy_test_message_id>
231 Subject: [issue] Testing... [nosy=mary; assignedto=richard]
233 This is a test submission of a new issue.
234 ''')
235 self.compareMessages(self._get_mail(),
236 '''FROM: roundup-admin@your.tracker.email.domain.example
237 TO: chef@bork.bork.bork, mary@test, richard@test
238 Content-Type: text/plain; charset=utf-8
239 Subject: [issue1] Testing...
240 To: chef@bork.bork.bork, mary@test, richard@test
241 From: "Bork, Chef" <issue_tracker@your.tracker.email.domain.example>
242 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
243 MIME-Version: 1.0
244 Message-Id: <dummy_test_message_id>
245 X-Roundup-Name: Roundup issue tracker
246 X-Roundup-Loop: hello
247 Content-Transfer-Encoding: quoted-printable
250 New submission from Bork, Chef <chef@bork.bork.bork>:
252 This is a test submission of a new issue.
254 ----------
255 assignedto: richard
256 messages: 1
257 nosy: Chef, mary, richard
258 status: unread
259 title: Testing...
261 _______________________________________________________________________
262 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
263 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
264 _______________________________________________________________________
265 ''')
267 # BUG
268 # def testMultipart(self):
269 # '''With more than one part'''
270 # see MultipartEnc tests: but if there is more than one part
271 # we return a multipart/mixed and the boundary contains
272 # the ip address of the test machine.
274 # BUG should test some binary attamchent too.
276 def testSimpleFollowup(self):
277 self.doNewIssue()
278 self._handle_mail('''Content-Type: text/plain;
279 charset="iso-8859-1"
280 From: mary <mary@test>
281 To: issue_tracker@your.tracker.email.domain.example
282 Message-Id: <followup_dummy_id>
283 In-Reply-To: <dummy_test_message_id>
284 Subject: [issue1] Testing...
286 This is a second followup
287 ''')
288 self.compareMessages(self._get_mail(),
289 '''FROM: roundup-admin@your.tracker.email.domain.example
290 TO: chef@bork.bork.bork, richard@test
291 Content-Type: text/plain; charset=utf-8
292 Subject: [issue1] Testing...
293 To: chef@bork.bork.bork, richard@test
294 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
295 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
296 MIME-Version: 1.0
297 Message-Id: <followup_dummy_id>
298 In-Reply-To: <dummy_test_message_id>
299 X-Roundup-Name: Roundup issue tracker
300 X-Roundup-Loop: hello
301 Content-Transfer-Encoding: quoted-printable
304 Contrary, Mary <mary@test> added the comment:
306 This is a second followup
308 ----------
309 status: unread -> chatting
311 _______________________________________________________________________
312 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
313 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
314 _______________________________________________________________________
315 ''')
317 def testFollowup(self):
318 self.doNewIssue()
320 self._handle_mail('''Content-Type: text/plain;
321 charset="iso-8859-1"
322 From: richard <richard@test>
323 To: issue_tracker@your.tracker.email.domain.example
324 Message-Id: <followup_dummy_id>
325 In-Reply-To: <dummy_test_message_id>
326 Subject: [issue1] Testing... [assignedto=mary; nosy=+john]
328 This is a followup
329 ''')
330 l = self.db.issue.get('1', 'nosy')
331 l.sort()
332 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
333 self.john_id])
335 self.compareMessages(self._get_mail(),
336 '''FROM: roundup-admin@your.tracker.email.domain.example
337 TO: chef@bork.bork.bork, john@test, mary@test
338 Content-Type: text/plain; charset=utf-8
339 Subject: [issue1] Testing...
340 To: chef@bork.bork.bork, john@test, mary@test
341 From: richard <issue_tracker@your.tracker.email.domain.example>
342 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
343 MIME-Version: 1.0
344 Message-Id: <followup_dummy_id>
345 In-Reply-To: <dummy_test_message_id>
346 X-Roundup-Name: Roundup issue tracker
347 X-Roundup-Loop: hello
348 Content-Transfer-Encoding: quoted-printable
351 richard <richard@test> added the comment:
353 This is a followup
355 ----------
356 assignedto: -> mary
357 nosy: +john, mary
358 status: unread -> chatting
360 _______________________________________________________________________
361 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
362 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
363 _______________________________________________________________________
364 ''')
366 def testFollowupTitleMatch(self):
367 self.doNewIssue()
368 self._handle_mail('''Content-Type: text/plain;
369 charset="iso-8859-1"
370 From: richard <richard@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: Re: Testing... [assignedto=mary; nosy=+john]
376 This is a followup
377 ''')
378 self.compareMessages(self._get_mail(),
379 '''FROM: roundup-admin@your.tracker.email.domain.example
380 TO: chef@bork.bork.bork, john@test, mary@test
381 Content-Type: text/plain; charset=utf-8
382 Subject: [issue1] Testing...
383 To: chef@bork.bork.bork, john@test, mary@test
384 From: richard <issue_tracker@your.tracker.email.domain.example>
385 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
386 MIME-Version: 1.0
387 Message-Id: <followup_dummy_id>
388 In-Reply-To: <dummy_test_message_id>
389 X-Roundup-Name: Roundup issue tracker
390 X-Roundup-Loop: hello
391 Content-Transfer-Encoding: quoted-printable
394 richard <richard@test> added the comment:
396 This is a followup
398 ----------
399 assignedto: -> mary
400 nosy: +john, mary
401 status: unread -> chatting
403 _______________________________________________________________________
404 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
405 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
406 _______________________________________________________________________
407 ''')
409 def testFollowupNosyAuthor(self):
410 self.doNewIssue()
411 self.db.config.ADD_AUTHOR_TO_NOSY = 'yes'
412 self._handle_mail('''Content-Type: text/plain;
413 charset="iso-8859-1"
414 From: john@test
415 To: issue_tracker@your.tracker.email.domain.example
416 Message-Id: <followup_dummy_id>
417 In-Reply-To: <dummy_test_message_id>
418 Subject: [issue1] Testing...
420 This is a followup
421 ''')
423 self.compareMessages(self._get_mail(),
424 '''FROM: roundup-admin@your.tracker.email.domain.example
425 TO: chef@bork.bork.bork, richard@test
426 Content-Type: text/plain; charset=utf-8
427 Subject: [issue1] Testing...
428 To: chef@bork.bork.bork, richard@test
429 From: John Doe <issue_tracker@your.tracker.email.domain.example>
430 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
431 MIME-Version: 1.0
432 Message-Id: <followup_dummy_id>
433 In-Reply-To: <dummy_test_message_id>
434 X-Roundup-Name: Roundup issue tracker
435 X-Roundup-Loop: hello
436 Content-Transfer-Encoding: quoted-printable
439 John Doe <john@test> added the comment:
441 This is a followup
443 ----------
444 nosy: +john
445 status: unread -> chatting
447 _______________________________________________________________________
448 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
449 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
450 _______________________________________________________________________
452 ''')
454 def testFollowupNosyRecipients(self):
455 self.doNewIssue()
456 self.db.config.ADD_RECIPIENTS_TO_NOSY = 'yes'
457 self._handle_mail('''Content-Type: text/plain;
458 charset="iso-8859-1"
459 From: richard@test
460 To: issue_tracker@your.tracker.email.domain.example
461 Cc: john@test
462 Message-Id: <followup_dummy_id>
463 In-Reply-To: <dummy_test_message_id>
464 Subject: [issue1] Testing...
466 This is a followup
467 ''')
468 self.compareMessages(self._get_mail(),
469 '''FROM: roundup-admin@your.tracker.email.domain.example
470 TO: chef@bork.bork.bork
471 Content-Type: text/plain; charset=utf-8
472 Subject: [issue1] Testing...
473 To: chef@bork.bork.bork
474 From: richard <issue_tracker@your.tracker.email.domain.example>
475 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
476 MIME-Version: 1.0
477 Message-Id: <followup_dummy_id>
478 In-Reply-To: <dummy_test_message_id>
479 X-Roundup-Name: Roundup issue tracker
480 X-Roundup-Loop: hello
481 Content-Transfer-Encoding: quoted-printable
484 richard <richard@test> added the comment:
486 This is a followup
488 ----------
489 nosy: +john
490 status: unread -> chatting
492 _______________________________________________________________________
493 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
494 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
495 _______________________________________________________________________
497 ''')
499 def testFollowupNosyAuthorAndCopy(self):
500 self.doNewIssue()
501 self.db.config.ADD_AUTHOR_TO_NOSY = 'yes'
502 self.db.config.MESSAGES_TO_AUTHOR = 'yes'
503 self._handle_mail('''Content-Type: text/plain;
504 charset="iso-8859-1"
505 From: john@test
506 To: issue_tracker@your.tracker.email.domain.example
507 Message-Id: <followup_dummy_id>
508 In-Reply-To: <dummy_test_message_id>
509 Subject: [issue1] Testing...
511 This is a followup
512 ''')
513 self.compareMessages(self._get_mail(),
514 '''FROM: roundup-admin@your.tracker.email.domain.example
515 TO: chef@bork.bork.bork, john@test, richard@test
516 Content-Type: text/plain; charset=utf-8
517 Subject: [issue1] Testing...
518 To: chef@bork.bork.bork, john@test, richard@test
519 From: John Doe <issue_tracker@your.tracker.email.domain.example>
520 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
521 MIME-Version: 1.0
522 Message-Id: <followup_dummy_id>
523 In-Reply-To: <dummy_test_message_id>
524 X-Roundup-Name: Roundup issue tracker
525 X-Roundup-Loop: hello
526 Content-Transfer-Encoding: quoted-printable
529 John Doe <john@test> added the comment:
531 This is a followup
533 ----------
534 nosy: +john
535 status: unread -> chatting
537 _______________________________________________________________________
538 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
539 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
540 _______________________________________________________________________
542 ''')
544 def testFollowupNoNosyAuthor(self):
545 self.doNewIssue()
546 self.instance.config.ADD_AUTHOR_TO_NOSY = 'no'
547 self._handle_mail('''Content-Type: text/plain;
548 charset="iso-8859-1"
549 From: john@test
550 To: issue_tracker@your.tracker.email.domain.example
551 Message-Id: <followup_dummy_id>
552 In-Reply-To: <dummy_test_message_id>
553 Subject: [issue1] Testing...
555 This is a followup
556 ''')
557 self.compareMessages(self._get_mail(),
558 '''FROM: roundup-admin@your.tracker.email.domain.example
559 TO: chef@bork.bork.bork, richard@test
560 Content-Type: text/plain; charset=utf-8
561 Subject: [issue1] Testing...
562 To: chef@bork.bork.bork, richard@test
563 From: John Doe <issue_tracker@your.tracker.email.domain.example>
564 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
565 MIME-Version: 1.0
566 Message-Id: <followup_dummy_id>
567 In-Reply-To: <dummy_test_message_id>
568 X-Roundup-Name: Roundup issue tracker
569 X-Roundup-Loop: hello
570 Content-Transfer-Encoding: quoted-printable
573 John Doe <john@test> added the comment:
575 This is a followup
577 ----------
578 status: unread -> chatting
580 _______________________________________________________________________
581 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
582 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
583 _______________________________________________________________________
585 ''')
587 def testFollowupNoNosyRecipients(self):
588 self.doNewIssue()
589 self.instance.config.ADD_RECIPIENTS_TO_NOSY = 'no'
590 self._handle_mail('''Content-Type: text/plain;
591 charset="iso-8859-1"
592 From: richard@test
593 To: issue_tracker@your.tracker.email.domain.example
594 Cc: john@test
595 Message-Id: <followup_dummy_id>
596 In-Reply-To: <dummy_test_message_id>
597 Subject: [issue1] Testing...
599 This is a followup
600 ''')
601 self.compareMessages(self._get_mail(),
602 '''FROM: roundup-admin@your.tracker.email.domain.example
603 TO: chef@bork.bork.bork
604 Content-Type: text/plain; charset=utf-8
605 Subject: [issue1] Testing...
606 To: chef@bork.bork.bork
607 From: richard <issue_tracker@your.tracker.email.domain.example>
608 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
609 MIME-Version: 1.0
610 Message-Id: <followup_dummy_id>
611 In-Reply-To: <dummy_test_message_id>
612 X-Roundup-Name: Roundup issue tracker
613 X-Roundup-Loop: hello
614 Content-Transfer-Encoding: quoted-printable
617 richard <richard@test> added the comment:
619 This is a followup
621 ----------
622 status: unread -> chatting
624 _______________________________________________________________________
625 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
626 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
627 _______________________________________________________________________
629 ''')
631 def testFollowupEmptyMessage(self):
632 self.doNewIssue()
634 self._handle_mail('''Content-Type: text/plain;
635 charset="iso-8859-1"
636 From: richard <richard@test>
637 To: issue_tracker@your.tracker.email.domain.example
638 Message-Id: <followup_dummy_id>
639 In-Reply-To: <dummy_test_message_id>
640 Subject: [issue1] Testing... [assignedto=mary; nosy=+john]
642 ''')
643 l = self.db.issue.get('1', 'nosy')
644 l.sort()
645 self.assertEqual(l, [self.chef_id, self.richard_id, self.mary_id,
646 self.john_id])
648 # should be no file created (ie. no message)
649 assert not os.path.exists(SENDMAILDEBUG)
651 def testNosyRemove(self):
652 self.doNewIssue()
654 self._handle_mail('''Content-Type: text/plain;
655 charset="iso-8859-1"
656 From: richard <richard@test>
657 To: issue_tracker@your.tracker.email.domain.example
658 Message-Id: <followup_dummy_id>
659 In-Reply-To: <dummy_test_message_id>
660 Subject: [issue1] Testing... [nosy=-richard]
662 ''')
663 l = self.db.issue.get('1', 'nosy')
664 l.sort()
665 self.assertEqual(l, [self.chef_id])
667 # NO NOSY MESSAGE SHOULD BE SENT!
668 assert not os.path.exists(SENDMAILDEBUG)
670 def testNewUserAuthor(self):
671 # first without the permission
672 # heh... just ignore the API for a second ;)
673 self.db.security.role['anonymous'].permissions=[]
674 anonid = self.db.user.lookup('anonymous')
675 self.db.user.set(anonid, roles='Anonymous')
677 self.db.security.hasPermission('Email Registration', anonid)
678 l = self.db.user.list()
679 l.sort()
680 message = '''Content-Type: text/plain;
681 charset="iso-8859-1"
682 From: fubar <fubar@bork.bork.bork>
683 To: issue_tracker@your.tracker.email.domain.example
684 Message-Id: <dummy_test_message_id>
685 Subject: [issue] Testing...
687 This is a test submission of a new issue.
688 '''
689 self.assertRaises(Unauthorized, self._handle_mail, message)
690 m = self.db.user.list()
691 m.sort()
692 self.assertEqual(l, m)
694 # now with the permission
695 p = self.db.security.getPermission('Email Registration')
696 self.db.security.role['anonymous'].permissions=[p]
697 self._handle_mail(message)
698 m = self.db.user.list()
699 m.sort()
700 self.assertNotEqual(l, m)
702 def testEnc01(self):
703 self.doNewIssue()
704 self._handle_mail('''Content-Type: text/plain;
705 charset="iso-8859-1"
706 From: mary <mary@test>
707 To: issue_tracker@your.tracker.email.domain.example
708 Message-Id: <followup_dummy_id>
709 In-Reply-To: <dummy_test_message_id>
710 Subject: [issue1] Testing...
711 Content-Type: text/plain;
712 charset="iso-8859-1"
713 Content-Transfer-Encoding: quoted-printable
715 A message with encoding (encoded oe =F6)
717 ''')
718 self.compareMessages(self._get_mail(),
719 '''FROM: roundup-admin@your.tracker.email.domain.example
720 TO: chef@bork.bork.bork, richard@test
721 Content-Type: text/plain; charset=utf-8
722 Subject: [issue1] Testing...
723 To: chef@bork.bork.bork, richard@test
724 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
725 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
726 MIME-Version: 1.0
727 Message-Id: <followup_dummy_id>
728 In-Reply-To: <dummy_test_message_id>
729 X-Roundup-Name: Roundup issue tracker
730 X-Roundup-Loop: hello
731 Content-Transfer-Encoding: quoted-printable
734 Contrary, Mary <mary@test> added the comment:
736 A message with encoding (encoded oe =C3=B6)
738 ----------
739 status: unread -> chatting
741 _______________________________________________________________________
742 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
743 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
744 _______________________________________________________________________
745 ''')
748 def testMultipartEnc01(self):
749 self.doNewIssue()
750 self._handle_mail('''Content-Type: text/plain;
751 charset="iso-8859-1"
752 From: mary <mary@test>
753 To: issue_tracker@your.tracker.email.domain.example
754 Message-Id: <followup_dummy_id>
755 In-Reply-To: <dummy_test_message_id>
756 Subject: [issue1] Testing...
757 Content-Type: multipart/mixed;
758 boundary="----_=_NextPart_000_01"
760 This message is in MIME format. Since your mail reader does not understand
761 this format, some or all of this message may not be legible.
763 ------_=_NextPart_000_01
764 Content-Type: text/plain;
765 charset="iso-8859-1"
766 Content-Transfer-Encoding: quoted-printable
768 A message with first part encoded (encoded oe =F6)
770 ''')
771 self.compareMessages(self._get_mail(),
772 '''FROM: roundup-admin@your.tracker.email.domain.example
773 TO: chef@bork.bork.bork, richard@test
774 Content-Type: text/plain; charset=utf-8
775 Subject: [issue1] Testing...
776 To: chef@bork.bork.bork, richard@test
777 From: "Contrary, Mary" <issue_tracker@your.tracker.email.domain.example>
778 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
779 MIME-Version: 1.0
780 Message-Id: <followup_dummy_id>
781 In-Reply-To: <dummy_test_message_id>
782 X-Roundup-Name: Roundup issue tracker
783 X-Roundup-Loop: hello
784 Content-Transfer-Encoding: quoted-printable
787 Contrary, Mary <mary@test> added the comment:
789 A message with first part encoded (encoded oe =C3=B6)
791 ----------
792 status: unread -> chatting
794 _______________________________________________________________________
795 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
796 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
797 _______________________________________________________________________
798 ''')
800 def testContentDisposition(self):
801 self.doNewIssue()
802 self._handle_mail('''Content-Type: text/plain;
803 charset="iso-8859-1"
804 From: mary <mary@test>
805 To: issue_tracker@your.tracker.email.domain.example
806 Message-Id: <followup_dummy_id>
807 In-Reply-To: <dummy_test_message_id>
808 Subject: [issue1] Testing...
809 Content-Type: multipart/mixed; boundary="bCsyhTFzCvuiizWE"
810 Content-Disposition: inline
813 --bCsyhTFzCvuiizWE
814 Content-Type: text/plain; charset=us-ascii
815 Content-Disposition: inline
817 test attachment binary
819 --bCsyhTFzCvuiizWE
820 Content-Type: application/octet-stream
821 Content-Disposition: attachment; filename="main.dvi"
823 xxxxxx
825 --bCsyhTFzCvuiizWE--
826 ''')
827 messages = self.db.issue.get('1', 'messages')
828 messages.sort()
829 file = self.db.msg.get(messages[-1], 'files')[0]
830 self.assertEqual(self.db.file.get(file, 'name'), 'main.dvi')
832 def testFollowupStupidQuoting(self):
833 self.doNewIssue()
835 self._handle_mail('''Content-Type: text/plain;
836 charset="iso-8859-1"
837 From: richard <richard@test>
838 To: issue_tracker@your.tracker.email.domain.example
839 Message-Id: <followup_dummy_id>
840 In-Reply-To: <dummy_test_message_id>
841 Subject: Re: "[issue1] Testing... "
843 This is a followup
844 ''')
845 self.compareMessages(self._get_mail(),
846 '''FROM: roundup-admin@your.tracker.email.domain.example
847 TO: chef@bork.bork.bork
848 Content-Type: text/plain; charset=utf-8
849 Subject: [issue1] Testing...
850 To: chef@bork.bork.bork
851 From: richard <issue_tracker@your.tracker.email.domain.example>
852 Reply-To: Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
853 MIME-Version: 1.0
854 Message-Id: <followup_dummy_id>
855 In-Reply-To: <dummy_test_message_id>
856 X-Roundup-Name: Roundup issue tracker
857 X-Roundup-Loop: hello
858 Content-Transfer-Encoding: quoted-printable
861 richard <richard@test> added the comment:
863 This is a followup
865 ----------
866 status: unread -> chatting
868 _______________________________________________________________________
869 Roundup issue tracker <issue_tracker@your.tracker.email.domain.example>
870 <http://tracker.example/cgi-bin/roundup.cgi/bugs/issue1>
871 _______________________________________________________________________
872 ''')
874 def testEmailQuoting(self):
875 self.instance.config.EMAIL_KEEP_QUOTED_TEXT = 'no'
876 self.innerTestQuoting('''This is a followup
877 ''')
879 def testEmailQuotingRemove(self):
880 self.instance.config.EMAIL_KEEP_QUOTED_TEXT = 'yes'
881 self.innerTestQuoting('''Blah blah wrote:
882 > Blah bklaskdfj sdf asdf jlaskdf skj sdkfjl asdf
883 > skdjlkjsdfalsdkfjasdlfkj dlfksdfalksd fj
884 >
886 This is a followup
887 ''')
889 def innerTestQuoting(self, expect):
890 nodeid = self.doNewIssue()
892 messages = self.db.issue.get(nodeid, 'messages')
894 self._handle_mail('''Content-Type: text/plain;
895 charset="iso-8859-1"
896 From: richard <richard@test>
897 To: issue_tracker@your.tracker.email.domain.example
898 Message-Id: <followup_dummy_id>
899 In-Reply-To: <dummy_test_message_id>
900 Subject: Re: [issue1] Testing...
902 Blah blah wrote:
903 > Blah bklaskdfj sdf asdf jlaskdf skj sdkfjl asdf
904 > skdjlkjsdfalsdkfjasdlfkj dlfksdfalksd fj
905 >
907 This is a followup
908 ''')
909 # figure the new message id
910 newmessages = self.db.issue.get(nodeid, 'messages')
911 for msg in messages:
912 newmessages.remove(msg)
913 messageid = newmessages[0]
915 self.compareMessages(self.db.msg.get(messageid, 'content'), expect)
917 def testUserLookup(self):
918 i = self.db.user.create(username='user1', address='user1@foo.com')
919 self.assertEqual(uidFromAddress(self.db, ('', 'user1@foo.com'), 0), i)
920 self.assertEqual(uidFromAddress(self.db, ('', 'USER1@foo.com'), 0), i)
921 i = self.db.user.create(username='user2', address='USER2@foo.com')
922 self.assertEqual(uidFromAddress(self.db, ('', 'USER2@foo.com'), 0), i)
923 self.assertEqual(uidFromAddress(self.db, ('', 'user2@foo.com'), 0), i)
925 def testUserAlternateLookup(self):
926 i = self.db.user.create(username='user1', address='user1@foo.com',
927 alternate_addresses='user1@bar.com')
928 self.assertEqual(uidFromAddress(self.db, ('', 'user1@bar.com'), 0), i)
929 self.assertEqual(uidFromAddress(self.db, ('', 'USER1@bar.com'), 0), i)
931 def testUserCreate(self):
932 i = uidFromAddress(self.db, ('', 'user@foo.com'), 1)
933 self.assertNotEqual(uidFromAddress(self.db, ('', 'user@bar.com'), 1), i)
935 def testRFC2822(self):
936 ascii_header = "[issue243] This is a \"test\" - with 'quotation' marks"
937 unicode_header = '[issue244] \xd0\xb0\xd0\xbd\xd0\xb4\xd1\x80\xd0\xb5\xd0\xb9'
938 unicode_encoded = '=?utf-8?q?[issue244]_=D0=B0=D0=BD=D0=B4=D1=80=D0=B5=D0=B9?='
939 self.assertEqual(rfc2822.encode_header(ascii_header), ascii_header)
940 self.assertEqual(rfc2822.encode_header(unicode_header), unicode_encoded)
942 def testRegistrationConfirmation(self):
943 otk = "Aj4euk4LZSAdwePohj90SME5SpopLETL"
944 self.db.getOTKManager().set(otk, username='johannes')
945 self._handle_mail('''Content-Type: text/plain;
946 charset="iso-8859-1"
947 From: Chef <chef@bork.bork.bork>
948 To: issue_tracker@your.tracker.email.domain.example
949 Cc: richard@test
950 Message-Id: <dummy_test_message_id>
951 Subject: Re: Complete your registration to Roundup issue tracker\r
952 -- key %s
954 This is a test confirmation of registration.
955 ''' % otk)
956 self.db.user.lookup('johannes')
958 def testFollowupOnNonIssue(self):
959 self.db.keyword.create(name='Foo')
960 self._handle_mail('''Content-Type: text/plain;
961 charset="iso-8859-1"
962 From: richard <richard@test>
963 To: issue_tracker@your.tracker.email.domain.example
964 Message-Id: <followup_dummy_id>
965 In-Reply-To: <dummy_test_message_id>
966 Subject: [keyword1] Testing... [name=Bar]
968 ''')
969 self.assertEqual(self.db.keyword.get('1', 'name'), 'Bar')
971 def testResentFrom(self):
972 nodeid = self._handle_mail('''Content-Type: text/plain;
973 charset="iso-8859-1"
974 From: Chef <chef@bork.bork.bork>
975 Resent-From: mary <mary@test>
976 To: issue_tracker@your.tracker.email.domain.example
977 Cc: richard@test
978 Message-Id: <dummy_test_message_id>
979 Subject: [issue] Testing...
981 This is a test submission of a new issue.
982 ''')
983 assert not os.path.exists(SENDMAILDEBUG)
984 l = self.db.issue.get(nodeid, 'nosy')
985 l.sort()
986 self.assertEqual(l, [self.richard_id, self.mary_id])
987 return nodeid
990 def testDejaVu(self):
991 self.assertRaises(IgnoreLoop, self._handle_mail,
992 '''Content-Type: text/plain;
993 charset="iso-8859-1"
994 From: Chef <chef@bork.bork.bork>
995 X-Roundup-Loop: hello
996 To: issue_tracker@your.tracker.email.domain.example
997 Cc: richard@test
998 Message-Id: <dummy_test_message_id>
999 Subject: Re: [issue] Testing...
1001 Hi, I've been mis-configured to loop messages back to myself.
1002 ''')
1004 def testItsBulkStupid(self):
1005 self.assertRaises(IgnoreBulk, self._handle_mail,
1006 '''Content-Type: text/plain;
1007 charset="iso-8859-1"
1008 From: Chef <chef@bork.bork.bork>
1009 Precedence: bulk
1010 To: issue_tracker@your.tracker.email.domain.example
1011 Cc: richard@test
1012 Message-Id: <dummy_test_message_id>
1013 Subject: Re: [issue] Testing...
1015 Hi, I'm on holidays, and this is a dumb auto-responder.
1016 ''')
1018 def test_suite():
1019 suite = unittest.TestSuite()
1020 suite.addTest(unittest.makeSuite(MailgwTestCase))
1021 return suite
1023 if __name__ == '__main__':
1024 runner = unittest.TextTestRunner()
1025 unittest.main(testRunner=runner)
1027 # vim: set filetype=python ts=4 sw=4 et si