Mercurial > p > roundup > code
comparison test/test_cgi.py @ 5166:232c74973a56
issue1408570: fix that form values are lost
.. on edit exceptions. This occured for example if editing an issue with
the classic template and setting 'superseder' to a non-existing issue
number. All changes to the form where the original field was non-empty
were lost.
| author | Ralf Schlatterbeck <rsc@runtux.com> |
|---|---|
| date | Mon, 22 Aug 2016 22:19:48 +0200 |
| parents | 3ee79a2d95d4 |
| children | 9e41254430fe |
comparison
equal
deleted
inserted
replaced
| 5165:a86860224d80 | 5166:232c74973a56 |
|---|---|
| 11 import unittest, os, shutil, errno, sys, difflib, cgi, re, StringIO | 11 import unittest, os, shutil, errno, sys, difflib, cgi, re, StringIO |
| 12 | 12 |
| 13 from roundup.cgi import client, actions, exceptions | 13 from roundup.cgi import client, actions, exceptions |
| 14 from roundup.cgi.exceptions import FormError | 14 from roundup.cgi.exceptions import FormError |
| 15 from roundup.cgi.templating import HTMLItem, HTMLRequest, NoTemplate | 15 from roundup.cgi.templating import HTMLItem, HTMLRequest, NoTemplate |
| 16 from roundup.cgi.templating import HTMLProperty, _HTMLItem | |
| 16 from roundup.cgi.form_parser import FormParser | 17 from roundup.cgi.form_parser import FormParser |
| 17 from roundup import init, instance, password, hyperdb, date | 18 from roundup import init, instance, password, hyperdb, date |
| 19 | |
| 20 # For testing very simple rendering | |
| 21 from roundup.cgi.engine_zopetal import RoundupPageTemplate | |
| 18 | 22 |
| 19 from mocknull import MockNull | 23 from mocknull import MockNull |
| 20 | 24 |
| 21 import db_test_base | 25 import db_test_base |
| 22 | 26 |
| 115 # compile the labels re | 119 # compile the labels re |
| 116 classes = '|'.join(self.db.classes.keys()) | 120 classes = '|'.join(self.db.classes.keys()) |
| 117 self.FV_SPECIAL = re.compile(FormParser.FV_LABELS%classes, | 121 self.FV_SPECIAL = re.compile(FormParser.FV_LABELS%classes, |
| 118 re.VERBOSE) | 122 re.VERBOSE) |
| 119 | 123 |
| 120 def parseForm(self, form, classname='test', nodeid=None): | 124 def setupClient(self, form, classname, nodeid=None, template='item'): |
| 121 cl = client.Client(self.instance, None, {'PATH_INFO':'/', | 125 cl = client.Client(self.instance, None, {'PATH_INFO':'/', |
| 122 'REQUEST_METHOD':'POST'}, makeForm(form)) | 126 'REQUEST_METHOD':'POST'}, makeForm(form)) |
| 123 cl.classname = classname | 127 cl.classname = classname |
| 124 cl.nodeid = nodeid | 128 cl.nodeid = nodeid |
| 125 cl.language = ('en',) | 129 cl.language = ('en',) |
| 130 cl.userid = '1' | |
| 126 cl.db = self.db | 131 cl.db = self.db |
| 132 cl.user = 'admin' | |
| 133 cl.template = template | |
| 134 return cl | |
| 135 | |
| 136 def parseForm(self, form, classname='test', nodeid=None): | |
| 137 cl = self.setupClient(form, classname, nodeid) | |
| 127 return cl.parsePropsFromForm(create=1) | 138 return cl.parsePropsFromForm(create=1) |
| 128 | 139 |
| 129 def tearDown(self): | 140 def tearDown(self): |
| 130 self.db.close() | 141 self.db.close() |
| 131 try: | 142 try: |
| 769 file = FileUpload('foo', 'foo.txt') | 780 file = FileUpload('foo', 'foo.txt') |
| 770 self.assertEqual(self.parseForm({':file': file}, 'issue'), | 781 self.assertEqual(self.parseForm({':file': file}, 'issue'), |
| 771 ({('issue', None): {}, ('file', '-1'): {'content': 'foo', | 782 ({('issue', None): {}, ('file', '-1'): {'content': 'foo', |
| 772 'name': 'foo.txt', 'type': 'text/plain'}}, | 783 'name': 'foo.txt', 'type': 'text/plain'}}, |
| 773 [('issue', None, 'files', [('file', '-1')])])) | 784 [('issue', None, 'files', [('file', '-1')])])) |
| 785 | |
| 786 def testFormValuePreserveOnError(self): | |
| 787 page_template = """ | |
| 788 <html> | |
| 789 <body> | |
| 790 <p tal:condition="options/error_message|nothing" | |
| 791 tal:repeat="m options/error_message" | |
| 792 tal:content="structure m"/> | |
| 793 <p tal:content="context/title/plain"/> | |
| 794 <p tal:content="context/priority/plain"/> | |
| 795 <p tal:content="context/status/plain"/> | |
| 796 <p tal:content="context/nosy/plain"/> | |
| 797 <p tal:content="context/keyword/plain"/> | |
| 798 <p tal:content="structure context/superseder/field"/> | |
| 799 </body> | |
| 800 </html> | |
| 801 """.strip () | |
| 802 self.db.keyword.create (name = 'key1') | |
| 803 self.db.keyword.create (name = 'key2') | |
| 804 nodeid = self.db.issue.create (title = 'Title', priority = '1', | |
| 805 status = '1', nosy = ['1'], keyword = ['1']) | |
| 806 self.db.commit () | |
| 807 form = {':note': 'msg-content', 'title': 'New title', | |
| 808 'priority': '2', 'status': '2', 'nosy': '1,2', 'keyword': '', | |
| 809 'superseder': '5000', ':action': 'edit'} | |
| 810 cl = self.setupClient(form, 'issue', '1') | |
| 811 pt = RoundupPageTemplate() | |
| 812 pt.pt_edit(page_template, 'text/html') | |
| 813 out = [] | |
| 814 def wh(s): | |
| 815 out.append(s) | |
| 816 cl.write_html = wh | |
| 817 # Enable the following if we get a templating error: | |
| 818 #def send_error (*args, **kw): | |
| 819 # import pdb; pdb.set_trace() | |
| 820 #cl.send_error_to_admin = send_error | |
| 821 # Need to rollback the database on error -- this usually happens | |
| 822 # in web-interface (and for other databases) anyway, need it for | |
| 823 # testing that the form values are really used, not the database! | |
| 824 # We do this together with the setup of the easy template above | |
| 825 def load_template(x): | |
| 826 cl.db.rollback() | |
| 827 return pt | |
| 828 cl.instance.templates.load = load_template | |
| 829 cl.selectTemplate = MockNull() | |
| 830 cl.determine_context = MockNull () | |
| 831 def hasPermission(s, p, classname=None, d=None, e=None, **kw): | |
| 832 return True | |
| 833 actions.Action.hasPermission = hasPermission | |
| 834 e1 = _HTMLItem.is_edit_ok | |
| 835 _HTMLItem.is_edit_ok = lambda x : True | |
| 836 e2 = HTMLProperty.is_edit_ok | |
| 837 HTMLProperty.is_edit_ok = lambda x : True | |
| 838 cl.inner_main() | |
| 839 _HTMLItem.is_edit_ok = e1 | |
| 840 HTMLProperty.is_edit_ok = e2 | |
| 841 self.assertEqual(len(out), 1) | |
| 842 self.assertEqual(out [0].strip (), """ | |
| 843 <html> | |
| 844 <body> | |
| 845 <p>Edit Error: issue has no node 5000</p> | |
| 846 <p>New title</p> | |
| 847 <p>urgent</p> | |
| 848 <p>deferred</p> | |
| 849 <p>admin, anonymous</p> | |
| 850 <p></p> | |
| 851 <p><input type="text" name="superseder" value="5000" size="30"></p> | |
| 852 </body> | |
| 853 </html> | |
| 854 """.strip ()) | |
| 774 | 855 |
| 775 # | 856 # |
| 776 # SECURITY | 857 # SECURITY |
| 777 # | 858 # |
| 778 # XXX test all default permissions | 859 # XXX test all default permissions |
