123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990 |
- import os
- from django.core.files.base import ContentFile
- from django.core.files.storage import Storage
- from django.db.models import FileField
- from django.test import SimpleTestCase
- class AWSS3Storage(Storage):
- """
- Simulate an AWS S3 storage which uses Unix-like paths and allows any
- characters in file names but where there aren't actual folders but just
- keys.
- """
- prefix = 'mys3folder/'
- def _save(self, name, content):
- """
- This method is important to test that Storage.save() doesn't replace
- '\' with '/' (rather FileSystemStorage.save() does).
- """
- return name
- def get_valid_name(self, name):
- return name
- def get_available_name(self, name, max_length=None):
- return name
- def generate_filename(self, filename):
- """
- This is the method that's important to override when using S3 so that
- os.path() isn't called, which would break S3 keys.
- """
- return self.prefix + self.get_valid_name(filename)
- class GenerateFilenameStorageTests(SimpleTestCase):
- def test_filefield_generate_filename(self):
- f = FileField(upload_to='some/folder/')
- self.assertEqual(
- f.generate_filename(None, 'test with space.txt'),
- os.path.normpath('some/folder/test_with_space.txt')
- )
- def test_filefield_generate_filename_with_upload_to(self):
- def upload_to(instance, filename):
- return 'some/folder/' + filename
- f = FileField(upload_to=upload_to)
- self.assertEqual(
- f.generate_filename(None, 'test with space.txt'),
- os.path.normpath('some/folder/test_with_space.txt')
- )
- def test_filefield_awss3_storage(self):
- """
- Simulate a FileField with an S3 storage which uses keys rather than
- folders and names. FileField and Storage shouldn't have any os.path()
- calls that break the key.
- """
- storage = AWSS3Storage()
- folder = 'not/a/folder/'
- f = FileField(upload_to=folder, storage=storage)
- key = 'my-file-key\\with odd characters'
- data = ContentFile('test')
- expected_key = AWSS3Storage.prefix + folder + key
- # Simulate call to f.save()
- result_key = f.generate_filename(None, key)
- self.assertEqual(result_key, expected_key)
- result_key = storage.save(result_key, data)
- self.assertEqual(result_key, expected_key)
- # Repeat test with a callable.
- def upload_to(instance, filename):
- # Return a non-normalized path on purpose.
- return folder + filename
- f = FileField(upload_to=upload_to, storage=storage)
- # Simulate call to f.save()
- result_key = f.generate_filename(None, key)
- self.assertEqual(result_key, expected_key)
- result_key = storage.save(result_key, data)
- self.assertEqual(result_key, expected_key)
|