Mercurial > p > roundup > code
diff test/test_cgi.py @ 5310:efb34cbdba7c
Add (currently failing) test for atomic actions
Actions via the web-interface can have several database-modifying
instructions. These should be atomic, i.e., either all should go in or
none. This is currently not the case due to commit calls from OTK
handling (CSRF-protection).
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Mon, 06 Nov 2017 09:26:59 +0100 |
| parents | 198b6e810c67 |
| children | 351763d6400a |
line wrap: on
line diff
--- a/test/test_cgi.py Wed Oct 25 23:07:35 2017 -0400 +++ b/test/test_cgi.py Mon Nov 06 09:26:59 2017 +0100 @@ -13,8 +13,8 @@ from roundup.cgi import client, actions, exceptions from roundup.cgi.exceptions import FormError, NotFound from roundup.exceptions import UsageError -from roundup.cgi.templating import HTMLItem, HTMLRequest, NoTemplate, anti_csrf_nonce -from roundup.cgi.templating import HTMLProperty, _HTMLItem +from roundup.cgi.templating import HTMLItem, HTMLRequest, NoTemplate +from roundup.cgi.templating import HTMLProperty, _HTMLItem, anti_csrf_nonce from roundup.cgi.form_parser import FormParser from roundup import init, instance, password, hyperdb, date @@ -24,11 +24,7 @@ from mocknull import MockNull import db_test_base - -class FileUpload: - def __init__(self, content, filename): - self.content = content - self.filename = filename +from db_test_base import FormTestParent, setupTracker, FileUpload class FileList: def __init__(self, name, *files): @@ -38,19 +34,6 @@ for f in self.files: yield (self.name, f) -def makeForm(args): - form = cgi.FieldStorage() - for k,v in args.items(): - if type(v) is type([]): - [form.list.append(cgi.MiniFieldStorage(k, x)) for x in v] - elif isinstance(v, FileUpload): - x = cgi.MiniFieldStorage(k, v.content) - x.filename = v.filename - form.list.append(x) - else: - form.list.append(cgi.MiniFieldStorage(k, v)) - return form - cm = client.add_message class MessageTestCase(unittest.TestCase): # Note: Escaping is now handled on a message-by-message basis at a @@ -86,24 +69,10 @@ self.assertEqual(cm([],'<i>x</i>\n<b>x</b>',False), ['<i>x</i><br />\n<b>x</b>']) -class FormTestCase(unittest.TestCase): - def setUp(self): - self.dirname = '_test_cgi_form' - # set up and open a tracker - self.instance = db_test_base.setupTracker(self.dirname) +class FormTestCase(FormTestParent, unittest.TestCase): - # open the database - self.db = self.instance.open('admin') - self.db.tx_Source = "web" - self.db.user.create(username='Chef', address='chef@bork.bork.bork', - realname='Bork, Chef', roles='User') - self.db.user.create(username='mary', address='mary@test.test', - roles='User', realname='Contrary, Mary') - - self.db.issue.addprop(tx_Source=hyperdb.String()) - self.db.msg.addprop(tx_Source=hyperdb.String()) - - self.db.post_init() + def setUp(self): + FormTestParent.setUp(self) vars = {} thisdir = os.path.dirname(__file__) @@ -122,32 +91,6 @@ self.FV_SPECIAL = re.compile(FormParser.FV_LABELS%classes, re.VERBOSE) - def setupClient(self, form, classname, nodeid=None, template='item', env_addon=None): - cl = client.Client(self.instance, None, {'PATH_INFO':'/', - 'REQUEST_METHOD':'POST'}, makeForm(form)) - cl.classname = classname - cl.base = 'http://whoami.com/path/' - cl.nodeid = nodeid - cl.language = ('en',) - cl.userid = '1' - cl.db = self.db - cl.user = 'admin' - cl.template = template - if env_addon is not None: - cl.env.update(env_addon) - return cl - - def parseForm(self, form, classname='test', nodeid=None): - cl = self.setupClient(form, classname, nodeid) - return cl.parsePropsFromForm(create=1) - - def tearDown(self): - self.db.close() - try: - shutil.rmtree(self.dirname) - except OSError as error: - if error.errno not in (errno.ENOENT, errno.ESRCH): raise - # # form label extraction # @@ -996,7 +939,7 @@ form2 = copy.copy(form) form2.update({'@csrf': 'booogus'}) # add a bogus csrf field to the form and rerun the inner_main - cl.form = makeForm(form2) + cl.form = db_test_base.makeForm(form2) cl.inner_main() match_at=out[0].find('Invalid csrf token found: booogus') @@ -1016,7 +959,7 @@ form2.update({'@csrf': nonce}) # add a real csrf field to the form and rerun the inner_main - cl.form = makeForm(form2) + cl.form = db_test_base.makeForm(form2) cl.inner_main() # csrf passes and redirects to the new issue. match_at=out[0].find('Redirecting to <a href="http://whoami.com/path/issue1?@ok_message') @@ -1040,7 +983,7 @@ nonce = anti_csrf_nonce(cl, cl) form2.update({'@csrf': nonce}) # add a real csrf field to the form and rerun the inner_main - cl.form = makeForm(form2) + cl.form = db_test_base.makeForm(form2) cl.inner_main() # csrf passes but fail creating new issue because not a post match_at=out[0].find('<p>Invalid request</p>') @@ -1137,7 +1080,7 @@ def _make_client(self, form, classname='user', nodeid='1', userid='2', template='item'): cl = client.Client(self.instance, None, {'PATH_INFO':'/', - 'REQUEST_METHOD':'POST'}, makeForm(form)) + 'REQUEST_METHOD':'POST'}, db_test_base.makeForm(form)) cl.classname = classname if nodeid is not None: cl.nodeid = nodeid @@ -1562,7 +1505,7 @@ def setUp(self): self.dirname = '_test_template' # set up and open a tracker - self.instance = db_test_base.setupTracker(self.dirname) + self.instance = setupTracker(self.dirname) # open the database self.db = self.instance.open('admin') @@ -1576,7 +1519,7 @@ # create a client instance and hijack write_html self.client = client.Client(self.instance, "user", {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, - form=makeForm({"@template": "item"})) + form=db_test_base.makeForm({"@template": "item"})) self.client._error_message = [] self.client._ok_message = [] @@ -1624,7 +1567,7 @@ # this will generate the default home page like # testrenderFrontPage - self.client.form=makeForm({}) + self.client.form=db_test_base.makeForm({}) self.client.path = '' self.client.determine_context() self.assertEqual((self.client.classname, self.client.template, self.client.nodeid), (None, '', None)) @@ -1635,7 +1578,8 @@ result.index('<!-- SHA: c87a4e18d59a527331f1d367c0c6cc67ee123e63 -->')) # now look at the user index page - self.client.form=makeForm({ "@ok_message": "ok message", "@template": "index"}) + self.client.form=db_test_base.makeForm( + { "@ok_message": "ok message", "@template": "index"}) self.client.path = 'user' self.client.determine_context() self.assertEqual((self.client.classname, self.client.template, self.client.nodeid), ('user', 'index', None)) @@ -1655,7 +1599,7 @@ # run renderContext(); check result for proper page # Test ok state template that uses user.forgotten.html - self.client.form=makeForm({"@template": "forgotten|item"}) + self.client.form=db_test_base.makeForm({"@template": "forgotten|item"}) self.client.path = 'user' self.client.determine_context() self.client.session_api = MockNull(_sid="1234567890") @@ -1669,7 +1613,7 @@ result.index('<!-- SHA: eb5dd0bec7a57d58cb7edbeb939fb0390ed1bf74 -->')) # now set an error in the form to get error template user.item.html - self.client.form=makeForm({"@template": "forgotten|item", + self.client.form=db_test_base.makeForm({"@template": "forgotten|item", "@error_message": "this is an error"}) self.client.path = 'user' self.client.determine_context() @@ -1773,7 +1717,7 @@ def setUp(self): self.dirname = '_test_template' # set up and open a tracker - self.instance = db_test_base.setupTracker(self.dirname) + self.instance = setupTracker(self.dirname) # open the database self.db = self.instance.open('admin') @@ -1802,7 +1746,7 @@ # but not used since I call selectTemplate directly. t = client.Client(self.instance, "user", {'PATH_INFO':'/user', 'REQUEST_METHOD':'POST'}, - form=makeForm({"@template": "item"})) + form=db_test_base.makeForm({"@template": "item"})) # create new file in subdir and a dummy file outside of # the tracker's html subdirectory
