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

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