Skip to content

Commit 4bfd32d

Browse files
committed
issue2551413 - Broken MultiLink columns in CSV export (take 2)
Changed how I solved this. Restored the original line that cmeerw took out, but use the 'id' field rather than the 'name' field. The if statements folowing the line change it to the 'name' field (realname if it's a user object): if there is one. Updated the tests to test for this error and exercise the code. I had to change the test to create/add messages to an issue. This required that I suppress the sending of nosy messages using SENDMAILDEBUG env var.
1 parent 6a05a1d commit 4bfd32d

File tree

2 files changed

+30
-15
lines changed

2 files changed

+30
-15
lines changed

roundup/cgi/actions.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1688,17 +1688,16 @@ def fct(arg):
16881688
if isinstance(props[col], hyperdb.Multilink):
16891689
cname = props[col].classname
16901690
cclass = self.db.getclass(cname)
1691+
# Use id by default to handle cases like messages
1692+
# which have no useful label field issue2551413
1693+
represent[col] = repr_list(cclass, 'id')
16911694
if not self.hasPermission(self.permissionType, classname=cname):
16921695
represent[col] = repr_no_right(cclass, 'name')
16931696
else:
16941697
if 'name' in cclass.getprops():
16951698
represent[col] = repr_list(cclass, 'name')
16961699
elif cname == 'user':
16971700
represent[col] = repr_list(cclass, 'realname')
1698-
else:
1699-
# handle cases like messages which have no
1700-
# useful label field issue2551413
1701-
represent[col] = repr_list(cclass, 'id')
17021701
if isinstance(props[col], hyperdb.Link):
17031702
cname = props[col].classname
17041703
cclass = self.db.getclass(cname)

test/test_cgi.py

Lines changed: 27 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,12 @@ def testAddMessageNoEscape(self):
108108
class testCsvExport(object):
109109

110110
def testCSVExportBase(self):
111+
if 'SENDMAILDEBUG' not in os.environ:
112+
os.environ['SENDMAILDEBUG'] = 'mail-test1.log'
113+
SENDMAILDEBUG = os.environ['SENDMAILDEBUG']
114+
111115
cl = self._make_client(
112-
{'@columns': 'id,title,status,keyword,assignedto,nosy,creation'},
116+
{'@columns': 'id,title,status,keyword,assignedto,nosy,creation,messages'},
113117
nodeid=None, userid='1')
114118
cl.classname = 'issue'
115119

@@ -127,19 +131,26 @@ def dummyClosure(adate=None, translator=None):
127131
return dummyClosure
128132
date.Date = dummyDate()
129133

134+
a_msg = self.db.msg.create(content="23a", author="4",
135+
messageid="xyzzy@there",
136+
recipients=['3'])
137+
b_msg = self.db.msg.create(content="23b", author="3",
138+
messageid="xyzzy@here",
139+
recipients=['4'])
140+
130141
self.db.issue.create(title='foo1', status='2', assignedto='4', nosy=['3',demo_id])
131142
self.db.issue.create(title='bar2', status='1', assignedto='3', keyword=[key_id1,key_id2])
132-
self.db.issue.create(title='baz32', status='4')
143+
self.db.issue.create(title='baz32', status='4', messages=[a_msg, b_msg])
144+
133145
output = io.BytesIO()
134146
cl.request = MockNull()
135147
cl.request.wfile = output
136148
# call export version that outputs names
137149
actions.ExportCSVAction(cl).handle()
138-
should_be=(s2b('"id","title","status","keyword","assignedto","nosy","creation"\r\n'
139-
'"1","foo1","deferred","","Contrary, Mary","Bork, Chef;Contrary, Mary;demo","2000-06-26 00:34"\r\n'
140-
'"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef","2000-06-26 00:34"\r\n'
141-
'"3","baz32","need-eg","","","","2000-06-26 00:34"\r\n'))
142-
150+
should_be=(s2b('"id","title","status","keyword","assignedto","nosy","creation","messages"\r\n'
151+
'"1","foo1","deferred","","Contrary, Mary","Bork, Chef;Contrary, Mary;demo","2000-06-26 00:34",""\r\n'
152+
'"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef","2000-06-26 00:34",""\r\n'
153+
'"3","baz32","need-eg","","","Bork, Chef;Contrary, Mary","2000-06-26 00:34","1;2"\r\n'))
143154

144155
#print(should_be)
145156
#print(output.getvalue())
@@ -149,10 +160,10 @@ def dummyClosure(adate=None, translator=None):
149160
cl.request.wfile = output
150161
# call export version that outputs id numbers
151162
actions.ExportCSVWithIdAction(cl).handle()
152-
should_be = s2b('"id","title","status","keyword","assignedto","nosy","creation"\r\n'
153-
'''"1","foo1","2","[]","4","['3', '4', '5']","2000-06-26.00:34:02"\r\n'''
154-
'''"2","bar2","1","['1', '2']","3","['3']","2000-06-26.00:34:02"\r\n'''
155-
'''"3","baz32","4","[]","None","[]","2000-06-26.00:34:02"\r\n''')
163+
should_be = s2b('"id","title","status","keyword","assignedto","nosy","creation","messages"\r\n'
164+
'''"1","foo1","2","[]","4","['3', '4', '5']","2000-06-26.00:34:02","[]"\r\n'''
165+
'''"2","bar2","1","['1', '2']","3","['3']","2000-06-26.00:34:02","[]"\r\n'''
166+
'''"3","baz32","4","[]","None","['3', '4']","2000-06-26.00:34:02","['1', '2']"\r\n''')
156167
#print(should_be)
157168
#print(output.getvalue())
158169
self.assertEqual(output.getvalue(), should_be)
@@ -184,6 +195,11 @@ def dummyClosure(adate=None, translator=None):
184195
"\"2\",\"bar2\",\"1\",\"['1', '2']\",\"3\",\"['3']\"\r\n")
185196
self.assertEqual(output.getvalue(), should_be)
186197

198+
# clean up from email log
199+
if os.path.exists(SENDMAILDEBUG):
200+
os.remove(SENDMAILDEBUG)
201+
202+
187203
class FormTestCase(FormTestParent, StringFragmentCmpHelper, testCsvExport, unittest.TestCase):
188204

189205
def setUp(self):

0 commit comments

Comments
 (0)