diff options
| author | sebpiq | 2011-03-11 15:05:35 +0200 |
|---|---|---|
| committer | sebpiq | 2011-03-11 15:05:35 +0200 |
| commit | ee74aec27cdc8ca9934f93c828ffbdc7da3c426c (patch) | |
| tree | aa0538d0fd302977d602484ef4f0fb53d606e6b2 | |
| parent | d6c13a9e5caee653f7a8f3150c00aa574aa15700 (diff) | |
| download | django-rest-framework-ee74aec27cdc8ca9934f93c828ffbdc7da3c426c.tar.bz2 | |
debug + tests for MultipartParser
| -rw-r--r-- | djangorestframework/parsers.py | 9 | ||||
| -rw-r--r-- | djangorestframework/tests/parsers.py | 57 |
2 files changed, 59 insertions, 7 deletions
diff --git a/djangorestframework/parsers.py b/djangorestframework/parsers.py index d324f687..3bd020ad 100644 --- a/djangorestframework/parsers.py +++ b/djangorestframework/parsers.py @@ -84,7 +84,6 @@ class DataFlatener(object): def flatten_data(self, data): """Given a data dictionary {<key>: <value_list>}, returns a flattened dictionary with information provided by the method "is_a_list".""" - data = data.copy() flatdata = dict() for key, val_list in data.items(): if self.is_a_list(key, val_list): @@ -108,10 +107,8 @@ class FormParser(BaseParser, DataFlatener): Return a dict containing a single value for each non-reserved parameter. In order to handle select multiple (and having possibly more than a single value for each parameter), - you can customize the output by subclassing the method 'is_a_list'. + you can customize the output by subclassing the method 'is_a_list'.""" - """ - # TODO: writing tests for PUT files + normal data media_type = 'application/x-www-form-urlencoded' """The value of the parameter when the select multiple is empty. @@ -159,8 +156,8 @@ class MultipartParser(BaseParser, DataFlatener): data, files = django_mpp.parse() # Flatening data, files and combining them - data = self.flatten_data(data) - files = self.flatten_data(files) + data = self.flatten_data(dict(data.iterlists())) + files = self.flatten_data(dict(files.iterlists())) data.update(files) # Strip any parameters that we are treating as reserved diff --git a/djangorestframework/tests/parsers.py b/djangorestframework/tests/parsers.py index a2831b63..d4cd1e87 100644 --- a/djangorestframework/tests/parsers.py +++ b/djangorestframework/tests/parsers.py @@ -8,6 +8,9 @@ >>> some_resource = Resource() >>> trash = some_resource.dispatch(req)# Some variables are set only when calling dispatch +FormParser +============ + Data flatening ---------------- @@ -35,6 +38,8 @@ This new parser only flattens the lists of parameters that contain a single valu >>> MyFormParser(some_resource).parse(inpt) == {'key1': 'bla1', 'key2': ['blo1', 'blo2']} True +.. note:: The same functionality is available for :class:`parsers.MultipartParser`. + Submitting an empty list -------------------------- @@ -68,5 +73,55 @@ Oh ... but wait a second, the parameter ``key2`` isn't even supposed to be a lis >>> MyFormParser(some_resource).parse(inpt) == {'key1': 'blo1', 'key2': []} True -Better like that. Note also that you can configure something else than ``_empty`` for the empty value by setting :class:`parsers.FormParser.EMPTY_VALUE`. +Better like that. Note that you can configure something else than ``_empty`` for the empty value by setting :attr:`parsers.FormParser.EMPTY_VALUE`. """ +import httplib, mimetypes +from tempfile import TemporaryFile +from django.test import TestCase +from djangorestframework.compat import RequestFactory +from djangorestframework.parsers import MultipartParser +from djangorestframework.resource import Resource + +def encode_multipart_formdata(fields, files): + """For testing multipart parser. + fields is a sequence of (name, value) elements for regular form fields. + files is a sequence of (name, filename, value) elements for data to be uploaded as files + Return (content_type, body).""" + BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$' + CRLF = '\r\n' + L = [] + for (key, value) in fields: + L.append('--' + BOUNDARY) + L.append('Content-Disposition: form-data; name="%s"' % key) + L.append('') + L.append(value) + for (key, filename, value) in files: + L.append('--' + BOUNDARY) + L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, filename)) + L.append('Content-Type: %s' % get_content_type(filename)) + L.append('') + L.append(value) + L.append('--' + BOUNDARY + '--') + L.append('') + body = CRLF.join(L) + content_type = 'multipart/form-data; boundary=%s' % BOUNDARY + return content_type, body + +def get_content_type(filename): + return mimetypes.guess_type(filename)[0] or 'application/octet-stream' + +class TestMultipartParser(TestCase): + def setUp(self): + self.req = RequestFactory() + self.content_type, self.body = encode_multipart_formdata([('key1', 'val1'), ('key1', 'val2')], + [('file1', 'pic.jpg', 'blablabla'), ('file1', 't.txt', 'blobloblo')]) + + def test_multipartparser(self): + """Ensure that MultipartParser can parse multipart/form-data that contains a mix of several files and parameters.""" + post_req = RequestFactory().post('/', self.body, content_type=self.content_type) + some_resource = Resource() + some_resource.dispatch(post_req) + parsed = MultipartParser(some_resource).parse(self.body) + self.assertEqual(parsed['key1'], 'val1') + self.assertEqual(parsed['file1'].read(), 'blablabla') + |
