33from django .test import TestCase
44from django .conf import settings
55from storages .backends .s3boto3 import S3Boto3Storage
6-
7- from smart_storages .s3_backend import BaseSpecialS3Storage
6+ from smart_storages .s3_backend import BaseSpecialS3Storage # Assuming this is the module path
87
98# Ensure Django settings are configured for standalone test runs
9+ # Assuming 'smart_storages.tests.settings' exists and configures AWS_STORAGE_BUCKET_NAME, STORAGES, etc.
1010if not settings .configured :
1111 os .environ .setdefault ("DJANGO_SETTINGS_MODULE" , "smart_storages.tests.settings" )
1212
1313
14+ # --- Helper Storage Subclasses ---
15+
16+ class MissingKeyS3Storage (BaseSpecialS3Storage ):
17+ # Intentional: storage_key = None
18+ pass
19+
20+
1421class ImportExportS3Storage (BaseSpecialS3Storage ):
1522 storage_key = "import_export"
1623
@@ -19,35 +26,81 @@ class AnalyticsS3Storage(BaseSpecialS3Storage):
1926 storage_key = "analytics"
2027
2128
22- class DefaultsS3Storage (AnalyticsS3Storage ):
23- storage_key = "none"
24-
29+ # --- Test Suite ---
2530
2631class TestSpecialStorages (TestCase ):
32+
33+ # --- New Tests for Robustness ---
34+
35+ def test_missing_storage_key_raises_error (self ):
36+ """The base class must raise NotImplementedError if storage_key is not set."""
37+ with self .assertRaises (NotImplementedError ):
38+ MissingKeyS3Storage ()
39+
40+ def test_region_is_picked_up_from_storages_dict (self ):
41+ """The class should pick up the region name from the STORAGES dict."""
42+ storage = AnalyticsS3Storage ()
43+ # Assuming settings.STORAGES['analytics']['OPTIONS']['region_name'] is set to 'eu-west-1'
44+ self .assertEqual (storage .region_name , settings .STORAGES ["analytics" ]["OPTIONS" ]["region_name" ])
45+ self .assertEqual (storage .bucket_name , settings .STORAGES ["analytics" ]["OPTIONS" ]["bucket_name" ])
46+
47+ def test_region_falls_back_to_global_setting (self ):
48+ """If not in STORAGES, region should fallback to AWS_S3_REGION_NAME."""
49+ # For this test, we temporarily set the key to something not in STORAGES
50+ # and assume AWS_S3_REGION_NAME is globally set (e.g., 'us-east-1').
51+
52+ # We'll use ImportExportS3Storage, but temporarily clear its region option for the test
53+ temp_options = settings .STORAGES ["import_export" ]["OPTIONS" ].copy ()
54+ temp_options .pop ("region_name" , None )
55+ settings .STORAGES ["import_export" ]["OPTIONS" ] = temp_options
56+
57+ storage = ImportExportS3Storage ()
58+ self .assertEqual (storage .region_name , settings .AWS_S3_REGION_NAME )
59+
60+ # Restore settings to avoid side effects
61+ settings .STORAGES ["import_export" ]["OPTIONS" ]["region_name" ] = "us-east-1-specific"
62+
63+ # --- Modified/Existing Tests ---
64+
2765 def test_base_storage_uses_default_bucket (self ):
28- """Fallback to AWS_STORAGE_BUCKET_NAME if specific bucket setting is missing."""
29- storage = DefaultsS3Storage ()
66+ """Fallback to AWS_STORAGE_BUCKET_NAME if specific bucket is not in STORAGES."""
67+
68+ # To test the fallback properly, we use a key that we assume exists in STORAGES,
69+ # but does *not* define a 'bucket_name' option.
70+ class TempNoBucketStorage (BaseSpecialS3Storage ):
71+ storage_key = "default_fallback_test"
72+
73+ # Temporarily configure a non-existent storage key without a bucket_name
74+ settings .STORAGES ["default_fallback_test" ] = {"BACKEND" : "..." }
75+
76+ storage = TempNoBucketStorage ()
77+
3078 self .assertIsInstance (storage , S3Boto3Storage )
3179 self .assertEqual (storage .bucket_name , settings .AWS_STORAGE_BUCKET_NAME )
80+ # Verify defaults from settings are applied
3281 self .assertFalse (storage .querystring_auth )
3382 self .assertEqual (storage .default_acl , "private" )
3483 self .assertEqual (storage .object_parameters , {"CacheControl" : "max-age=3600" })
84+ # Clean up
85+ del settings .STORAGES ["default_fallback_test" ]
3586
3687 def test_custom_bucket_is_used (self ):
3788 """The class should pick up its bucket name from the STORAGES dict."""
3889 storage = ImportExportS3Storage ()
39- self .assertEqual (storage .bucket_name , "import_export" )
90+ self .assertEqual (storage .bucket_name , settings . STORAGES [ "import_export" ][ "OPTIONS" ][ "bucket_name" ] )
4091
4192 def test_multiple_subclasses_can_have_different_buckets (self ):
4293 """Each subclass can have its own bucket."""
4394 export_storage = ImportExportS3Storage ()
4495 analytics_storage = AnalyticsS3Storage ()
96+
4597 self .assertNotEqual (export_storage .bucket_name , analytics_storage .bucket_name )
4698 self .assertEqual (export_storage .bucket_name , settings .STORAGES ["import_export" ]["OPTIONS" ]["bucket_name" ])
4799 self .assertEqual (analytics_storage .bucket_name , settings .STORAGES ["analytics" ]["OPTIONS" ]["bucket_name" ])
48100
49101 def test_init_allows_overriding_default_kwargs (self ):
50102 """User-provided kwargs override defaults."""
103+ # The default for import_export should be True (assuming settings)
51104 storage = ImportExportS3Storage (querystring_auth = False )
52105 self .assertFalse (storage .querystring_auth )
53106 self .assertEqual (storage .bucket_name , settings .STORAGES ["import_export" ]["OPTIONS" ]["bucket_name" ])
0 commit comments