summaryrefslogtreecommitdiff
path: root/tests/file_storage
diff options
context:
space:
mode:
authormiigotu <miigotu@gmail.com>2020-03-31 12:12:39 +0200
committerCarlton Gibson <carlton@noumenal.es>2020-04-08 11:26:17 +0200
commit210657b791fec359a9109b69e566018253edfad0 (patch)
treed9bb41fcd6aae39772ac373697834b24f5193524 /tests/file_storage
parentdb6933a032c850153a688b6c977691b37ca02745 (diff)
downloaddjango-210657b791fec359a9109b69e566018253edfad0.tar.gz
Fixed #28184 -- Allowed using a callable for FileField and ImageField storage.
Diffstat (limited to 'tests/file_storage')
-rw-r--r--tests/file_storage/models.py12
-rw-r--r--tests/file_storage/tests.py45
2 files changed, 56 insertions, 1 deletions
diff --git a/tests/file_storage/models.py b/tests/file_storage/models.py
index 8085a8bb1a..9097f465dd 100644
--- a/tests/file_storage/models.py
+++ b/tests/file_storage/models.py
@@ -23,6 +23,16 @@ temp_storage_location = tempfile.mkdtemp()
temp_storage = FileSystemStorage(location=temp_storage_location)
+def callable_storage():
+ return temp_storage
+
+
+class CallableStorage(FileSystemStorage):
+ def __call__(self):
+ # no-op implementation.
+ return self
+
+
class Storage(models.Model):
def custom_upload_to(self, filename):
return 'foo'
@@ -44,6 +54,8 @@ class Storage(models.Model):
storage=CustomValidNameStorage(location=temp_storage_location),
upload_to=random_upload_to,
)
+ storage_callable = models.FileField(storage=callable_storage, upload_to='storage_callable')
+ storage_callable_class = models.FileField(storage=CallableStorage, upload_to='storage_callable_class')
default = models.FileField(storage=temp_storage, upload_to='tests', default='tests/default.txt')
empty = models.FileField(storage=temp_storage)
limited_length = models.FileField(storage=temp_storage, upload_to='tests', max_length=20)
diff --git a/tests/file_storage/tests.py b/tests/file_storage/tests.py
index 9b41f5250d..a1d2bd372c 100644
--- a/tests/file_storage/tests.py
+++ b/tests/file_storage/tests.py
@@ -13,10 +13,13 @@ from urllib.request import urlopen
from django.core.cache import cache
from django.core.exceptions import SuspiciousFileOperation
from django.core.files.base import ContentFile, File
-from django.core.files.storage import FileSystemStorage, get_storage_class
+from django.core.files.storage import (
+ FileSystemStorage, Storage as BaseStorage, get_storage_class,
+)
from django.core.files.uploadedfile import (
InMemoryUploadedFile, SimpleUploadedFile, TemporaryUploadedFile,
)
+from django.db.models import FileField
from django.db.models.fields.files import FileDescriptor
from django.test import (
LiveServerTestCase, SimpleTestCase, TestCase, override_settings,
@@ -866,6 +869,46 @@ class FileFieldStorageTests(TestCase):
self.assertEqual(f.read(), b'content')
+class FieldCallableFileStorageTests(SimpleTestCase):
+ def setUp(self):
+ self.temp_storage_location = tempfile.mkdtemp(suffix='filefield_callable_storage')
+
+ def tearDown(self):
+ shutil.rmtree(self.temp_storage_location)
+
+ def test_callable_base_class_error_raises(self):
+ class NotStorage:
+ pass
+ msg = 'FileField.storage must be a subclass/instance of django.core.files.storage.Storage'
+ for invalid_type in (NotStorage, str, list, set, tuple):
+ with self.subTest(invalid_type=invalid_type):
+ with self.assertRaisesMessage(TypeError, msg):
+ FileField(storage=invalid_type)
+
+ def test_callable_function_storage_file_field(self):
+ storage = FileSystemStorage(location=self.temp_storage_location)
+
+ def get_storage():
+ return storage
+
+ obj = FileField(storage=get_storage)
+ self.assertEqual(obj.storage, storage)
+ self.assertEqual(obj.storage.location, storage.location)
+
+ def test_callable_class_storage_file_field(self):
+ class GetStorage(FileSystemStorage):
+ pass
+
+ obj = FileField(storage=GetStorage)
+ self.assertIsInstance(obj.storage, BaseStorage)
+
+ def test_callable_storage_file_field_in_model(self):
+ obj = Storage()
+ self.assertEqual(obj.storage_callable.storage, temp_storage)
+ self.assertEqual(obj.storage_callable.storage.location, temp_storage_location)
+ self.assertIsInstance(obj.storage_callable_class.storage, BaseStorage)
+
+
# Tests for a race condition on file saving (#4948).
# This is written in such a way that it'll always pass on platforms
# without threading.