diff options
author | Gael Pasgrimaud <gael@gawel.org> | 2022-01-19 08:55:34 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-19 08:55:34 +0100 |
commit | b0426fc2952ba45de75cbd37db350281dce101df (patch) | |
tree | 821d6e8d5cf77a4505042a03fb1fb4905dd36b28 | |
parent | 2719819e5ac26bdc0cf39879ca4d3879ae9eb0c9 (diff) | |
parent | d1dbc25f53a031d03112cb1e44f4a060cf3665cd (diff) | |
download | webtest-master.tar.gz |
Merge pull request #242 from azmeuk/issue-240-multiple-file-inputmaster
Support for multiple file input
-rw-r--r-- | CHANGELOG.rst | 2 | ||||
-rw-r--r-- | docs/forms.rst | 11 | ||||
-rw-r--r-- | tests/test_forms.py | 52 | ||||
-rw-r--r-- | webtest/app.py | 5 |
4 files changed, 64 insertions, 6 deletions
diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 4325a0e..c2e06f8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -4,7 +4,7 @@ News 3.0.1 (unreleased) ------------------ -- Nothing changed yet. +- Multiple file input support. 3.0.0 (2021-08-19) diff --git a/docs/forms.rst b/docs/forms.rst index 6e5b7c9..8f4ff4c 100644 --- a/docs/forms.rst +++ b/docs/forms.rst @@ -197,6 +197,17 @@ You can deal with file upload by using the Upload class: >>> form['file'] = Upload('README.rst', b'data') >>> form['file'] = Upload('README.rst', b'data', 'text/x-rst') +If the file field has a ``multiple`` parameter, you can pass a +list of :class:`~webtest.forms.Upload`: + +.. code-block:: python + + >>> from webtest import Upload + >>> form['files'] = [ + ... Upload('README.rst'), + ... Upload('LICENSE.rst'), + ... ] + Submit a form -------------- diff --git a/tests/test_forms.py b/tests/test_forms.py index d50c034..f8bd39d 100644 --- a/tests/test_forms.py +++ b/tests/test_forms.py @@ -829,7 +829,6 @@ class SingleUploadFileApp: 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) @@ -854,7 +853,7 @@ class UploadBinaryApp(SingleUploadFileApp): return b','.join([to_bytes(str(i)) for i in data]) -class MultipleUploadFileApp(SingleUploadFileApp): +class SeveralSingleFileApp(SingleUploadFileApp): body = b""" <html> <head><title>form page</title></head> @@ -870,6 +869,23 @@ class MultipleUploadFileApp(SingleUploadFileApp): """ +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="files-field" type="file" value="some/path/file.txt" multiple="" /> + <input name="int-field" type="text" value="" /> + <input name="button" type="submit" value="single"> + </form> + </body> +</html> +""" + + class TestFileUpload(unittest.TestCase): def assertFile(self, name, contents, display, content_type=None): @@ -960,7 +976,7 @@ class TestFileUpload(unittest.TestCase): 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): + def test_several_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() @@ -971,7 +987,7 @@ class TestFileUpload(unittest.TestCase): uploaded_file2_contents = open(uploaded_file2_name).read() uploaded_file2_contents = to_bytes(uploaded_file2_contents) - app = webtest.TestApp(MultipleUploadFileApp()) + app = webtest.TestApp(SeveralSingleFileApp()) res = app.get('/') self.assertEqual(res.status_int, 200) self.assertEqual(res.headers['content-type'], @@ -1063,3 +1079,31 @@ class TestFileUpload(unittest.TestCase): resp = form.submit() resp.mustcontain("<p>You selected 'filename'</p>", "<p>with contents: ''</p>") + + def test_multiple_file(self): + uploaded_file_name_1 = os.path.join(os.path.dirname(__file__), + "__init__.py") + uploaded_file_contents_1 = open(uploaded_file_name_1).read() + uploaded_file_contents_1 = to_bytes(uploaded_file_contents_1) + + uploaded_file_name_2 = os.path.join(os.path.dirname(__file__), + os.path.basename(__file__)) + uploaded_file_contents_2 = open(uploaded_file_name_1).read() + uploaded_file_contents_2 = to_bytes(uploaded_file_contents_2) + + 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("files-field", [ + (uploaded_file_name_1, uploaded_file_contents_1), + (uploaded_file_name_2, uploaded_file_contents_2), + ]) + + display = single_form.submit("button") + self.assertFile(uploaded_file_name_1, uploaded_file_contents_1, display) + self.assertFile(uploaded_file_name_2, uploaded_file_contents_2, display) diff --git a/webtest/app.py b/webtest/app.py index 4ea19e9..9e3155e 100644 --- a/webtest/app.py +++ b/webtest/app.py @@ -500,7 +500,10 @@ class TestApp: except: # pragma: no cover raise # field name are always ascii if isinstance(value, forms.File): - if value.value: + if "multiple" in value.attrs: + for file in value.value: + _append_file([key] + list(file)) + elif value.value: _append_file([key] + list(value.value)) else: # If no file was uploaded simulate an empty file with no |