030bbc98fd
Шаблоны/ручное создание, access_projects, сид «Открытие аптеки». Плюс SILO/S3 для Django media. Co-authored-by: Cursor <cursoragent@cursor.com>
86 lines
3.2 KiB
Python
86 lines
3.2 KiB
Python
"""S3/SILO media storage wiring (no live SILO required)."""
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from django.core.files.base import ContentFile
|
|
from django.core.files.storage import FileSystemStorage
|
|
from django.core.management import call_command
|
|
from django.core.management.base import CommandError
|
|
from django.test import SimpleTestCase, TestCase, override_settings
|
|
|
|
|
|
class S3MediaSettingsTests(SimpleTestCase):
|
|
def test_use_s3_media_false_without_endpoint(self):
|
|
from django.conf import settings
|
|
|
|
self.assertFalse(settings.USE_S3_MEDIA)
|
|
|
|
@override_settings(
|
|
USE_S3_MEDIA=True,
|
|
STORAGES={
|
|
'default': {
|
|
'BACKEND': 'django.core.files.storage.InMemoryStorage',
|
|
},
|
|
'staticfiles': {
|
|
'BACKEND': 'django.contrib.staticfiles.storage.StaticFilesStorage',
|
|
},
|
|
},
|
|
)
|
|
def test_default_storage_uses_configured_backend_when_s3_flag_on(self):
|
|
from django.core.files.storage import default_storage
|
|
|
|
name = default_storage.save('s3-test/hello.txt', ContentFile(b'hi'))
|
|
self.assertTrue(default_storage.exists(name))
|
|
self.assertEqual(default_storage.open(name).read(), b'hi')
|
|
|
|
|
|
class SyncMediaToS3CommandTests(TestCase):
|
|
def test_requires_s3_config(self):
|
|
with self.assertRaises(CommandError) as ctx:
|
|
call_command('sync_media_to_s3')
|
|
self.assertIn('S3 media is not configured', str(ctx.exception))
|
|
|
|
@override_settings(USE_S3_MEDIA=True, MEDIA_ROOT='/tmp/acore-media-missing-xyz')
|
|
def test_missing_media_root(self):
|
|
with self.assertRaises(CommandError) as ctx:
|
|
call_command('sync_media_to_s3')
|
|
self.assertIn('MEDIA_ROOT does not exist', str(ctx.exception))
|
|
|
|
def test_dry_run_lists_files(self):
|
|
media = Path(self._media_dir())
|
|
(media / 'employees').mkdir(parents=True)
|
|
(media / 'employees' / 'a.jpg').write_bytes(b'\xff\xd8')
|
|
|
|
mock_storage = MagicMock(spec=FileSystemStorage)
|
|
mock_storage.exists.return_value = False
|
|
|
|
with override_settings(USE_S3_MEDIA=True, MEDIA_ROOT=str(media)), \
|
|
patch('core.management.commands.sync_media_to_s3.default_storage', mock_storage):
|
|
call_command('sync_media_to_s3', '--dry-run')
|
|
|
|
mock_storage.save.assert_not_called()
|
|
|
|
def test_upload_calls_storage_save(self):
|
|
media = Path(self._media_dir())
|
|
(media / 'x').mkdir(parents=True)
|
|
(media / 'x' / 'f.bin').write_bytes(b'abc')
|
|
|
|
mock_storage = MagicMock()
|
|
mock_storage.exists.return_value = False
|
|
mock_storage.save.side_effect = lambda name, content: name
|
|
|
|
with override_settings(USE_S3_MEDIA=True, MEDIA_ROOT=str(media)), \
|
|
patch('core.management.commands.sync_media_to_s3.default_storage', mock_storage):
|
|
call_command('sync_media_to_s3')
|
|
|
|
mock_storage.save.assert_called_once()
|
|
args, _kwargs = mock_storage.save.call_args
|
|
self.assertEqual(args[0], 'x/f.bin')
|
|
|
|
def _media_dir(self) -> str:
|
|
import tempfile
|
|
|
|
return tempfile.mkdtemp(prefix='acore-media-test-')
|