diff --git a/extensions/tests/test_api.py b/extensions/tests/test_api.py index 058f864c..3d4a9ce2 100644 --- a/extensions/tests/test_api.py +++ b/extensions/tests/test_api.py @@ -343,6 +343,33 @@ class VersionUploadAPITest(APITestCase): self.assertEqual(response.status_code, status.HTTP_201_CREATED) self.assertEqual(Version.objects.filter(extension=self.extension).count(), 2) + def test_version_upload_multiline(self): + self.assertEqual(Version.objects.filter(extension=self.extension).count(), 1) + + # Make sure the \n is escaped, to simulate how CURL passes strings. + release_notes = 'First line\\nSecond line' + + with open(self.file_path, 'rb') as version_file: + response = self.client.post( + self._get_upload_url(self.extension.extension_id), + { + 'version_file': version_file, + 'release_notes': release_notes, + }, + format='multipart', + HTTP_AUTHORIZATION=f'Bearer {self.token_key}', + ) + + self.assertEqual(response.status_code, status.HTTP_201_CREATED) + self.assertEqual(Version.objects.filter(extension=self.extension).count(), 2) + self.extension.refresh_from_db() + + version = self.extension.latest_version + self.assertEqual(version.version, "1.0.8") + + self.assertNotIn('\n', release_notes) + self.assertIn('\n', version.release_notes) + def test_date_last_access(self): self.assertIsNone(self.token.date_last_access) with open(self.file_path, 'rb') as version_file: diff --git a/extensions/views/api.py b/extensions/views/api.py index 4380b87a..fe61dc73 100644 --- a/extensions/views/api.py +++ b/extensions/views/api.py @@ -172,6 +172,12 @@ class ExtensionVersionSerializer(serializers.Serializer): version_file = serializers.FileField() release_notes = serializers.CharField(max_length=1024, required=False) + def validate_release_notes(self, value): + r"""Make sure \n and \r are valid after sanitation.""" + if value is None: + return + return value.replace('\\n', '\n').replace('\\r', '\r') + class UploadExtensionVersionView(APIView): permission_classes = [IsAuthenticated]