comparison test/test_mailgw.py @ 4215:57dfcc824acc

fix problem with bounce-message if incoming mail has insufficient privilege... ...e.g., user not existing (issue 2550534) Added a regression test for this issue that reproduces the traceback reported in issue 2550534 I'm using a slightly modified variant of the original patch that avoids repeated string-concatenation (which could degenerate to quadratic runtime behaviour for large number of email headers).
author Ralf Schlatterbeck <schlatterbeck@users.sourceforge.net>
date Wed, 15 Jul 2009 12:22:35 +0000
parents 61cf00ca920a
children 7275e3dec0e0
comparison
equal deleted inserted replaced
4214:d5cd6f440396 4215:57dfcc824acc
49 del new['date'], old['date'] 49 del new['date'], old['date']
50 50
51 if not new == old: 51 if not new == old:
52 res = [] 52 res = []
53 53
54 replace = {}
54 for key in new.keys(): 55 for key in new.keys():
55 if key.startswith('from '): 56 if key.startswith('from '):
56 # skip the unix from line 57 # skip the unix from line
57 continue 58 continue
58 if key.lower() == 'x-roundup-version': 59 if key.lower() == 'x-roundup-version':
59 # version changes constantly, so handle it specially 60 # version changes constantly, so handle it specially
60 if new[key] != __version__: 61 if new[key] != __version__:
61 res.append(' %s: %r != %r' % (key, __version__, 62 res.append(' %s: %r != %r' % (key, __version__,
62 new[key])) 63 new[key]))
64 elif key.lower() == 'content-type' and 'boundary=' in new[key]:
65 # handle mime messages
66 newmime = new[key].split('=',1)[-1].strip('"')
67 oldmime = old.get(key, '').split('=',1)[-1].strip('"')
68 replace ['--' + newmime] = '--' + oldmime
69 replace ['--' + newmime + '--'] = '--' + oldmime + '--'
63 elif new.get(key, '') != old.get(key, ''): 70 elif new.get(key, '') != old.get(key, ''):
64 res.append(' %s: %r != %r' % (key, old.get(key, ''), 71 res.append(' %s: %r != %r' % (key, old.get(key, ''),
65 new.get(key, ''))) 72 new.get(key, '')))
66 73
67 body_diff = self.compareStrings(new.fp.read(), old.fp.read()) 74 body_diff = self.compareStrings(new.fp.read(), old.fp.read(),
75 replace=replace)
68 if body_diff: 76 if body_diff:
69 res.append('') 77 res.append('')
70 res.extend(body_diff) 78 res.extend(body_diff)
71 79
72 if res: 80 if res:
73 res.insert(0, 'Generated message not correct (diff follows):') 81 res.insert(0, 'Generated message not correct (diff follows):')
74 raise AssertionError, '\n'.join(res) 82 raise AssertionError, '\n'.join(res)
75 83
76 def compareStrings(self, s2, s1): 84 def compareStrings(self, s2, s1, replace={}):
77 '''Note the reversal of s2 and s1 - difflib.SequenceMatcher wants 85 '''Note the reversal of s2 and s1 - difflib.SequenceMatcher wants
78 the first to be the "original" but in the calls in this file, 86 the first to be the "original" but in the calls in this file,
79 the second arg is the original. Ho hum. 87 the second arg is the original. Ho hum.
88 Do replacements over the replace dict -- used for mime boundary
80 ''' 89 '''
81 l1 = s1.strip().split('\n') 90 l1 = s1.strip().split('\n')
82 l2 = s2.strip().split('\n') 91 l2 = [replace.get(i,i) for i in s2.strip().split('\n')]
83 if l1 == l2: 92 if l1 == l2:
84 return 93 return
85 s = difflib.SequenceMatcher(None, l1, l2) 94 s = difflib.SequenceMatcher(None, l1, l2)
86 res = [] 95 res = []
87 for value, s1s, s1e, s2s, s2e in s.get_opcodes(): 96 for value, s1s, s1e, s2s, s2e in s.get_opcodes():
1103 m = set(self.db.user.list()) 1112 m = set(self.db.user.list())
1104 new = list(m - l)[0] 1113 new = list(m - l)[0]
1105 name = self.db.user.get(new, 'realname') 1114 name = self.db.user.get(new, 'realname')
1106 self.assertEquals(name, 'H€llo') 1115 self.assertEquals(name, 'H€llo')
1107 1116
1117 def testUnknownUser(self):
1118 l = set(self.db.user.list())
1119 message = '''Content-Type: text/plain;
1120 charset="iso-8859-1"
1121 From: Nonexisting User <nonexisting@bork.bork.bork>
1122 To: issue_tracker@your.tracker.email.domain.example
1123 Message-Id: <dummy_test_message_id>
1124 Subject: [issue] Testing nonexisting user...
1125
1126 This is a test submission of a new issue.
1127 '''
1128 self.db.close()
1129 handler = self.instance.MailGW(self.instance)
1130 # we want a bounce message:
1131 handler.trapExceptions = 1
1132 ret = handler.main(StringIO(message))
1133 self.compareMessages(self._get_mail(),
1134 '''FROM: Roundup issue tracker <roundup-admin@your.tracker.email.domain.example>
1135 TO: nonexisting@bork.bork.bork
1136 From nobody Tue Jul 14 12:04:11 2009
1137 Content-Type: multipart/mixed; boundary="===============0639262320=="
1138 MIME-Version: 1.0
1139 Subject: Failed issue tracker submission
1140 To: nonexisting@bork.bork.bork
1141 From: Roundup issue tracker <roundup-admin@your.tracker.email.domain.example>
1142 Date: Tue, 14 Jul 2009 12:04:11 +0000
1143 Precedence: bulk
1144 X-Roundup-Name: Roundup issue tracker
1145 X-Roundup-Loop: hello
1146 X-Roundup-Version: 1.4.8
1147 MIME-Version: 1.0
1148
1149 --===============0639262320==
1150 Content-Type: text/plain; charset="us-ascii"
1151 MIME-Version: 1.0
1152 Content-Transfer-Encoding: 7bit
1153
1154
1155
1156 You are not a registered user.
1157
1158 Unknown address: nonexisting@bork.bork.bork
1159
1160 --===============0639262320==
1161 Content-Type: text/plain; charset="us-ascii"
1162 MIME-Version: 1.0
1163 Content-Transfer-Encoding: 7bit
1164
1165 Content-Type: text/plain;
1166 charset="iso-8859-1"
1167 From: Nonexisting User <nonexisting@bork.bork.bork>
1168 To: issue_tracker@your.tracker.email.domain.example
1169 Message-Id: <dummy_test_message_id>
1170 Subject: [issue] Testing nonexisting user...
1171
1172 This is a test submission of a new issue.
1173
1174 --===============0639262320==--
1175 ''')
1176
1108 def testEnc01(self): 1177 def testEnc01(self):
1109 self.doNewIssue() 1178 self.doNewIssue()
1110 self._handle_mail('''Content-Type: text/plain; 1179 self._handle_mail('''Content-Type: text/plain;
1111 charset="iso-8859-1" 1180 charset="iso-8859-1"
1112 From: mary <mary@test.test> 1181 From: mary <mary@test.test>

Roundup Issue Tracker: http://roundup-tracker.org/