| # -*- coding: utf-8 -*- |
| from __future__ import unicode_literals |
| |
| import cgi |
| import os.path |
| import struct |
| import sys |
| |
| import webtest |
| import six |
| from six import binary_type |
| from six import PY3 |
| from webob import Request |
| from webtest.debugapp import DebugApp |
| from webtest.compat import to_bytes |
| from webtest.forms import NoValue, Submit, Upload |
| from tests.compat import unittest |
| from tests.compat import u |
| |
| |
| class TestForms(unittest.TestCase): |
| |
| def callFUT(self, filename='form_inputs.html', formid='simple_form'): |
| dirname = os.path.join(os.path.dirname(__file__), 'html') |
| app = DebugApp(form=os.path.join(dirname, filename), show_form=True) |
| resp = webtest.TestApp(app).get('/form.html') |
| return resp.forms[formid] |
| |
| def test_set_submit_field(self): |
| form = self.callFUT() |
| self.assertRaises( |
| AttributeError, |
| form['submit'].value__set, |
| 'foo' |
| ) |
| |
| def test_button(self): |
| form = self.callFUT() |
| button = form['button'] |
| self.assertTrue(isinstance(button, Submit), |
| "<button> without type is a submit button") |
| |
| def test_force_select(self): |
| form = self.callFUT() |
| form['select'].force_value('notavalue') |
| form['select'].value__set('value3') |
| |
| self.assertTrue( |
| form['select']._forced_value is NoValue, |
| "Setting a value after having forced a value should keep a forced" |
| " state") |
| self.assertEqual( |
| form['select'].value, 'value3', |
| "the value should the the one set by value__set") |
| self.assertEqual( |
| form['select'].selectedIndex, 2, |
| "the value index should be the one set by value__set") |
| |
| def test_form_select(self): |
| form = self.callFUT() |
| form.select('select', 'value1') |
| |
| self.assertEqual( |
| form['select'].value, 'value1', |
| "when using form.select, the input selected value should be " |
| "changed") |
| |
| def test_get_field_by_index(self): |
| form = self.callFUT() |
| self.assertEqual(form['select'], |
| form.get('select', index=0)) |
| |
| def test_get_unknown_field(self): |
| form = self.callFUT() |
| self.assertEqual(form['unknown'].value, '') |
| form['unknown'].value = '1' |
| self.assertEqual(form['unknown'].value, '1') |
| |
| def test_get_non_exist_fields(self): |
| form = self.callFUT() |
| self.assertRaises(AssertionError, form.get, 'nonfield') |
| |
| def test_get_non_exist_fields_with_default(self): |
| form = self.callFUT() |
| value = form.get('nonfield', default=1) |
| self.assertEqual(value, 1) |
| |
| def test_upload_fields(self): |
| form = self.callFUT() |
| fu = webtest.Upload(__file__) |
| form['file'] = fu |
| self.assertEqual(form.upload_fields(), |
| [['file', __file__]]) |
| |
| def test_repr(self): |
| form = self.callFUT() |
| self.assertTrue(repr(form).startswith('<Form id=')) |
| |
| def test_the_bs_node_must_not_change(self): |
| form = self.callFUT() |
| self.assertEqual(form.text, str(form.html)) |
| |
| def test_set_multiple_checkboxes(self): |
| form = self.callFUT(formid='multiple_checkbox_form') |
| form['checkbox'] = [10, 30] |
| |
| self.assertEqual(form.get('checkbox', index=0).value, '10') |
| self.assertEqual(form.get('checkbox', index=1).value, None) |
| self.assertEqual(form.get('checkbox', index=2).value, '30') |
| |
| def test_button_submit(self): |
| form = self.callFUT(formid='multiple_buttons_form') |
| display = form.submit('action') |
| self.assertIn(u("action=deactivate"), display, display) |
| |
| def test_button_submit_by_index(self): |
| form = self.callFUT(formid='multiple_buttons_form') |
| display = form.submit('action', index=1) |
| self.assertIn(u("action=activate"), display, display) |
| |
| def test_button_submit_by_value(self): |
| form = self.callFUT(formid='multiple_buttons_form') |
| display = form.submit('action', value='activate') |
| self.assertIn(u("action=activate"), display, display) |
| |
| def test_button_submit_by_value_and_index(self): |
| form = self.callFUT(formid='multiple_buttons_form') |
| self.assertRaises(ValueError, |
| form.submit, "action", value="activate", |
| index=0) |
| |
| |
| class TestResponseFormAttribute(unittest.TestCase): |
| |
| def callFUT(self, body): |
| app = DebugApp(form=to_bytes(body)) |
| return webtest.TestApp(app) |
| |
| def test_no_form(self): |
| app = self.callFUT('<html><body></body></html>') |
| res = app.get('/form.html') |
| self.assertRaises(TypeError, lambda: res.form) |
| |
| def test_too_many_forms(self): |
| app = self.callFUT( |
| '<html><body><form></form><form></form></body></html>') |
| res = app.get('/form.html') |
| self.assertRaises(TypeError, lambda: res.form) |
| |
| |
| class TestInput(unittest.TestCase): |
| |
| def callFUT(self, filename='form_inputs.html'): |
| dirname = os.path.join(os.path.dirname(__file__), 'html') |
| app = DebugApp(form=os.path.join(dirname, filename), show_form=True) |
| return webtest.TestApp(app) |
| |
| def test_input(self): |
| app = self.callFUT() |
| res = app.get('/form.html') |
| self.assertEqual(res.status_int, 200) |
| self.assertTrue(res.content_type.startswith('text/html')) |
| |
| form = res.forms['text_input_form'] |
| self.assertEqual(form['foo'].value, 'bar') |
| self.assertEqual(form.submit_fields(), [('foo', 'bar')]) |
| |
| form = res.forms['radio_input_form'] |
| self.assertEqual(form['foo'].selectedIndex, 1) |
| self.assertEqual(form['foo'].value, 'baz') |
| self.assertEqual(form.submit_fields(), [('foo', 'baz')]) |
| |
| form = res.forms['checkbox_input_form'] |
| self.assertEqual(form['foo'].value, 'bar') |
| self.assertEqual(form.submit_fields(), [('foo', 'bar')]) |
| |
| form = res.forms['password_input_form'] |
| self.assertEqual(form['foo'].value, 'bar') |
| self.assertEqual(form.submit_fields(), [('foo', 'bar')]) |
| |
| def test_force_radio_input(self): |
| app = self.callFUT() |
| res = app.get('/form.html') |
| |
| form = res.forms['radio_input_form'] |
| |
| form['foo'].force_value('fido') |
| self.assertEqual(form['foo'].value, 'fido') |
| self.assertEqual(form.submit_fields(), [('foo', 'fido')]) |
| |
| def test_radio_input_order(self): |
| app = self.callFUT() |
| res = app.get('/form.html') |
| self.assertEqual(res.status_int, 200) |
| self.assertTrue(res.content_type.startswith('text/html')) |
| |
| form = res.forms['complex_radio_input_form'] |
| form['foo'].value = 'true' |
| self.assertEqual(form['foo'].value, 'true') |
| self.assertEqual(form['foo'].selectedIndex, 0) |
| self.assertEqual(form.submit_fields(), [ |
| (u'__start__', u'item:mapping'), |
| ('foo', 'true'), |
| (u'__end__', u'item:mapping'), |
| (u'__start__', u'item:mapping'), |
| (u'__end__', u'item:mapping')]) |
| |
| res = app.get('/form.html') |
| form = res.forms['complex_radio_input_form'] |
| self.assertEqual(form['foo'].value, 'true') |
| self.assertEqual(form['foo'].selectedIndex, 1) |
| self.assertEqual(form.submit_fields(), [ |
| (u'__start__', u'item:mapping'), |
| (u'__end__', u'item:mapping'), |
| (u'__start__', u'item:mapping'), |
| ('foo', 'true'), |
| (u'__end__', u'item:mapping')]) |
| |
| def test_input_unicode(self): |
| app = self.callFUT('form_unicode_inputs.html') |
| res = app.get('/form.html') |
| self.assertEqual(res.status_int, 200) |
| self.assertTrue(res.content_type.startswith('text/html')) |
| self.assertEqual(res.charset.lower(), 'utf-8') |
| |
| form = res.forms['text_input_form'] |
| self.assertEqual(form['foo'].value, u('Хармс')) |
| self.assertEqual(form.submit_fields(), [('foo', u('Хармс'))]) |
| |
| form = res.forms['radio_input_form'] |
| self.assertEqual(form['foo'].selectedIndex, 1) |
| self.assertEqual(form['foo'].value, u('Блок')) |
| self.assertEqual(form.submit_fields(), [('foo', u('Блок'))]) |
| |
| form = res.forms['checkbox_input_form'] |
| self.assertEqual(form['foo'].value, u('Хармс')) |
| self.assertEqual(form.submit_fields(), [('foo', u('Хармс'))]) |
| |
| form = res.forms['password_input_form'] |
| self.assertEqual(form['foo'].value, u('Хармс')) |
| self.assertEqual(form.submit_fields(), [('foo', u('Хармс'))]) |
| |
| def test_input_no_default(self): |
| app = self.callFUT('form_inputs_with_defaults.html') |
| res = app.get('/form.html') |
| self.assertEqual(res.status_int, 200) |
| self.assertTrue(res.content_type.startswith('text/html')) |
| |
| form = res.forms['text_input_form'] |
| self.assertEqual(form['foo'].value, '') |
| self.assertEqual(form.submit_fields(), [('foo', '')]) |
| |
| form = res.forms['radio_input_form'] |
| self.assertTrue(form['foo'].value is None) |
| self.assertEqual(form.submit_fields(), []) |
| |
| form = res.forms['checkbox_input_form'] |
| self.assertTrue(form['foo'].value is None) |
| self.assertEqual(form.submit_fields(), []) |
| |
| form = res.forms['password_input_form'] |
| self.assertEqual(form['foo'].value, '') |
| self.assertEqual(form.submit_fields(), [('foo', '')]) |
| |
| def test_textarea_entities(self): |
| app = self.callFUT() |
| res = app.get('/form.html') |
| form = res.forms.get("textarea_input_form") |
| self.assertEqual(form.get("textarea").value, "'foo&bar'") |
| self.assertEqual(form.submit_fields(), [('textarea', "'foo&bar'")]) |
| |
| def test_textarea_emptyfirstline(self): |
| app = self.callFUT() |
| res = app.get('/form.html') |
| form = res.forms.get("textarea_emptyline_form") |
| self.assertEqual(form.get("textarea").value, "aaa") |
| self.assertEqual(form.submit_fields(), [('textarea', "aaa")]) |
| |
| |
| class TestFormLint(unittest.TestCase): |
| |
| def test_form_lint(self): |
| form = webtest.Form(None, '''<form> |
| <input type="text" name="field"/> |
| </form>''') |
| self.assertRaises(AttributeError, form.lint) |
| |
| form = webtest.Form(None, '''<form> |
| <input type="text" id="myfield" name="field"/> |
| </form>''') |
| self.assertRaises(AttributeError, form.lint) |
| |
| form = webtest.Form(None, '''<form> |
| <label for="myfield">my field</label> |
| <input type="text" id="myfield" name="field"/> |
| </form>''') |
| form.lint() |
| |
| form = webtest.Form(None, '''<form> |
| <label class="field" for="myfield" role="r">my field</label> |
| <input type="text" id="myfield" name="field"/> |
| </form>''') |
| form.lint() |
| |
| |
| def select_app(environ, start_response): |
| req = Request(environ) |
| status = b"200 OK" |
| if req.method == "GET": |
| body = to_bytes(""" |
| <html> |
| <head><title>form page</title></head> |
| <body> |
| <form method="POST" id="single_select_form"> |
| <select id="single" name="single"> |
| <option value="4">Four</option> |
| <option value="5" selected="selected">Five</option> |
| <option value="6">Six</option> |
| <option value="7">Seven</option> |
| </select> |
| <input name="button" type="submit" value="single"> |
| </form> |
| <form method="POST" id="multiple_select_form"> |
| <select id="multiple" name="multiple" multiple> |
| <option value="8" selected="selected">Eight</option> |
| <option value="9">Nine</option> |
| <option value="10">Ten</option> |
| <option value="11" selected="selected">Eleven</option> |
| </select> |
| <input name="button" type="submit" value="multiple"> |
| </form> |
| </body> |
| </html> |
| """) |
| else: |
| select_type = req.POST.get("button") |
| if select_type == "single": |
| selection = req.POST.get("single") |
| elif select_type == "multiple": |
| selection = ", ".join(req.POST.getall("multiple")) |
| body = to_bytes(""" |
| <html> |
| <head><title>display page</title></head> |
| <body> |
| <p>You submitted the %(select_type)s </p> |
| <p>You selected %(selection)s</p> |
| </body> |
| </html> |
| """ % dict(selection=selection, select_type=select_type)) |
| |
| headers = [ |
| ('Content-Type', 'text/html; charset=utf-8'), |
| ('Content-Length', str(len(body)))] |
| # PEP 3333 requires native strings: |
| headers = [(str(k), str(v)) for k, v in headers] |
| start_response(status, headers) |
| return [body] |
| |
| |
| def select_app_without_values(environ, start_response): |
| req = Request(environ) |
| status = b"200 OK" |
| if req.method == "GET": |
| body = to_bytes(""" |
| <html> |
| <head><title>form page</title></head> |
| <body> |
| <form method="POST" id="single_select_form"> |
| <select id="single" name="single"> |
| <option>Four</option> |
| <option>Five</option> |
| <option>Six</option> |
| <option>Seven</option> |
| </select> |
| <input name="button" type="submit" value="single"> |
| </form> |
| <form method="POST" id="multiple_select_form"> |
| <select id="multiple" name="multiple" multiple="multiple"> |
| <option>Eight</option> |
| <option selected value="Nine">Nine</option> |
| <option>Ten</option> |
| <option selected>Eleven</option> |
| </select> |
| <input name="button" type="submit" value="multiple"> |
| </form> |
| </body> |
| </html> |
| """) |
| else: |
| select_type = req.POST.get("button") |
| if select_type == "single": |
| selection = req.POST.get("single") |
| elif select_type == "multiple": |
| selection = ", ".join(req.POST.getall("multiple")) |
| body = to_bytes(""" |
| <html> |
| <head><title>display page</title></head> |
| <body> |
| <p>You submitted the %(select_type)s </p> |
| <p>You selected %(selection)s</p> |
| </body> |
| </html> |
| """ % dict(selection=selection, select_type=select_type)) |
| |
| headers = [ |
| ('Content-Type', 'text/html; charset=utf-8'), |
| ('Content-Length', str(len(body)))] |
| # PEP 3333 requires native strings: |
| headers = [(str(k), str(v)) for k, v in headers] |
| start_response(status, headers) |
| return [body] |
| |
| |
| def select_app_without_default(environ, start_response): |
| req = Request(environ) |
| status = b"200 OK" |
| if req.method == "GET": |
| body = to_bytes(""" |
| <html> |
| <head><title>form page</title></head> |
| <body> |
| <form method="POST" id="single_select_form"> |
| <select id="single" name="single"> |
| <option value="4">Four</option> |
| <option value="5">Five</option> |
| <option value="6">Six</option> |
| <option value="7">Seven</option> |
| </select> |
| <input name="button" type="submit" value="single"> |
| </form> |
| <form method="POST" id="multiple_select_form"> |
| <select id="multiple" name="multiple" multiple="multiple"> |
| <option value="8">Eight</option> |
| <option value="9">Nine</option> |
| <option value="10">Ten</option> |
| <option value="11">Eleven</option> |
| </select> |
| <input name="button" type="submit" value="multiple"> |
| </form> |
| </body> |
| </html> |
| """) |
| else: |
| select_type = req.POST.get("button") |
| if select_type == "single": |
| selection = req.POST.get("single") |
| elif select_type == "multiple": |
| selection = ", ".join(req.POST.getall("multiple")) |
| body = to_bytes(""" |
| <html> |
| <head><title>display page</title></head> |
| <body> |
| <p>You submitted the %(select_type)s </p> |
| <p>You selected %(selection)s</p> |
| </body> |
| </html> |
| """ % dict(selection=selection, select_type=select_type)) |
| |
| headers = [ |
| ('Content-Type', 'text/html; charset=utf-8'), |
| ('Content-Length', str(len(body)))] |
| # PEP 3333 requires native strings: |
| headers = [(str(k), str(v)) for k, v in headers] |
| start_response(status, headers) |
| return [body] |
| |
| |
| def select_app_unicode(environ, start_response): |
| req = Request(environ) |
| status = b"200 OK" |
| if req.method == "GET": |
| body = u(""" |
| <html> |
| <head><title>form page</title></head> |
| <body> |
| <form method="POST" id="single_select_form"> |
| <select id="single" name="single"> |
| <option value="ЕКБ">Екатеринбург</option> |
| <option value="МСК" selected="selected">Москва</option> |
| <option value="СПБ">Санкт-Петербург</option> |
| <option value="САМ">Самара</option> |
| </select> |
| <input name="button" type="submit" value="single"> |
| </form> |
| <form method="POST" id="multiple_select_form"> |
| <select id="multiple" name="multiple" multiple="multiple"> |
| <option value="8" selected="selected">Лондон</option> |
| <option value="9">Париж</option> |
| <option value="10">Пекин</option> |
| <option value="11" selected="selected">Бристоль</option> |
| </select> |
| <input name="button" type="submit" value="multiple"> |
| </form> |
| </body> |
| </html> |
| """).encode('utf8') |
| else: |
| select_type = req.POST.get("button") |
| if select_type == "single": |
| selection = req.POST.get("single") |
| elif select_type == "multiple": |
| selection = ", ".join(req.POST.getall("multiple")) |
| body = (u(""" |
| <html> |
| <head><title>display page</title></head> |
| <body> |
| <p>You submitted the %(select_type)s </p> |
| <p>You selected %(selection)s</p> |
| </body> |
| </html> |
| """) % dict(selection=selection, select_type=select_type)).encode('utf8') |
| headers = [ |
| ('Content-Type', 'text/html; charset=utf-8'), |
| ('Content-Length', str(len(body)))] |
| # PEP 3333 requires native strings: |
| headers = [(str(k), str(v)) for k, v in headers] |
| start_response(status, headers) |
| if not isinstance(body, binary_type): |
| raise AssertionError('Body is not %s' % binary_type) |
| return [body] |
| |
| |
| class TestSelect(unittest.TestCase): |
| |
| def test_unicode_select(self): |
| app = webtest.TestApp(select_app_unicode) |
| res = app.get('/') |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, u("МСК")) |
| |
| display = single_form.submit("button") |
| self.assertIn(u("<p>You selected МСК</p>"), display, display) |
| |
| res = app.get('/') |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, u("МСК")) |
| single_form.set("single", u("СПБ")) |
| self.assertEqual(single_form["single"].value, u("СПБ")) |
| display = single_form.submit("button") |
| self.assertIn(u("<p>You selected СПБ</p>"), display, display) |
| |
| def test_single_select(self): |
| app = webtest.TestApp(select_app) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, "5") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected 5</p>", display, display) |
| |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, "5") |
| single_form.set("single", "6") |
| self.assertEqual(single_form["single"].value, "6") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected 6</p>", display, display) |
| |
| res = app.get('/') |
| single_form = res.forms["single_select_form"] |
| self.assertRaises(ValueError, single_form.select, "single", "5", |
| text="Five") |
| self.assertRaises(ValueError, single_form.select, "single", |
| text="Three") |
| single_form.select("single", text="Seven") |
| self.assertEqual(single_form["single"].value, "7") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected 7</p>", display, display) |
| |
| def test_single_select_forced_value(self): |
| app = webtest.TestApp(select_app) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, "5") |
| self.assertRaises(ValueError, single_form.set, "single", "984") |
| single_form["single"].force_value("984") |
| self.assertEqual(single_form["single"].value, "984") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected 984</p>", display, display) |
| |
| def test_single_select_no_default(self): |
| app = webtest.TestApp(select_app_without_default) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, "4") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected 4</p>", display, display) |
| |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, "4") |
| single_form.set("single", 6) |
| self.assertEqual(single_form["single"].value, "6") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected 6</p>", display, display) |
| |
| def test_multiple_select(self): |
| app = webtest.TestApp(select_app) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertEqual(multiple_form["multiple"].value, ['8', '11'], |
| multiple_form["multiple"].value) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected 8, 11</p>", display, display) |
| |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertEqual(multiple_form["multiple"].value, ["8", "11"], |
| multiple_form["multiple"].value) |
| multiple_form.set("multiple", ["9"]) |
| self.assertEqual(multiple_form["multiple"].value, ["9"], |
| multiple_form["multiple"].value) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected 9</p>", display, display) |
| |
| res = app.get('/') |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertRaises(ValueError, multiple_form.select_multiple, |
| "multiple", |
| ["8", "10"], texts=["Eight", "Ten"]) |
| self.assertRaises(ValueError, multiple_form.select_multiple, |
| "multiple", texts=["Twelve"]) |
| multiple_form.select_multiple("multiple", |
| texts=["Eight", "Nine", "Ten"]) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected 8, 9, 10</p>", display, display) |
| |
| def test_multiple_select_forced_values(self): |
| app = webtest.TestApp(select_app) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertEqual(multiple_form["multiple"].value, ["8", "11"], |
| multiple_form["multiple"].value) |
| self.assertRaises(ValueError, multiple_form.set, |
| "multiple", ["24", "88"]) |
| multiple_form["multiple"].force_value(["24", "88"]) |
| self.assertEqual(multiple_form["multiple"].value, ["24", "88"], |
| multiple_form["multiple"].value) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected 24, 88</p>", display, display) |
| |
| def test_multiple_select_no_default(self): |
| app = webtest.TestApp(select_app_without_default) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertTrue(multiple_form["multiple"].value is None, |
| repr(multiple_form["multiple"].value)) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected </p>", display, display) |
| |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertTrue(multiple_form["multiple"].value is None, |
| multiple_form["multiple"].value) |
| multiple_form.set("multiple", ["9"]) |
| self.assertEqual(multiple_form["multiple"].value, ["9"], |
| multiple_form["multiple"].value) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected 9</p>", display, display) |
| |
| def test_select_no_value(self): |
| app = webtest.TestApp(select_app_without_values) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, "Four") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected Four</p>", display, display) |
| |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["single_select_form"] |
| self.assertEqual(single_form["single"].value, "Four") |
| single_form.set("single", "Six") |
| self.assertEqual(single_form["single"].value, "Six") |
| display = single_form.submit("button") |
| self.assertIn("<p>You selected Six</p>", display, display) |
| |
| def test_multiple_select_no_value(self): |
| app = webtest.TestApp(select_app_without_values) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertEqual(multiple_form["multiple"].value, ["Nine", "Eleven"]) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected Nine, Eleven</p>", display, display) |
| |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertEqual(multiple_form["multiple"].value, ["Nine", "Eleven"]) |
| multiple_form.set("multiple", ["Nine", "Ten"]) |
| self.assertEqual(multiple_form["multiple"].value, ["Nine", "Ten"]) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected Nine, Ten</p>", display, display) |
| |
| def test_multiple_select_reset_value(self): |
| app = webtest.TestApp(select_app_without_values) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| multiple_form = res.forms["multiple_select_form"] |
| self.assertEqual(multiple_form["multiple"].value, ["Nine", "Eleven"]) |
| multiple_form["multiple"].force_value(None) |
| self.assertIsNone(multiple_form["multiple"].value) |
| display = multiple_form.submit("button") |
| self.assertIn("<p>You selected </p>", display, display) |
| |
| |
| class SingleUploadFileApp(object): |
| |
| body = b""" |
| <html> |
| <head><title>form page</title></head> |
| <body> |
| <form method="POST" id="file_upload_form" |
| enctype="multipart/form-data"> |
| <input name="file-field" type="file" value="some/path/file.txt" /> |
| <input name="int-field" type="text" value="" /> |
| <input name="button" type="submit" value="single"> |
| </form> |
| </body> |
| </html> |
| """ |
| |
| def __call__(self, environ, start_response): |
| req = Request(environ) |
| status = b"200 OK" |
| if req.method == "GET": |
| body = self.body |
| else: |
| body = b""" |
| <html> |
| <head><title>display page</title></head> |
| <body> |
| """ + self.get_files_page(req) + b""" |
| </body> |
| </html> |
| """ |
| headers = [ |
| ('Content-Type', 'text/html; charset=utf-8'), |
| ('Content-Length', str(len(body)))] |
| # PEP 3333 requires native strings: |
| headers = [(str(k), str(v)) for k, v in headers] |
| start_response(status, headers) |
| assert(isinstance(body, binary_type)) |
| return [body] |
| |
| def get_files_page(self, req): |
| file_parts = [] |
| uploaded_files = [(k, v) for k, v in req.POST.items() if 'file' in k] |
| uploaded_files = sorted(uploaded_files) |
| for name, uploaded_file in uploaded_files: |
| if isinstance(uploaded_file, cgi.FieldStorage): |
| filename = to_bytes(uploaded_file.filename) |
| value = to_bytes(uploaded_file.value, 'ascii') |
| content_type = to_bytes(uploaded_file.type, 'ascii') |
| else: |
| filename = value = content_type = b'' |
| file_parts.append(b""" |
| <p>You selected '""" + filename + b"""'</p> |
| <p>with contents: '""" + value + b"""'</p> |
| <p>with content type: '""" + content_type + b"""'</p> |
| """) |
| return b''.join(file_parts) |
| |
| |
| class UploadBinaryApp(SingleUploadFileApp): |
| |
| def get_files_page(self, req): |
| uploaded_files = [(k, v) for k, v in req.POST.items() if 'file' in k] |
| data = uploaded_files[0][1].value |
| if PY3: |
| data = struct.unpack(b'255h', data[:510]) |
| else: |
| data = struct.unpack(str('255h'), data) |
| return b','.join([to_bytes(str(i)) for i in data]) |
| |
| |
| class MultipleUploadFileApp(SingleUploadFileApp): |
| body = b""" |
| <html> |
| <head><title>form page</title></head> |
| <body> |
| <form method="POST" id="file_upload_form" |
| enctype="multipart/form-data"> |
| <input name="file-field-1" type="file" /> |
| <input name="file-field-2" type="file" /> |
| <input name="button" type="submit" value="single"> |
| </form> |
| </body> |
| </html> |
| """ |
| |
| |
| class TestFileUpload(unittest.TestCase): |
| |
| def assertFile(self, name, contents, display, content_type=None): |
| if isinstance(name, six.binary_type): |
| text_name = name.decode('ascii') |
| else: |
| text_name = name |
| self.assertIn("<p>You selected '" + text_name + "'</p>", |
| display, display) |
| if isinstance(contents, six.binary_type): |
| text_contents = contents.decode('ascii') |
| else: |
| text_contents = contents |
| self.assertIn("<p>with contents: '" + text_contents + "'</p>", |
| display, display) |
| if content_type: |
| self.assertIn("<p>with content type: '" + content_type + "'</p>", |
| display, display) |
| |
| def test_no_uploads_error(self): |
| app = webtest.TestApp(SingleUploadFileApp()) |
| app.get('/').forms["file_upload_form"].upload_fields() |
| |
| def test_upload_without_file(self): |
| app = webtest.TestApp(SingleUploadFileApp()) |
| upload_form = app.get('/').forms["file_upload_form"] |
| upload_form.submit() |
| |
| def test_file_upload_with_filename_only(self): |
| uploaded_file_name = os.path.join(os.path.dirname(__file__), |
| "__init__.py") |
| uploaded_file_contents = open(uploaded_file_name).read() |
| if PY3: |
| uploaded_file_contents = to_bytes(uploaded_file_contents) |
| |
| app = webtest.TestApp(SingleUploadFileApp()) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| self.assertEqual(res.charset, 'utf-8') |
| |
| single_form = res.forms["file_upload_form"] |
| single_form.set("file-field", (uploaded_file_name,)) |
| display = single_form.submit("button") |
| self.assertFile(uploaded_file_name, uploaded_file_contents, display) |
| |
| def test_file_upload_with_filename_and_contents(self): |
| uploaded_file_name = os.path.join(os.path.dirname(__file__), |
| "__init__.py") |
| uploaded_file_contents = open(uploaded_file_name).read() |
| if PY3: |
| uploaded_file_contents = to_bytes(uploaded_file_contents) |
| |
| app = webtest.TestApp(SingleUploadFileApp()) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["file_upload_form"] |
| single_form.set("file-field", |
| (uploaded_file_name, uploaded_file_contents)) |
| display = single_form.submit("button") |
| self.assertFile(uploaded_file_name, uploaded_file_contents, display) |
| |
| def test_file_upload_with_content_type(self): |
| uploaded_file_name = os.path.join(os.path.dirname(__file__), |
| "__init__.py") |
| with open(uploaded_file_name, 'rb') as f: |
| uploaded_file_contents = f.read() |
| app = webtest.TestApp(SingleUploadFileApp()) |
| res = app.get('/') |
| single_form = res.forms["file_upload_form"] |
| single_form["file-field"].value = Upload(uploaded_file_name, |
| uploaded_file_contents, |
| 'text/x-custom-type') |
| display = single_form.submit("button") |
| self.assertFile(uploaded_file_name, uploaded_file_contents, display, |
| content_type='text/x-custom-type') |
| |
| def test_file_upload_binary(self): |
| binary_data = struct.pack(str('255h'), *range(0, 255)) |
| app = webtest.TestApp(UploadBinaryApp()) |
| res = app.get('/') |
| single_form = res.forms["file_upload_form"] |
| single_form.set("file-field", ('my_file.dat', binary_data)) |
| display = single_form.submit("button") |
| self.assertIn(','.join([str(n) for n in range(0, 255)]), display) |
| |
| def test_multiple_file_uploads_with_filename_and_contents(self): |
| uploaded_file1_name = os.path.join(os.path.dirname(__file__), |
| "__init__.py") |
| uploaded_file1_contents = open(uploaded_file1_name).read() |
| if PY3: |
| uploaded_file1_contents = to_bytes(uploaded_file1_contents) |
| uploaded_file2_name = __file__ |
| uploaded_file2_name = os.path.join(os.path.dirname(__file__), 'html', |
| "404.html") |
| uploaded_file2_contents = open(uploaded_file2_name).read() |
| if PY3: |
| uploaded_file2_contents = to_bytes(uploaded_file2_contents) |
| |
| app = webtest.TestApp(MultipleUploadFileApp()) |
| res = app.get('/') |
| self.assertEqual(res.status_int, 200) |
| self.assertEqual(res.headers['content-type'], |
| 'text/html; charset=utf-8') |
| self.assertEqual(res.content_type, 'text/html') |
| |
| single_form = res.forms["file_upload_form"] |
| single_form.set("file-field-1", |
| (uploaded_file1_name, uploaded_file1_contents)) |
| single_form.set("file-field-2", |
| (uploaded_file2_name, uploaded_file2_contents)) |
| display = single_form.submit("button") |
| self.assertFile(uploaded_file1_name, uploaded_file1_contents, display) |
| self.assertFile(uploaded_file1_name, uploaded_file1_contents, display) |
| |
| def test_post_int(self): |
| binary_data = struct.pack(str('255h'), *range(0, 255)) |
| app = webtest.TestApp(SingleUploadFileApp()) |
| res = app.get('/') |
| single_form = res.forms["file_upload_form"] |
| single_form.set("file-field", ('my_file.dat', binary_data)) |
| single_form.set("int-field", 100) |
| # just check it does not raise |
| single_form.submit("button") |
| |
| def test_invalid_types(self): |
| binary_data = struct.pack(str('255h'), *range(0, 255)) |
| app = webtest.TestApp(SingleUploadFileApp()) |
| res = app.get('/') |
| single_form = res.forms["file_upload_form"] |
| single_form.set("file-field", ('my_file.dat', binary_data)) |
| single_form.set("int-field", SingleUploadFileApp()) |
| self.assertRaises(ValueError, single_form.submit, "button") |
| |
| def test_upload_invalid_content(self): |
| app = webtest.TestApp(SingleUploadFileApp()) |
| res = app.get('/') |
| single_form = res.forms["file_upload_form"] |
| single_form.set("file-field", ('my_file.dat', 1)) |
| try: |
| single_form.submit("button") |
| except ValueError: |
| e = sys.exc_info()[1] |
| self.assertEquals( |
| six.text_type(e), |
| u('File content must be %s not %s' % (binary_type, int)) |
| ) |
| |
| def test_invalid_uploadfiles(self): |
| app = webtest.TestApp(SingleUploadFileApp()) |
| self.assertRaises(ValueError, app.post, '/', upload_files=[()]) |
| self.assertRaises( |
| ValueError, |
| app.post, '/', |
| upload_files=[('name', 'filename', 'content', 'extra')] |
| ) |
| |
| def test_goto_upload_files(self): |
| app = webtest.TestApp(SingleUploadFileApp()) |
| resp = app.get('/') |
| resp = resp.goto( |
| '/', |
| method='post', |
| upload_files=[('file', 'filename', b'content')] |
| ) |
| resp.mustcontain("<p>You selected 'filename'</p>", |
| "<p>with contents: 'content'</p>") |
| |
| def test_post_upload_files(self): |
| app = webtest.TestApp(SingleUploadFileApp()) |
| resp = app.post( |
| '/', |
| upload_files=[('file', 'filename', b'content')] |
| ) |
| resp.mustcontain("<p>You selected 'filename'</p>", |
| "<p>with contents: 'content'</p>") |
| |
| def test_post_upload_empty_files(self): |
| app = webtest.TestApp(SingleUploadFileApp()) |
| resp = app.post( |
| '/', |
| upload_files=[('file', 'filename', b'')] |
| ) |
| resp.mustcontain("<p>You selected 'filename'</p>", |
| "<p>with contents: ''</p>") |
| resp = app.get('/') |
| form = resp.form |
| form['file-field'] = Upload('filename', b'', 'text/plain') |
| resp = form.submit() |
| resp.mustcontain("<p>You selected 'filename'</p>", |
| "<p>with contents: ''</p>") |