From a6beeefd6a25ede0ce8cb26d408f8e00a195a24d Mon Sep 17 00:00:00 2001 From: Jeff Bradberry Date: Wed, 2 Mar 2016 14:06:56 -0500 Subject: [PATCH] Added support for the file mode to MediaStorage.read(). --- import_export/tmp_storages.py | 6 ++-- tests/core/exports/books-mac.csv | 1 + tests/core/tests/admin_integration_tests.py | 34 +++++++++++++++++++++ tests/core/tests/base_formats_tests.py | 10 ++++++ tests/core/tests/tmp_storages_tests.py | 15 +++++++++ 5 files changed, 63 insertions(+), 3 deletions(-) create mode 100644 tests/core/exports/books-mac.csv diff --git a/import_export/tmp_storages.py b/import_export/tmp_storages.py index 80f715717..dea5b2e28 100644 --- a/import_export/tmp_storages.py +++ b/import_export/tmp_storages.py @@ -79,9 +79,9 @@ def save(self, data, mode=None): self.name = uuid4().hex default_storage.save(self.get_full_path(), ContentFile(data)) - def read(self, read_mode='r'): - with default_storage.open(self.get_full_path()) as file: - return file.read() + def read(self, read_mode='rb'): + with default_storage.open(self.get_full_path(), mode=read_mode) as f: + return f.read() def remove(self): default_storage.delete(self.get_full_path()) diff --git a/tests/core/exports/books-mac.csv b/tests/core/exports/books-mac.csv new file mode 100644 index 000000000..8ee412104 --- /dev/null +++ b/tests/core/exports/books-mac.csv @@ -0,0 +1 @@ +id,name,author_email 1,Some book,test@example.com \ No newline at end of file diff --git a/tests/core/tests/admin_integration_tests.py b/tests/core/tests/admin_integration_tests.py index 4b414d2fa..5f2307480 100644 --- a/tests/core/tests/admin_integration_tests.py +++ b/tests/core/tests/admin_integration_tests.py @@ -64,6 +64,40 @@ def test_import(self): self.assertEqual(response.status_code, 200) self.assertContains(response, _('Import finished')) + @override_settings(TEMPLATE_STRING_IF_INVALID='INVALID_VARIABLE') + def test_import_mac(self): + # GET the import form + response = self.client.get('/admin/core/book/import/') + self.assertEqual(response.status_code, 200) + self.assertTemplateUsed(response, 'admin/import_export/import.html') + self.assertContains(response, 'form action=""') + + # POST the import form + input_format = '0' + filename = os.path.join( + os.path.dirname(__file__), + os.path.pardir, + 'exports', + 'books-mac.csv') + with open(filename, "rb") as f: + data = { + 'input_format': input_format, + 'import_file': f, + } + response = self.client.post('/admin/core/book/import/', data) + self.assertEqual(response.status_code, 200) + self.assertIn('result', response.context) + self.assertFalse(response.context['result'].has_errors()) + self.assertIn('confirm_form', response.context) + confirm_form = response.context['confirm_form'] + + data = confirm_form.initial + self.assertEqual(data['original_file_name'], 'books-mac.csv') + response = self.client.post('/admin/core/book/process_import/', data, + follow=True) + self.assertEqual(response.status_code, 200) + self.assertContains(response, _('Import finished')) + def test_export(self): response = self.client.get('/admin/core/book/export/') self.assertEqual(response.status_code, 200) diff --git a/tests/core/tests/base_formats_tests.py b/tests/core/tests/base_formats_tests.py index 56f6332de..d4b82004b 100644 --- a/tests/core/tests/base_formats_tests.py +++ b/tests/core/tests/base_formats_tests.py @@ -52,6 +52,16 @@ def test_import_dos(self): expected = 'id,name,author_email\n1,Some book,test@example.com\n' self.assertEqual(in_stream, expected) + def test_import_mac(self): + filename = os.path.join( + os.path.dirname(__file__), + os.path.pardir, + 'exports', + 'books-mac.csv') + in_stream = open(filename, self.format.get_read_mode()).read() + expected = 'id,name,author_email\n1,Some book,test@example.com\n' + self.assertEqual(in_stream, expected) + def test_import_unicode(self): # importing csv UnicodeEncodeError 347 filename = os.path.join( diff --git a/tests/core/tests/tmp_storages_tests.py b/tests/core/tests/tmp_storages_tests.py index 44a8fe5e4..fb5f0d46b 100644 --- a/tests/core/tests/tmp_storages_tests.py +++ b/tests/core/tests/tmp_storages_tests.py @@ -4,6 +4,8 @@ from django.test import TestCase from django.core.cache import cache from django.core.files.storage import default_storage +from django.utils import six + from import_export.tmp_storages import ( CacheStorage, MediaStorage, @@ -56,3 +58,16 @@ def test_media_storage(self): self.assertTrue(default_storage.exists(tmp_storage.get_full_path())) tmp_storage.remove() self.assertFalse(default_storage.exists(tmp_storage.get_full_path())) + + def test_media_storage_read_mode(self): + # issue 416 - MediaStorage does not respect the read_mode parameter. + test_string = self.test_string.replace(b'\n', b'\r') + + tmp_storage = MediaStorage() + tmp_storage.save(test_string) + name = tmp_storage.name + + tmp_storage = MediaStorage(name=name) + read_mode = 'r' if six.PY3 else 'rbU' + self.assertEqual(self.test_string.decode('utf-8'), + tmp_storage.read(read_mode=read_mode))