Mercurial > p > roundup > code
comparison test/test_cgi.py @ 6599:39189dd94f2c
issue2551189 - increase size of words in full text index.
Increased indexed word maxlength to 50
DB migration code is written and tests work.
Restructured some tests to allow for code reuse.
Docs.
If this passes CI without errors 2551189 should be done. However,
testing on my system generates errors. Encoding (indexer unicode
russian unicode string invalid) and collation errors (utf8_bin not
valid) when running under python2. No issues with python3 and I
haven't changed code that should cause these since the last successful
build in CI. So if this fails in CI we will have more checkins.
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Wed, 26 Jan 2022 15:04:09 -0500 |
| parents | e70e2789bc2c |
| children | 65336409738c |
comparison
equal
deleted
inserted
replaced
| 6598:27a4ab499189 | 6599:39189dd94f2c |
|---|---|
| 98 def testAddMessageNoEscape(self): | 98 def testAddMessageNoEscape(self): |
| 99 self.assertEqual(cm([],'<i>x</i>',False), ['<i>x</i>']) | 99 self.assertEqual(cm([],'<i>x</i>',False), ['<i>x</i>']) |
| 100 self.assertEqual(cm([],'<i>x</i>\n<b>x</b>',False), | 100 self.assertEqual(cm([],'<i>x</i>\n<b>x</b>',False), |
| 101 ['<i>x</i><br />\n<b>x</b>']) | 101 ['<i>x</i><br />\n<b>x</b>']) |
| 102 | 102 |
| 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='demo@test.test', | |
| 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): | |
| 104 | 163 |
| 105 def setUp(self): | 164 def setUp(self): |
| 106 FormTestParent.setUp(self) | 165 FormTestParent.setUp(self) |
| 107 | 166 |
| 108 tx_Source_init(self.db) | 167 tx_Source_init(self.db) |
| 1808 self.assertTrue(not item.hasRole('')) | 1867 self.assertTrue(not item.hasRole('')) |
| 1809 self.assertTrue(not item.hasRole(' ')) | 1868 self.assertTrue(not item.hasRole(' ')) |
| 1810 self.db.user.set('1', roles='') | 1869 self.db.user.set('1', roles='') |
| 1811 self.assertTrue(not item.hasRole('')) | 1870 self.assertTrue(not item.hasRole('')) |
| 1812 | 1871 |
| 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='demo@test.test', | |
| 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 | |
| 1851 def testCSVExportCharset(self): | 1872 def testCSVExportCharset(self): |
| 1852 cl = self._make_client( | 1873 cl = self._make_client( |
| 1853 {'@columns': 'id,title,status,keyword,assignedto,nosy'}, | 1874 {'@columns': 'id,title,status,keyword,assignedto,nosy'}, |
| 1854 nodeid=None, userid='1') | 1875 nodeid=None, userid='1') |
| 1855 cl.classname = 'issue' | 1876 cl.classname = 'issue' |
| 2362 | 2383 |
| 2363 # template check works | 2384 # template check works |
| 2364 r = t.selectTemplate("user", "subdir/item") | 2385 r = t.selectTemplate("user", "subdir/item") |
| 2365 self.assertEqual("subdir/user.item", r) | 2386 self.assertEqual("subdir/user.item", r) |
| 2366 | 2387 |
| 2367 class SqliteNativeFtsCgiTest(unittest.TestCase, testFtsQuery): | 2388 class SqliteNativeFtsCgiTest(unittest.TestCase, testFtsQuery, testCsvExport): |
| 2368 """All of the rest of the tests use anydbm as the backend. | 2389 """All of the rest of the tests use anydbm as the backend. |
| 2369 In addtion to normal fts test, this class tests renderError | 2390 In addtion to normal fts test, this class tests renderError |
| 2370 when renderContext fails. | 2391 when renderContext fails. |
| 2371 Triggering this error requires the native-fts backend for | 2392 Triggering this error requires the native-fts backend for |
| 2372 the sqlite db. | 2393 the sqlite db. |
| 2380 self.instance.config.INDEXER = "native-fts" | 2401 self.instance.config.INDEXER = "native-fts" |
| 2381 | 2402 |
| 2382 # open the database | 2403 # open the database |
| 2383 self.db = self.instance.open('admin') | 2404 self.db = self.instance.open('admin') |
| 2384 self.db.tx_Source = "web" | 2405 self.db.tx_Source = "web" |
| 2406 self.db.user.create(username='Chef', address='chef@bork.bork.bork', | |
| 2407 realname='Bork, Chef', roles='User') | |
| 2408 self.db.user.create(username='mary', address='mary@test.test', | |
| 2409 roles='User', realname='Contrary, Mary') | |
| 2410 self.db.post_init() | |
| 2385 | 2411 |
| 2386 # create a client instance and hijack write_html | 2412 # create a client instance and hijack write_html |
| 2387 self.client = client.Client(self.instance, "user", | 2413 self.client = client.Client(self.instance, "user", |
| 2388 {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, | 2414 {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, |
| 2389 form=db_test_base.makeForm({"@template": "item"})) | 2415 form=db_test_base.makeForm({"@template": "item"})) |
| 2427 expected = '\n<html><head><title>Roundup issue tracker: An error has occurred</title>\n <link rel="stylesheet" type="text/css" href="@@file/style.css">\n</head>\n<body class="body" marginwidth="0" marginheight="0">\n <p class="error-message">Search failed. Try quoting any terms that include a \'-\' and retry the search.</p>\n</body></html>\n' | 2453 expected = '\n<html><head><title>Roundup issue tracker: An error has occurred</title>\n <link rel="stylesheet" type="text/css" href="@@file/style.css">\n</head>\n<body class="body" marginwidth="0" marginheight="0">\n <p class="error-message">Search failed. Try quoting any terms that include a \'-\' and retry the search.</p>\n</body></html>\n' |
| 2428 | 2454 |
| 2429 self.assertEqual(result, expected) | 2455 self.assertEqual(result, expected) |
| 2430 self.assertEqual(self.client.response_code, 400) | 2456 self.assertEqual(self.client.response_code, 400) |
| 2431 | 2457 |
| 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 | |
| 2432 class SqliteNativeCgiTest(unittest.TestCase, testFtsQuery): | 2482 class SqliteNativeCgiTest(unittest.TestCase, testFtsQuery): |
| 2433 """All of the rest of the tests use anydbm as the backend. | 2483 """All of the rest of the tests use anydbm as the backend. |
| 2434 This class tests renderContext for fulltext search. | 2484 This class tests renderContext for fulltext search. |
| 2435 Run with sqlite and native indexer. | 2485 Run with sqlite and native indexer. |
| 2436 """ | 2486 """ |
