diff --git a/project/tests/test_multipart_forms.py b/project/tests/test_multipart_forms.py index f4e9a8b6..9f217b53 100644 --- a/project/tests/test_multipart_forms.py +++ b/project/tests/test_multipart_forms.py @@ -8,14 +8,44 @@ class TestMultipartForms(TestCase): + def setUp(self): + self.mock_request = Mock() + self.mock_request.method = "POST" + self.mock_request.GET = {} + self.mock_request.path = reverse("silk:requests") + self.mock_request.headers = {"content-type": multipart_form} + self.mock_request.FILES = {"file": "file.txt", "file2": "file2.pdf", "file3": "file3.jpg"} + def test_no_max_request(self): mock_request = Mock() - mock_request.headers = {'content-type': multipart_form} + mock_request.headers = {"content-type": multipart_form} mock_request.GET = {} - mock_request.path = reverse('silk:requests') - mock_request.method = 'post' + mock_request.path = reverse("silk:requests") + mock_request.method = "post" mock_request.body = Mock() request_model = RequestModelFactory(mock_request).construct_request_model() self.assertFalse(request_model.body) - self.assertEqual(b"Raw body not available for multipart_form data, Silk is not showing file uploads.", request_model.raw_body) + self.assertEqual( + b"Raw body not available for multipart_form data, Silk is not showing file uploads.", + request_model.raw_body, + ) mock_request.body.assert_not_called() + + def test_multipart_form_request_creation_raises_no_exception(self): + """ + Test that a request with multipart form data is created correctly without raising excetions + """ + request_model = RequestModelFactory(self.mock_request).construct_request_model() + self.assertTrue(request_model.body) + self.assertEqual( + { + 'form_data': {}, + 'files': { + 'file': 'file.txt', + 'file2': 'file2.pdf', + 'file3': 'file3.jpg' + } + }, + request_model.body + ) + self.assertIsNone(request_model.raw_body) diff --git a/silk/model_factory.py b/silk/model_factory.py index a802beb4..5d33d423 100644 --- a/silk/model_factory.py +++ b/silk/model_factory.py @@ -226,6 +226,16 @@ def construct_request_model(self): query_params = self.query_params() path = self.request.path view_name = self.view_name() + content_type = self.request.content_type + + if content_type.startswith('multipart/form-data'): + body = { + 'form_data': self.request.POST.dict(), + 'files': {f: self.request.FILES[f].name for f in self.request.FILES} + } + raw_body = None # Raw body is not available for multipart/form-data + else: + body, raw_body = self.body() request_model = models.Request.objects.create( path=path, @@ -234,12 +244,15 @@ def construct_request_model(self): query_params=query_params, view_name=view_name, body=body) + # Text fields are encoded as UTF-8 in Django and hence will try to coerce # anything to we pass to UTF-8. Some stuff like binary will fail. - try: - request_model.raw_body = raw_body - except UnicodeDecodeError: - Logger.debug('NYI: Binary request bodies') # TODO + if raw_body is not None: + try: + request_model.raw_body = raw_body + except UnicodeDecodeError: + Logger.debug('NYI: Binary request bodies') # TODO + Logger.debug('Created new request model with pk %s' % request_model.pk) return request_model