@@ -100,7 +100,66 @@ def testAddMessageNoEscape(self):
100100 self .assertEqual (cm ([],'<i>x</i>\n <b>x</b>' ,False ),
101101 ['<i>x</i><br />\n <b>x</b>' ])
102102
103- class FormTestCase (FormTestParent , StringFragmentCmpHelper , unittest .TestCase ):
103+ class testCsvExport (object ):
104+
105+ def testCSVExport (self ):
106+ cl = self ._make_client (
107+ {'@columns' : 'id,title,status,keyword,assignedto,nosy' },
108+ nodeid = None , userid = '1' )
109+ cl .classname = 'issue'
110+
111+ demo_id = self .
db .
user .
create (
username = 'demo' ,
address = '[email protected] ' ,
112+ roles = 'User' , realname = 'demo' )
113+ key_id1 = self .db .keyword .create (name = 'keyword1' )
114+ key_id2 = self .db .keyword .create (name = 'keyword2' )
115+ self .db .issue .create (title = 'foo1' , status = '2' , assignedto = '4' , nosy = ['3' ,demo_id ])
116+ self .db .issue .create (title = 'bar2' , status = '1' , assignedto = '3' , keyword = [key_id1 ,key_id2 ])
117+ self .db .issue .create (title = 'baz32' , status = '4' )
118+ output = io .BytesIO ()
119+ cl .request = MockNull ()
120+ cl .request .wfile = output
121+ # call export version that outputs names
122+ actions .ExportCSVAction (cl ).handle ()
123+ should_be = (s2b ('"id","title","status","keyword","assignedto","nosy"\r \n '
124+ '"1","foo1","deferred","","Contrary, Mary","Bork, Chef;Contrary, Mary;demo"\r \n '
125+ '"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef"\r \n '
126+ '"3","baz32","need-eg","","",""\r \n ' ))
127+ #print(should_be)
128+ print (output .getvalue ())
129+ self .assertEqual (output .getvalue (), should_be )
130+ output = io .BytesIO ()
131+ cl .request = MockNull ()
132+ cl .request .wfile = output
133+ # call export version that outputs id numbers
134+ actions .ExportCSVWithIdAction (cl ).handle ()
135+ should_be = s2b ('"id","title","status","keyword","assignedto","nosy"\r \n '
136+ "\" 1\" ,\" foo1\" ,\" 2\" ,\" []\" ,\" 4\" ,\" ['3', '4', '5']\" \r \n "
137+ "\" 2\" ,\" bar2\" ,\" 1\" ,\" ['1', '2']\" ,\" 3\" ,\" ['3']\" \r \n "
138+ '\" 3\" ,"baz32",\" 4\" ,"[]","None","[]"\r \n ' )
139+ #print(should_be)
140+ print (output .getvalue ())
141+ self .assertEqual (output .getvalue (), should_be )
142+
143+ # test full text search
144+ cl = self ._make_client (
145+ {'@columns' : 'id,title,status,keyword,assignedto,nosy' ,
146+ "@search_text" : "bar2" }, nodeid = None , userid = '1' )
147+ cl .classname = 'issue'
148+ output = io .BytesIO ()
149+ cl .request = MockNull ()
150+ cl .request .wfile = output
151+
152+ # call export version that outputs names
153+ actions .ExportCSVAction (cl ).handle ()
154+ should_be = (s2b ('"id","title","status","keyword","assignedto","nosy"\r \n '
155+ '"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef"\r \n ' ))
156+
157+ # call export version that outputs id numbers
158+ actions .ExportCSVWithIdAction (cl ).handle ()
159+ should_be = s2b ('"id","title","status","keyword","assignedto","nosy"\r \n '
160+ "\" 2\" ,\" bar2\" ,\" 1\" ,\" ['1', '2']\" ,\" 3\" ,\" ['3']\" \r \n " )
161+
162+ class FormTestCase (FormTestParent , StringFragmentCmpHelper , testCsvExport , unittest .TestCase ):
104163
105164 def setUp (self ):
106165 FormTestParent .setUp (self )
@@ -1810,44 +1869,6 @@ def testRoles(self):
18101869 self .db .user .set ('1' , roles = '' )
18111870 self .assertTrue (not item .hasRole ('' ))
18121871
1813- def testCSVExport (self ):
1814- cl = self ._make_client (
1815- {'@columns' : 'id,title,status,keyword,assignedto,nosy' },
1816- nodeid = None , userid = '1' )
1817- cl .classname = 'issue'
1818-
1819- demo_id = self .
db .
user .
create (
username = 'demo' ,
address = '[email protected] ' ,
1820- roles = 'User' , realname = 'demo' )
1821- key_id1 = self .db .keyword .create (name = 'keyword1' )
1822- key_id2 = self .db .keyword .create (name = 'keyword2' )
1823- self .db .issue .create (title = 'foo1' , status = '2' , assignedto = '4' , nosy = ['3' ,demo_id ])
1824- self .db .issue .create (title = 'bar2' , status = '1' , assignedto = '3' , keyword = [key_id1 ,key_id2 ])
1825- self .db .issue .create (title = 'baz32' , status = '4' )
1826- output = io .BytesIO ()
1827- cl .request = MockNull ()
1828- cl .request .wfile = output
1829- # call export version that outputs names
1830- actions .ExportCSVAction (cl ).handle ()
1831- should_be = (s2b ('"id","title","status","keyword","assignedto","nosy"\r \n '
1832- '"1","foo1","deferred","","Contrary, Mary","Bork, Chef;Contrary, Mary;demo"\r \n '
1833- '"2","bar2","unread","keyword1;keyword2","Bork, Chef","Bork, Chef"\r \n '
1834- '"3","baz32","need-eg","","",""\r \n ' ))
1835- #print(should_be)
1836- print (output .getvalue ())
1837- self .assertEqual (output .getvalue (), should_be )
1838- output = io .BytesIO ()
1839- cl .request = MockNull ()
1840- cl .request .wfile = output
1841- # call export version that outputs id numbers
1842- actions .ExportCSVWithIdAction (cl ).handle ()
1843- should_be = s2b ('"id","title","status","keyword","assignedto","nosy"\r \n '
1844- "\" 1\" ,\" foo1\" ,\" 2\" ,\" []\" ,\" 4\" ,\" ['3', '4', '5']\" \r \n "
1845- "\" 2\" ,\" bar2\" ,\" 1\" ,\" ['1', '2']\" ,\" 3\" ,\" ['3']\" \r \n "
1846- '\" 3\" ,"baz32",\" 4\" ,"[]","None","[]"\r \n ' )
1847- #print(should_be)
1848- print (output .getvalue ())
1849- self .assertEqual (output .getvalue (), should_be )
1850-
18511872 def testCSVExportCharset (self ):
18521873 cl = self ._make_client (
18531874 {'@columns' : 'id,title,status,keyword,assignedto,nosy' },
@@ -2364,7 +2385,7 @@ def testTemplateSubdirectory(self):
23642385 r = t .selectTemplate ("user" , "subdir/item" )
23652386 self .assertEqual ("subdir/user.item" , r )
23662387
2367- class SqliteNativeFtsCgiTest (unittest .TestCase , testFtsQuery ):
2388+ class SqliteNativeFtsCgiTest (unittest .TestCase , testFtsQuery , testCsvExport ):
23682389 """All of the rest of the tests use anydbm as the backend.
23692390 In addtion to normal fts test, this class tests renderError
23702391 when renderContext fails.
@@ -2382,6 +2403,11 @@ def setUp(self):
23822403 # open the database
23832404 self .db = self .instance .open ('admin' )
23842405 self .db .tx_Source = "web"
2406+ self .
db .
user .
create (
username = 'Chef' ,
address = '[email protected] ' ,
2407+ realname = 'Bork, Chef' , roles = 'User' )
2408+ self .
db .
user .
create (
username = 'mary' ,
address = '[email protected] ' ,
2409+ roles = 'User' , realname = 'Contrary, Mary' )
2410+ self .db .post_init ()
23852411
23862412 # create a client instance and hijack write_html
23872413 self .client = client .Client (self .instance , "user" ,
@@ -2429,6 +2455,30 @@ def testRenderContextBadFtsQuery(self):
24292455 self .assertEqual (result , expected )
24302456 self .assertEqual (self .client .response_code , 400 )
24312457
2458+ #
2459+ # SECURITY
2460+ #
2461+ # XXX test all default permissions
2462+ def _make_client (self , form , classname = 'user' , nodeid = '1' ,
2463+ userid = '2' , template = 'item' ):
2464+ cl = client .Client (self .instance , None , {'PATH_INFO' :'/' ,
2465+ 'REQUEST_METHOD' :'POST' }, db_test_base .makeForm (form ))
2466+ cl .classname = classname
2467+ if nodeid is not None :
2468+ cl .nodeid = nodeid
2469+ cl .db = self .db
2470+ #cl.db.Otk = MockNull()
2471+ #cl.db.Otk.data = {}
2472+ #cl.db.Otk.getall = self.data_get
2473+ #cl.db.Otk.set = self.data_set
2474+ cl .userid = userid
2475+ cl .language = ('en' ,)
2476+ cl ._error_message = []
2477+ cl ._ok_message = []
2478+ cl .template = template
2479+ return cl
2480+
2481+
24322482class SqliteNativeCgiTest (unittest .TestCase , testFtsQuery ):
24332483 """All of the rest of the tests use anydbm as the backend.
24342484 This class tests renderContext for fulltext search.
0 commit comments