comparison test/test_cgi.py @ 6588:91ab3e0ffcd0

Summary: Add test cases for sqlite fts Add support for using the FTS5 full text query engine for sqlite. Also stubbed out some sections for adding postgresql FTS support as well. Added nee indexer type native-fts. It is not selected by default. The indexer=native is used if no indexer is set. This prevents an upgrade from seeming to wipe out the native index if upgraded and indexer=native is not explicitly set. Docs updated. Also changed section headers to sentence case for the current release notes. Indexing backend can control if the full text search phrase is broken into a list of words or passed intact. For backends with query languages (sqlite and can be enabled for whoosh and xapian) we do not want the phrase "tokenized" on whitespace. This also updates the rdbms database version to version 7 to add FTS table. I will be using the same version when I add postgresql. If somebody runs this version on postgresql, they will have to manually add the fts tables for postgresql if they want to use it. Added a new renderError method to client. This allows errors to be reported still using page.html rather than raw html. It also supports templates for any error code. If no template for the error code (e.g. 400) is found, the error in raw html with no page frame is shown. New IndexerQueryError exception to pass back message about query syntax errors.
author John Rouillard <rouilj@ieee.org>
date Sun, 23 Jan 2022 18:57:45 -0500
parents ada96db8ec62
children e70e2789bc2c
comparison
equal deleted inserted replaced
6587:4f8fc55730e1 6588:91ab3e0ffcd0
2034 # make sure we can find the last SHA1 sum line at the end of the 2034 # make sure we can find the last SHA1 sum line at the end of the
2035 # page 2035 # page
2036 self.assertNotEqual(-1, 2036 self.assertNotEqual(-1,
2037 self.output[0].index('<!-- SHA: c87a4e18d59a527331f1d367c0c6cc67ee123e63 -->')) 2037 self.output[0].index('<!-- SHA: c87a4e18d59a527331f1d367c0c6cc67ee123e63 -->'))
2038 2038
2039 def testRenderError(self):
2040 # set up the client;
2041 # run determine_context to set the required client attributes
2042 # run renderError(); check result for proper page
2043
2044 self.client.form=db_test_base.makeForm({})
2045 self.client.path = ''
2046 self.client.determine_context()
2047
2048 error = "Houston, we have a problem"
2049
2050
2051 # template rendering will fail and return fallback html
2052 out = self.client.renderError(error, 404)
2053
2054 expected_fallback = (
2055 '\n<html><head><title>Roundup issue tracker: '
2056 'An error has occurred</title>\n'
2057 ' <link rel="stylesheet" type="text/css" href="@@file/style.css">\n'
2058 '</head>\n'
2059 '<body class="body" marginwidth="0" marginheight="0">\n'
2060 ' <p class="error-message">Houston, we have a problem</p>\n'
2061 '</body></html>\n')
2062
2063 self.assertEqual(out, expected_fallback)
2064 self.assertIn(error, self.client._error_message)
2065 self.assertEqual(self.client.response_code, 404)
2066
2067 ### next test
2068 # Set this so template rendering works.
2069 self.client.classname = 'issue'
2070
2071 out = self.client.renderError("Houston, we have a problem", 404)
2072 # match hard coded line in 404 template
2073 expected = ('There is no <span>issue</span> with id')
2074
2075 self.assertIn(expected, out)
2076 self.assertEqual(self.client.response_code, 404)
2077
2078
2079 ### next test
2080 # disable template use get fallback
2081 out = self.client.renderError("Houston, we have a problem", 404,
2082 use_template=False)
2083
2084 self.assertEqual(out, expected_fallback)
2085 self.assertEqual(self.client.response_code, 404)
2086
2087 ### next test
2088 # no 400 template (default 2nd param) so we get fallback
2089 out = self.client.renderError("Houston, we have a problem")
2090 self.assertEqual(out, expected_fallback)
2091 self.assertIn(error, self.client._error_message)
2092 self.assertEqual(self.client.response_code, 400)
2093
2039 def testrenderContext(self): 2094 def testrenderContext(self):
2040 # set up the client; 2095 # set up the client;
2041 # run determine_context to set the required client attributes 2096 # run determine_context to set the required client attributes
2042 # run renderContext(); check result for proper page 2097 # run renderContext(); check result for proper page
2043 2098
2286 2341
2287 # template check works 2342 # template check works
2288 r = t.selectTemplate("user", "subdir/item") 2343 r = t.selectTemplate("user", "subdir/item")
2289 self.assertEqual("subdir/user.item", r) 2344 self.assertEqual("subdir/user.item", r)
2290 2345
2346 class SqliteCgiTest(unittest.TestCase):
2347 """All of the rest of the tests use anydbm as the backend.
2348 This class tests renderError when renderContext fails.
2349 Triggering this error requires the native-fts backend for
2350 the sqlite db.
2351 """
2352
2353 def setUp(self):
2354 self.dirname = '_test_template'
2355 # set up and open a tracker
2356 self.instance = setupTracker(self.dirname, backend="sqlite")
2357
2358 self.instance.config.INDEXER = "native-fts"
2359
2360 # open the database
2361 self.db = self.instance.open('admin')
2362 self.db.tx_Source = "web"
2363
2364 # create a client instance and hijack write_html
2365 self.client = client.Client(self.instance, "user",
2366 {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'},
2367 form=db_test_base.makeForm({"@template": "item"}))
2368
2369 self.client._error_message = []
2370 self.client._ok_message = []
2371 self.client.db = self.db
2372 self.client.userid = '1'
2373 self.client.language = ('en',)
2374 self.client.session_api = MockNull(_sid="1234567890")
2375
2376 self.output = []
2377 # ugly hack to get html_write to return data here.
2378 def html_write(s):
2379 self.output.append(s)
2380
2381 # hijack html_write
2382 self.client.write_html = html_write
2383
2384 def tearDown(self):
2385 self.db.close()
2386 try:
2387 shutil.rmtree(self.dirname)
2388 except OSError as error:
2389 if error.errno not in (errno.ENOENT, errno.ESRCH): raise
2390
2391 def testRenderContextBadFtsQuery(self):
2392 # only test for sqlite
2393 if self.db.dbtype not in [ "sqlite" ]:
2394 pytest.skip("Not tested for backends without native FTS")
2395
2396 # generate a bad fts query
2397 self.client.form=db_test_base.makeForm(
2398 { "@ok_message": "ok message", "@template": "index",
2399 "@search_text": "foo-bar"})
2400 self.client.path = 'issue'
2401 self.client.determine_context()
2402
2403 result = self.client.renderContext()
2404
2405 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'
2406
2407 self.assertEqual(result, expected)
2408 self.assertEqual(self.client.response_code, 400)
2409
2410
2291 # vim: set filetype=python sts=4 sw=4 et si : 2411 # vim: set filetype=python sts=4 sw=4 et si :

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