test_forms.py
Go to the documentation of this file.
00001 # -*- coding: utf-8 -*-
00002 from __future__ import unicode_literals
00003 
00004 import os.path
00005 import struct
00006 import sys
00007 
00008 import webtest
00009 import six
00010 from six import binary_type
00011 from six import PY3
00012 from webob import Request
00013 from webtest.debugapp import DebugApp
00014 from webtest.compat import to_bytes
00015 from webtest.forms import NoValue, Submit, Upload
00016 from tests.compat import unittest
00017 from tests.compat import u
00018 
00019 
00020 class TestForms(unittest.TestCase):
00021 
00022     def callFUT(self, filename='form_inputs.html', formid='simple_form'):
00023         dirname = os.path.join(os.path.dirname(__file__), 'html')
00024         app = DebugApp(form=os.path.join(dirname, filename), show_form=True)
00025         resp = webtest.TestApp(app).get('/form.html')
00026         return resp.forms[formid]
00027 
00028     def test_set_submit_field(self):
00029         form = self.callFUT()
00030         self.assertRaises(
00031             AttributeError,
00032             form['submit'].value__set,
00033             'foo'
00034         )
00035 
00036     def test_button(self):
00037         form = self.callFUT()
00038         button = form['button']
00039         self.assertTrue(isinstance(button, Submit),
00040                         "<button> without type is a submit button")
00041 
00042     def test_force_select(self):
00043         form = self.callFUT()
00044         form['select'].force_value('notavalue')
00045         form['select'].value__set('value3')
00046 
00047         self.assertTrue(
00048             form['select']._forced_value is NoValue,
00049             "Setting a value after having forced a value should keep a forced"
00050             " state")
00051         self.assertEqual(
00052             form['select'].value, 'value3',
00053             "the value should the the one set by value__set")
00054         self.assertEqual(
00055             form['select'].selectedIndex, 2,
00056             "the value index should be the one set by value__set")
00057 
00058     def test_form_select(self):
00059         form = self.callFUT()
00060         form.select('select', 'value1')
00061 
00062         self.assertEqual(
00063             form['select'].value, 'value1',
00064             "when using form.select, the input selected value should be "
00065             "changed")
00066 
00067     def test_get_field_by_index(self):
00068         form = self.callFUT()
00069         self.assertEqual(form['select'],
00070                          form.get('select', index=0))
00071 
00072     def test_get_unknown_field(self):
00073         form = self.callFUT()
00074         self.assertEqual(form['unknown'].value, '')
00075         form['unknown'].value = '1'
00076         self.assertEqual(form['unknown'].value, '1')
00077 
00078     def test_get_non_exist_fields(self):
00079         form = self.callFUT()
00080         self.assertRaises(AssertionError, form.get, 'nonfield')
00081 
00082     def test_get_non_exist_fields_with_default(self):
00083         form = self.callFUT()
00084         value = form.get('nonfield', default=1)
00085         self.assertEqual(value, 1)
00086 
00087     def test_upload_fields(self):
00088         form = self.callFUT()
00089         fu = webtest.Upload(__file__)
00090         form['file'] = fu
00091         self.assertEqual(form.upload_fields(),
00092                          [['file', __file__]])
00093 
00094     def test_repr(self):
00095         form = self.callFUT()
00096         self.assertTrue(repr(form).startswith('<Form id='))
00097 
00098     def test_the_bs_node_must_not_change(self):
00099         form = self.callFUT()
00100         self.assertEqual(form.text, str(form.html))
00101 
00102     def test_set_multiple_checkboxes(self):
00103         form = self.callFUT(formid='multiple_checkbox_form')
00104         form['checkbox'] = [10, 30]
00105 
00106         self.assertEqual(form.get('checkbox', index=0).value, '10')
00107         self.assertEqual(form.get('checkbox', index=1).value, None)
00108         self.assertEqual(form.get('checkbox', index=2).value, '30')
00109 
00110     def test_button_submit(self):
00111         form = self.callFUT(formid='multiple_buttons_form')
00112         display = form.submit('action')
00113         self.assertIn(u("action=deactivate"), display, display)
00114 
00115     def test_button_submit_by_index(self):
00116         form = self.callFUT(formid='multiple_buttons_form')
00117         display = form.submit('action', index=1)
00118         self.assertIn(u("action=activate"), display, display)
00119 
00120     def test_button_submit_by_value(self):
00121         form = self.callFUT(formid='multiple_buttons_form')
00122         display = form.submit('action', value='activate')
00123         self.assertIn(u("action=activate"), display, display)
00124 
00125     def test_button_submit_by_value_and_index(self):
00126         form = self.callFUT(formid='multiple_buttons_form')
00127         self.assertRaises(ValueError,
00128                           form.submit, "action", value="activate",
00129                           index=0)
00130 
00131 
00132 class TestResponseFormAttribute(unittest.TestCase):
00133 
00134     def callFUT(self, body):
00135         app = DebugApp(form=to_bytes(body))
00136         return webtest.TestApp(app)
00137 
00138     def test_no_form(self):
00139         app = self.callFUT('<html><body></body></html>')
00140         res = app.get('/form.html')
00141         self.assertRaises(TypeError, lambda: res.form)
00142 
00143     def test_too_many_forms(self):
00144         app = self.callFUT(
00145             '<html><body><form></form><form></form></body></html>')
00146         res = app.get('/form.html')
00147         self.assertRaises(TypeError, lambda: res.form)
00148 
00149 
00150 class TestInput(unittest.TestCase):
00151 
00152     def callFUT(self, filename='form_inputs.html'):
00153         dirname = os.path.join(os.path.dirname(__file__), 'html')
00154         app = DebugApp(form=os.path.join(dirname, filename), show_form=True)
00155         return webtest.TestApp(app)
00156 
00157     def test_input(self):
00158         app = self.callFUT()
00159         res = app.get('/form.html')
00160         self.assertEqual(res.status_int, 200)
00161         self.assertTrue(res.content_type.startswith('text/html'))
00162 
00163         form = res.forms['text_input_form']
00164         self.assertEqual(form['foo'].value, 'bar')
00165         self.assertEqual(form.submit_fields(), [('foo', 'bar')])
00166 
00167         form = res.forms['radio_input_form']
00168         self.assertEqual(form['foo'].value, 'baz')
00169         self.assertEqual(form.submit_fields(), [('foo', 'baz')])
00170 
00171         form = res.forms['checkbox_input_form']
00172         self.assertEqual(form['foo'].value, 'bar')
00173         self.assertEqual(form.submit_fields(), [('foo', 'bar')])
00174 
00175         form = res.forms['password_input_form']
00176         self.assertEqual(form['foo'].value, 'bar')
00177         self.assertEqual(form.submit_fields(), [('foo', 'bar')])
00178 
00179     def test_force_radio_input(self):
00180         app = self.callFUT()
00181         res = app.get('/form.html')
00182 
00183         form = res.forms['radio_input_form']
00184 
00185         form['foo'].force_value('fido')
00186         self.assertEqual(form['foo'].value, 'fido')
00187         self.assertEqual(form.submit_fields(), [('foo', 'fido')])
00188 
00189     def test_input_unicode(self):
00190         app = self.callFUT('form_unicode_inputs.html')
00191         res = app.get('/form.html')
00192         self.assertEqual(res.status_int, 200)
00193         self.assertTrue(res.content_type.startswith('text/html'))
00194         self.assertEqual(res.charset.lower(), 'utf-8')
00195 
00196         form = res.forms['text_input_form']
00197         self.assertEqual(form['foo'].value, u('Хармс'))
00198         self.assertEqual(form.submit_fields(), [('foo', u('Хармс'))])
00199 
00200         form = res.forms['radio_input_form']
00201         self.assertEqual(form['foo'].value, u('Блок'))
00202         self.assertEqual(form.submit_fields(), [('foo', u('Блок'))])
00203 
00204         form = res.forms['checkbox_input_form']
00205         self.assertEqual(form['foo'].value, u('Хармс'))
00206         self.assertEqual(form.submit_fields(), [('foo', u('Хармс'))])
00207 
00208         form = res.forms['password_input_form']
00209         self.assertEqual(form['foo'].value, u('Хармс'))
00210         self.assertEqual(form.submit_fields(), [('foo', u('Хармс'))])
00211 
00212     def test_input_no_default(self):
00213         app = self.callFUT('form_inputs_with_defaults.html')
00214         res = app.get('/form.html')
00215         self.assertEqual(res.status_int, 200)
00216         self.assertTrue(res.content_type.startswith('text/html'))
00217 
00218         form = res.forms['text_input_form']
00219         self.assertEqual(form['foo'].value, '')
00220         self.assertEqual(form.submit_fields(), [('foo', '')])
00221 
00222         form = res.forms['radio_input_form']
00223         self.assertTrue(form['foo'].value is None)
00224         self.assertEqual(form.submit_fields(), [])
00225 
00226         form = res.forms['checkbox_input_form']
00227         self.assertTrue(form['foo'].value is None)
00228         self.assertEqual(form.submit_fields(), [])
00229 
00230         form = res.forms['password_input_form']
00231         self.assertEqual(form['foo'].value, '')
00232         self.assertEqual(form.submit_fields(), [('foo', '')])
00233 
00234     def test_textarea_entities(self):
00235         app = self.callFUT()
00236         res = app.get('/form.html')
00237         form = res.forms.get("textarea_input_form")
00238         self.assertEqual(form.get("textarea").value, "'foo&bar'")
00239         self.assertEqual(form.submit_fields(), [('textarea', "'foo&bar'")])
00240 
00241     def test_textarea_emptyfirstline(self):
00242         app = self.callFUT()
00243         res = app.get('/form.html')
00244         form = res.forms.get("textarea_emptyline_form")
00245         self.assertEqual(form.get("textarea").value, "aaa")
00246         self.assertEqual(form.submit_fields(), [('textarea', "aaa")])
00247 
00248 
00249 class TestFormLint(unittest.TestCase):
00250 
00251     def test_form_lint(self):
00252         form = webtest.Form(None, '''<form>
00253         <input type="text" name="field"/>
00254         </form>''')
00255         self.assertRaises(AttributeError, form.lint)
00256 
00257         form = webtest.Form(None, '''<form>
00258         <input type="text" id="myfield" name="field"/>
00259         </form>''')
00260         self.assertRaises(AttributeError, form.lint)
00261 
00262         form = webtest.Form(None, '''<form>
00263         <label for="myfield">my field</label>
00264         <input type="text" id="myfield" name="field"/>
00265         </form>''')
00266         form.lint()
00267 
00268         form = webtest.Form(None, '''<form>
00269         <label class="field" for="myfield" role="r">my field</label>
00270         <input type="text" id="myfield" name="field"/>
00271         </form>''')
00272         form.lint()
00273 
00274 
00275 def select_app(environ, start_response):
00276     req = Request(environ)
00277     status = b"200 OK"
00278     if req.method == "GET":
00279         body = to_bytes("""
00280 <html>
00281     <head><title>form page</title></head>
00282     <body>
00283         <form method="POST" id="single_select_form">
00284             <select id="single" name="single">
00285                 <option value="4">Four</option>
00286                 <option value="5" selected="selected">Five</option>
00287                 <option value="6">Six</option>
00288                 <option value="7">Seven</option>
00289             </select>
00290             <input name="button" type="submit" value="single">
00291         </form>
00292         <form method="POST" id="multiple_select_form">
00293             <select id="multiple" name="multiple" multiple>
00294                 <option value="8" selected="selected">Eight</option>
00295                 <option value="9">Nine</option>
00296                 <option value="10">Ten</option>
00297                 <option value="11" selected="selected">Eleven</option>
00298             </select>
00299             <input name="button" type="submit" value="multiple">
00300         </form>
00301     </body>
00302 </html>
00303 """)
00304     else:
00305         select_type = req.POST.get("button")
00306         if select_type == "single":
00307             selection = req.POST.get("single")
00308         elif select_type == "multiple":
00309             selection = ", ".join(req.POST.getall("multiple"))
00310         body = to_bytes("""
00311 <html>
00312     <head><title>display page</title></head>
00313     <body>
00314         <p>You submitted the %(select_type)s </p>
00315         <p>You selected %(selection)s</p>
00316     </body>
00317 </html>
00318 """ % dict(selection=selection, select_type=select_type))
00319 
00320     headers = [
00321         ('Content-Type', 'text/html; charset=utf-8'),
00322         ('Content-Length', str(len(body)))]
00323     start_response(status, headers)
00324     return [body]
00325 
00326 
00327 def select_app_without_values(environ, start_response):
00328     req = Request(environ)
00329     status = b"200 OK"
00330     if req.method == "GET":
00331         body = to_bytes("""
00332 <html>
00333     <head><title>form page</title></head>
00334     <body>
00335         <form method="POST" id="single_select_form">
00336             <select id="single" name="single">
00337                 <option>Four</option>
00338                 <option>Five</option>
00339                 <option>Six</option>
00340                 <option>Seven</option>
00341             </select>
00342             <input name="button" type="submit" value="single">
00343         </form>
00344         <form method="POST" id="multiple_select_form">
00345             <select id="multiple" name="multiple" multiple="multiple">
00346                 <option>Eight</option>
00347                 <option selected value="Nine">Nine</option>
00348                 <option>Ten</option>
00349                 <option selected>Eleven</option>
00350             </select>
00351             <input name="button" type="submit" value="multiple">
00352         </form>
00353     </body>
00354 </html>
00355 """)
00356     else:
00357         select_type = req.POST.get("button")
00358         if select_type == "single":
00359             selection = req.POST.get("single")
00360         elif select_type == "multiple":
00361             selection = ", ".join(req.POST.getall("multiple"))
00362         body = to_bytes("""
00363 <html>
00364     <head><title>display page</title></head>
00365     <body>
00366         <p>You submitted the %(select_type)s </p>
00367         <p>You selected %(selection)s</p>
00368     </body>
00369 </html>
00370 """ % dict(selection=selection, select_type=select_type))
00371 
00372     headers = [
00373         ('Content-Type', 'text/html; charset=utf-8'),
00374         ('Content-Length', str(len(body)))]
00375     start_response(status, headers)
00376     return [body]
00377 
00378 
00379 def select_app_without_default(environ, start_response):
00380     req = Request(environ)
00381     status = b"200 OK"
00382     if req.method == "GET":
00383         body = to_bytes("""
00384 <html>
00385     <head><title>form page</title></head>
00386     <body>
00387         <form method="POST" id="single_select_form">
00388             <select id="single" name="single">
00389                 <option value="4">Four</option>
00390                 <option value="5">Five</option>
00391                 <option value="6">Six</option>
00392                 <option value="7">Seven</option>
00393             </select>
00394             <input name="button" type="submit" value="single">
00395         </form>
00396         <form method="POST" id="multiple_select_form">
00397             <select id="multiple" name="multiple" multiple="multiple">
00398                 <option value="8">Eight</option>
00399                 <option value="9">Nine</option>
00400                 <option value="10">Ten</option>
00401                 <option value="11">Eleven</option>
00402             </select>
00403             <input name="button" type="submit" value="multiple">
00404         </form>
00405     </body>
00406 </html>
00407 """)
00408     else:
00409         select_type = req.POST.get("button")
00410         if select_type == "single":
00411             selection = req.POST.get("single")
00412         elif select_type == "multiple":
00413             selection = ", ".join(req.POST.getall("multiple"))
00414         body = to_bytes("""
00415 <html>
00416     <head><title>display page</title></head>
00417     <body>
00418         <p>You submitted the %(select_type)s </p>
00419         <p>You selected %(selection)s</p>
00420     </body>
00421 </html>
00422 """ % dict(selection=selection, select_type=select_type))
00423 
00424     headers = [
00425         ('Content-Type', 'text/html; charset=utf-8'),
00426         ('Content-Length', str(len(body)))]
00427     start_response(status, headers)
00428     return [body]
00429 
00430 
00431 def select_app_unicode(environ, start_response):
00432     req = Request(environ)
00433     status = b"200 OK"
00434     if req.method == "GET":
00435         body = u("""
00436 <html>
00437     <head><title>form page</title></head>
00438     <body>
00439         <form method="POST" id="single_select_form">
00440             <select id="single" name="single">
00441                 <option value="ЕКБ">Екатеринбург</option>
00442                 <option value="МСК" selected="selected">Москва</option>
00443                 <option value="СПБ">Санкт-Петербург</option>
00444                 <option value="САМ">Самара</option>
00445             </select>
00446             <input name="button" type="submit" value="single">
00447         </form>
00448         <form method="POST" id="multiple_select_form">
00449             <select id="multiple" name="multiple" multiple="multiple">
00450                 <option value="8" selected="selected">Лондон</option>
00451                 <option value="9">Париж</option>
00452                 <option value="10">Пекин</option>
00453                 <option value="11" selected="selected">Бристоль</option>
00454             </select>
00455             <input name="button" type="submit" value="multiple">
00456         </form>
00457     </body>
00458 </html>
00459 """).encode('utf8')
00460     else:
00461         select_type = req.POST.get("button")
00462         if select_type == "single":
00463             selection = req.POST.get("single")
00464         elif select_type == "multiple":
00465             selection = ", ".join(req.POST.getall("multiple"))
00466         body = (u("""
00467 <html>
00468     <head><title>display page</title></head>
00469     <body>
00470         <p>You submitted the %(select_type)s </p>
00471         <p>You selected %(selection)s</p>
00472     </body>
00473 </html>
00474 """) % dict(selection=selection, select_type=select_type)).encode('utf8')
00475     headers = [
00476         ('Content-Type', 'text/html; charset=utf-8'),
00477         ('Content-Length', str(len(body)))]
00478     start_response(status, headers)
00479     if not isinstance(body, binary_type):
00480         raise AssertionError('Body is not %s' % binary_type)
00481     return [body]
00482 
00483 
00484 class TestSelect(unittest.TestCase):
00485 
00486     def test_unicode_select(self):
00487         app = webtest.TestApp(select_app_unicode)
00488         res = app.get('/')
00489         single_form = res.forms["single_select_form"]
00490         self.assertEqual(single_form["single"].value, u("МСК"))
00491 
00492         display = single_form.submit("button")
00493         self.assertIn(u("<p>You selected МСК</p>"), display, display)
00494 
00495         res = app.get('/')
00496         single_form = res.forms["single_select_form"]
00497         self.assertEqual(single_form["single"].value, u("МСК"))
00498         single_form.set("single", u("СПБ"))
00499         self.assertEqual(single_form["single"].value, u("СПБ"))
00500         display = single_form.submit("button")
00501         self.assertIn(u("<p>You selected СПБ</p>"), display, display)
00502 
00503     def test_single_select(self):
00504         app = webtest.TestApp(select_app)
00505         res = app.get('/')
00506         self.assertEqual(res.status_int, 200)
00507         self.assertEqual(res.headers['content-type'],
00508                          'text/html; charset=utf-8')
00509         self.assertEqual(res.content_type, 'text/html')
00510 
00511         single_form = res.forms["single_select_form"]
00512         self.assertEqual(single_form["single"].value, "5")
00513         display = single_form.submit("button")
00514         self.assertIn("<p>You selected 5</p>", display, display)
00515 
00516         res = app.get('/')
00517         self.assertEqual(res.status_int, 200)
00518         self.assertEqual(res.headers['content-type'],
00519                          'text/html; charset=utf-8')
00520         self.assertEqual(res.content_type, 'text/html')
00521 
00522         single_form = res.forms["single_select_form"]
00523         self.assertEqual(single_form["single"].value, "5")
00524         single_form.set("single", "6")
00525         self.assertEqual(single_form["single"].value, "6")
00526         display = single_form.submit("button")
00527         self.assertIn("<p>You selected 6</p>", display, display)
00528 
00529         res = app.get('/')
00530         single_form = res.forms["single_select_form"]
00531         self.assertRaises(ValueError, single_form.select, "single", "5",
00532                           text="Five")
00533         self.assertRaises(ValueError, single_form.select, "single",
00534                           text="Three")
00535         single_form.select("single", text="Seven")
00536         self.assertEqual(single_form["single"].value, "7")
00537         display = single_form.submit("button")
00538         self.assertIn("<p>You selected 7</p>", display, display)
00539 
00540     def test_single_select_forced_value(self):
00541         app = webtest.TestApp(select_app)
00542         res = app.get('/')
00543         self.assertEqual(res.status_int, 200)
00544         self.assertEqual(res.headers['content-type'],
00545                          'text/html; charset=utf-8')
00546         self.assertEqual(res.content_type, 'text/html')
00547 
00548         single_form = res.forms["single_select_form"]
00549         self.assertEqual(single_form["single"].value, "5")
00550         self.assertRaises(ValueError, single_form.set, "single", "984")
00551         single_form["single"].force_value("984")
00552         self.assertEqual(single_form["single"].value, "984")
00553         display = single_form.submit("button")
00554         self.assertIn("<p>You selected 984</p>", display, display)
00555 
00556     def test_single_select_no_default(self):
00557         app = webtest.TestApp(select_app_without_default)
00558         res = app.get('/')
00559         self.assertEqual(res.status_int, 200)
00560         self.assertEqual(res.headers['content-type'],
00561                          'text/html; charset=utf-8')
00562         self.assertEqual(res.content_type, 'text/html')
00563 
00564         single_form = res.forms["single_select_form"]
00565         self.assertEqual(single_form["single"].value, "4")
00566         display = single_form.submit("button")
00567         self.assertIn("<p>You selected 4</p>", display, display)
00568 
00569         res = app.get('/')
00570         self.assertEqual(res.status_int, 200)
00571         self.assertEqual(res.headers['content-type'],
00572                          'text/html; charset=utf-8')
00573         self.assertEqual(res.content_type, 'text/html')
00574 
00575         single_form = res.forms["single_select_form"]
00576         self.assertEqual(single_form["single"].value, "4")
00577         single_form.set("single", 6)
00578         self.assertEqual(single_form["single"].value, "6")
00579         display = single_form.submit("button")
00580         self.assertIn("<p>You selected 6</p>", display, display)
00581 
00582     def test_multiple_select(self):
00583         app = webtest.TestApp(select_app)
00584         res = app.get('/')
00585         self.assertEqual(res.status_int, 200)
00586         self.assertEqual(res.headers['content-type'],
00587                          'text/html; charset=utf-8')
00588         self.assertEqual(res.content_type, 'text/html')
00589 
00590         multiple_form = res.forms["multiple_select_form"]
00591         self.assertEqual(multiple_form["multiple"].value, ['8', '11'],
00592                          multiple_form["multiple"].value)
00593         display = multiple_form.submit("button")
00594         self.assertIn("<p>You selected 8, 11</p>", display, display)
00595 
00596         res = app.get('/')
00597         self.assertEqual(res.status_int, 200)
00598         self.assertEqual(res.headers['content-type'],
00599                          'text/html; charset=utf-8')
00600         self.assertEqual(res.content_type, 'text/html')
00601 
00602         multiple_form = res.forms["multiple_select_form"]
00603         self.assertEqual(multiple_form["multiple"].value, ["8", "11"],
00604                          multiple_form["multiple"].value)
00605         multiple_form.set("multiple", ["9"])
00606         self.assertEqual(multiple_form["multiple"].value, ["9"],
00607                          multiple_form["multiple"].value)
00608         display = multiple_form.submit("button")
00609         self.assertIn("<p>You selected 9</p>", display, display)
00610 
00611         res = app.get('/')
00612         multiple_form = res.forms["multiple_select_form"]
00613         self.assertRaises(ValueError, multiple_form.select_multiple,
00614                           "multiple",
00615                           ["8", "10"], texts=["Eight", "Ten"])
00616         self.assertRaises(ValueError, multiple_form.select_multiple,
00617                           "multiple", texts=["Twelve"])
00618         multiple_form.select_multiple("multiple",
00619                                       texts=["Eight", "Nine", "Ten"])
00620         display = multiple_form.submit("button")
00621         self.assertIn("<p>You selected 8, 9, 10</p>", display, display)
00622 
00623     def test_multiple_select_forced_values(self):
00624         app = webtest.TestApp(select_app)
00625         res = app.get('/')
00626         self.assertEqual(res.status_int, 200)
00627         self.assertEqual(res.headers['content-type'],
00628                          'text/html; charset=utf-8')
00629         self.assertEqual(res.content_type, 'text/html')
00630 
00631         multiple_form = res.forms["multiple_select_form"]
00632         self.assertEqual(multiple_form["multiple"].value, ["8", "11"],
00633                          multiple_form["multiple"].value)
00634         self.assertRaises(ValueError, multiple_form.set,
00635                           "multiple", ["24", "88"])
00636         multiple_form["multiple"].force_value(["24", "88"])
00637         self.assertEqual(multiple_form["multiple"].value, ["24", "88"],
00638                          multiple_form["multiple"].value)
00639         display = multiple_form.submit("button")
00640         self.assertIn("<p>You selected 24, 88</p>", display, display)
00641 
00642     def test_multiple_select_no_default(self):
00643         app = webtest.TestApp(select_app_without_default)
00644         res = app.get('/')
00645         self.assertEqual(res.status_int, 200)
00646         self.assertEqual(res.headers['content-type'],
00647                          'text/html; charset=utf-8')
00648         self.assertEqual(res.content_type, 'text/html')
00649 
00650         multiple_form = res.forms["multiple_select_form"]
00651         self.assertTrue(multiple_form["multiple"].value is None,
00652                         repr(multiple_form["multiple"].value))
00653         display = multiple_form.submit("button")
00654         self.assertIn("<p>You selected </p>", display, display)
00655 
00656         res = app.get('/')
00657         self.assertEqual(res.status_int, 200)
00658         self.assertEqual(res.headers['content-type'],
00659                          'text/html; charset=utf-8')
00660         self.assertEqual(res.content_type, 'text/html')
00661 
00662         multiple_form = res.forms["multiple_select_form"]
00663         self.assertTrue(multiple_form["multiple"].value is None,
00664                         multiple_form["multiple"].value)
00665         multiple_form.set("multiple", ["9"])
00666         self.assertEqual(multiple_form["multiple"].value, ["9"],
00667                          multiple_form["multiple"].value)
00668         display = multiple_form.submit("button")
00669         self.assertIn("<p>You selected 9</p>", display, display)
00670 
00671     def test_select_no_value(self):
00672         app = webtest.TestApp(select_app_without_values)
00673         res = app.get('/')
00674         self.assertEqual(res.status_int, 200)
00675         self.assertEqual(res.headers['content-type'],
00676                          'text/html; charset=utf-8')
00677         self.assertEqual(res.content_type, 'text/html')
00678 
00679         single_form = res.forms["single_select_form"]
00680         self.assertEqual(single_form["single"].value, "Four")
00681         display = single_form.submit("button")
00682         self.assertIn("<p>You selected Four</p>", display, display)
00683 
00684         res = app.get('/')
00685         self.assertEqual(res.status_int, 200)
00686         self.assertEqual(res.headers['content-type'],
00687                          'text/html; charset=utf-8')
00688         self.assertEqual(res.content_type, 'text/html')
00689 
00690         single_form = res.forms["single_select_form"]
00691         self.assertEqual(single_form["single"].value, "Four")
00692         single_form.set("single", "Six")
00693         self.assertEqual(single_form["single"].value, "Six")
00694         display = single_form.submit("button")
00695         self.assertIn("<p>You selected Six</p>", display, display)
00696 
00697     def test_multiple_select_no_value(self):
00698         app = webtest.TestApp(select_app_without_values)
00699         res = app.get('/')
00700         self.assertEqual(res.status_int, 200)
00701         self.assertEqual(res.headers['content-type'],
00702                          'text/html; charset=utf-8')
00703         self.assertEqual(res.content_type, 'text/html')
00704 
00705         multiple_form = res.forms["multiple_select_form"]
00706         self.assertEqual(multiple_form["multiple"].value, ["Nine", "Eleven"])
00707         display = multiple_form.submit("button")
00708         self.assertIn("<p>You selected Nine, Eleven</p>", display, display)
00709 
00710         res = app.get('/')
00711         self.assertEqual(res.status_int, 200)
00712         self.assertEqual(res.headers['content-type'],
00713                          'text/html; charset=utf-8')
00714         self.assertEqual(res.content_type, 'text/html')
00715 
00716         multiple_form = res.forms["multiple_select_form"]
00717         self.assertEqual(multiple_form["multiple"].value, ["Nine", "Eleven"])
00718         multiple_form.set("multiple", ["Nine", "Ten"])
00719         self.assertEqual(multiple_form["multiple"].value, ["Nine", "Ten"])
00720         display = multiple_form.submit("button")
00721         self.assertIn("<p>You selected Nine, Ten</p>", display, display)
00722 
00723 
00724 class SingleUploadFileApp(object):
00725 
00726     body = b"""
00727 <html>
00728     <head><title>form page</title></head>
00729     <body>
00730         <form method="POST" id="file_upload_form"
00731               enctype="multipart/form-data">
00732             <input name="file-field" type="file" value="some/path/file.txt" />
00733             <input name="button" type="submit" value="single">
00734         </form>
00735     </body>
00736 </html>
00737 """
00738 
00739     def __call__(self, environ, start_response):
00740         req = Request(environ)
00741         status = b"200 OK"
00742         if req.method == "GET":
00743             body = self.body
00744         else:
00745             body = b"""
00746 <html>
00747     <head><title>display page</title></head>
00748     <body>
00749         """ + self.get_files_page(req) + b"""
00750     </body>
00751 </html>
00752 """
00753         headers = [
00754             ('Content-Type', 'text/html; charset=utf-8'),
00755             ('Content-Length', str(len(body)))]
00756         start_response(status, headers)
00757         assert(isinstance(body, binary_type))
00758         return [body]
00759 
00760     def get_files_page(self, req):
00761         file_parts = []
00762         uploaded_files = [(k, v) for k, v in req.POST.items() if 'file' in k]
00763         uploaded_files = sorted(uploaded_files)
00764         for name, uploaded_file in uploaded_files:
00765             filename = to_bytes(uploaded_file.filename)
00766             value = to_bytes(uploaded_file.value, 'ascii')
00767             content_type = to_bytes(uploaded_file.type, 'ascii')
00768             file_parts.append(b"""
00769         <p>You selected '""" + filename + b"""'</p>
00770         <p>with contents: '""" + value + b"""'</p>
00771         <p>with content type: '""" + content_type + b"""'</p>
00772 """)
00773         return b''.join(file_parts)
00774 
00775 
00776 class UploadBinaryApp(SingleUploadFileApp):
00777 
00778     def get_files_page(self, req):
00779         uploaded_files = [(k, v) for k, v in req.POST.items() if 'file' in k]
00780         data = uploaded_files[0][1].value
00781         if PY3:
00782             data = struct.unpack(b'255h', data[:510])
00783         else:
00784             data = struct.unpack(str('255h'), data)
00785         return b','.join([to_bytes(str(i)) for i in data])
00786 
00787 
00788 class MultipleUploadFileApp(SingleUploadFileApp):
00789     body = b"""
00790 <html>
00791     <head><title>form page</title></head>
00792     <body>
00793         <form method="POST" id="file_upload_form"
00794               enctype="multipart/form-data">
00795             <input name="file-field-1" type="file" />
00796             <input name="file-field-2" type="file" />
00797             <input name="button" type="submit" value="single">
00798         </form>
00799     </body>
00800 </html>
00801 """
00802 
00803 
00804 class TestFileUpload(unittest.TestCase):
00805 
00806     def assertFile(self, name, contents, display, content_type=None):
00807         if isinstance(name, six.binary_type):
00808             text_name = name.decode('ascii')
00809         else:
00810             text_name = name
00811         self.assertIn("<p>You selected '" + text_name + "'</p>",
00812                       display, display)
00813         if isinstance(contents, six.binary_type):
00814             text_contents = contents.decode('ascii')
00815         else:
00816             text_contents = contents
00817         self.assertIn("<p>with contents: '" + text_contents + "'</p>",
00818                       display, display)
00819         if content_type:
00820             self.assertIn("<p>with content type: '" + content_type + "'</p>",
00821                           display, display)
00822 
00823     def test_no_uploads_error(self):
00824         app = webtest.TestApp(SingleUploadFileApp())
00825         app.get('/').forms["file_upload_form"].upload_fields()
00826 
00827     def test_upload_without_file(self):
00828         app = webtest.TestApp(SingleUploadFileApp())
00829         upload_form = app.get('/').forms["file_upload_form"]
00830         upload_form.submit()
00831 
00832     def test_file_upload_with_filename_only(self):
00833         uploaded_file_name = os.path.join(os.path.dirname(__file__),
00834                                           "__init__.py")
00835         uploaded_file_contents = open(uploaded_file_name).read()
00836         if PY3:
00837             uploaded_file_contents = to_bytes(uploaded_file_contents)
00838 
00839         app = webtest.TestApp(SingleUploadFileApp())
00840         res = app.get('/')
00841         self.assertEqual(res.status_int, 200)
00842         self.assertEqual(res.headers['content-type'],
00843                          'text/html; charset=utf-8')
00844         self.assertEqual(res.content_type, 'text/html')
00845         self.assertEqual(res.charset, 'utf-8')
00846 
00847         single_form = res.forms["file_upload_form"]
00848         single_form.set("file-field", (uploaded_file_name,))
00849         display = single_form.submit("button")
00850         self.assertFile(uploaded_file_name, uploaded_file_contents, display)
00851 
00852     def test_file_upload_with_filename_and_contents(self):
00853         uploaded_file_name = os.path.join(os.path.dirname(__file__),
00854                                           "__init__.py")
00855         uploaded_file_contents = open(uploaded_file_name).read()
00856         if PY3:
00857             uploaded_file_contents = to_bytes(uploaded_file_contents)
00858 
00859         app = webtest.TestApp(SingleUploadFileApp())
00860         res = app.get('/')
00861         self.assertEqual(res.status_int, 200)
00862         self.assertEqual(res.headers['content-type'],
00863                          'text/html; charset=utf-8')
00864         self.assertEqual(res.content_type, 'text/html')
00865 
00866         single_form = res.forms["file_upload_form"]
00867         single_form.set("file-field",
00868                         (uploaded_file_name, uploaded_file_contents))
00869         display = single_form.submit("button")
00870         self.assertFile(uploaded_file_name, uploaded_file_contents, display)
00871 
00872     def test_file_upload_with_content_type(self):
00873         uploaded_file_name = os.path.join(os.path.dirname(__file__),
00874                                           "__init__.py")
00875         with open(uploaded_file_name, 'rb') as f:
00876             uploaded_file_contents = f.read()
00877         app = webtest.TestApp(SingleUploadFileApp())
00878         res = app.get('/')
00879         single_form = res.forms["file_upload_form"]
00880         single_form["file-field"].value = Upload(uploaded_file_name,
00881                                                  uploaded_file_contents,
00882                                                  'text/x-custom-type')
00883         display = single_form.submit("button")
00884         self.assertFile(uploaded_file_name, uploaded_file_contents, display,
00885                         content_type='text/x-custom-type')
00886 
00887     def test_file_upload_binary(self):
00888         binary_data = struct.pack(str('255h'), *range(0, 255))
00889         app = webtest.TestApp(UploadBinaryApp())
00890         res = app.get('/')
00891         single_form = res.forms["file_upload_form"]
00892         single_form.set("file-field", ('my_file.dat', binary_data))
00893         display = single_form.submit("button")
00894         self.assertIn(','.join([str(n) for n in range(0, 255)]), display)
00895 
00896     def test_multiple_file_uploads_with_filename_and_contents(self):
00897         uploaded_file1_name = os.path.join(os.path.dirname(__file__),
00898                                            "__init__.py")
00899         uploaded_file1_contents = open(uploaded_file1_name).read()
00900         if PY3:
00901             uploaded_file1_contents = to_bytes(uploaded_file1_contents)
00902         uploaded_file2_name = __file__
00903         uploaded_file2_name = os.path.join(os.path.dirname(__file__), 'html',
00904                                            "404.html")
00905         uploaded_file2_contents = open(uploaded_file2_name).read()
00906         if PY3:
00907             uploaded_file2_contents = to_bytes(uploaded_file2_contents)
00908 
00909         app = webtest.TestApp(MultipleUploadFileApp())
00910         res = app.get('/')
00911         self.assertEqual(res.status_int, 200)
00912         self.assertEqual(res.headers['content-type'],
00913                          'text/html; charset=utf-8')
00914         self.assertEqual(res.content_type, 'text/html')
00915 
00916         single_form = res.forms["file_upload_form"]
00917         single_form.set("file-field-1",
00918                         (uploaded_file1_name, uploaded_file1_contents))
00919         single_form.set("file-field-2",
00920                         (uploaded_file2_name, uploaded_file2_contents))
00921         display = single_form.submit("button")
00922         self.assertFile(uploaded_file1_name, uploaded_file1_contents, display)
00923         self.assertFile(uploaded_file1_name, uploaded_file1_contents, display)
00924 
00925     def test_upload_invalid_content(self):
00926         app = webtest.TestApp(SingleUploadFileApp())
00927         res = app.get('/')
00928         single_form = res.forms["file_upload_form"]
00929         single_form.set("file-field", ('my_file.dat', 1))
00930         try:
00931             single_form.submit("button")
00932         except ValueError:
00933             e = sys.exc_info()[1]
00934             self.assertEquals(
00935                 six.text_type(e),
00936                 u('File content must be %s not %s' % (binary_type, int))
00937             )
00938 
00939     def test_invalid_uploadfiles(self):
00940         app = webtest.TestApp(SingleUploadFileApp())
00941         self.assertRaises(ValueError, app.post, '/', upload_files=[()])
00942         self.assertRaises(
00943             ValueError,
00944             app.post, '/',
00945             upload_files=[('name', 'filename', 'content', 'extra')]
00946         )
00947 
00948     def test_goto_upload_files(self):
00949         app = webtest.TestApp(SingleUploadFileApp())
00950         resp = app.get('/')
00951         resp = resp.goto(
00952             '/',
00953             method='post',
00954             upload_files=[('file', 'filename', b'content')]
00955         )
00956         resp.mustcontain("<p>You selected 'filename'</p>",
00957                          "<p>with contents: 'content'</p>")
00958 
00959     def test_post_upload_files(self):
00960         app = webtest.TestApp(SingleUploadFileApp())
00961         resp = app.post(
00962             '/',
00963             upload_files=[('file', 'filename', b'content')]
00964         )
00965         resp.mustcontain("<p>You selected 'filename'</p>",
00966                          "<p>with contents: 'content'</p>")


webtest
Author(s): AlexV
autogenerated on Sat Jun 8 2019 20:32:07