@@ -204,3 +204,97 @@ def test_explicit_expiration_overrides_default(self, mock_boto3):
204204 mock_s3_client .generate_presigned_url .assert_called_once ()
205205 call_kwargs = mock_s3_client .generate_presigned_url .call_args [1 ]
206206 assert call_kwargs ["ExpiresIn" ] == 120
207+
208+
209+ @pytest .mark .unit
210+ class TestS3StorageAddressingStyle :
211+ """Test the S3 addressing style configuration via AWS_S3_ADDRESSING_STYLE"""
212+
213+ @patch .dict (
214+ os .environ ,
215+ {
216+ "AWS_ACCESS_KEY_ID" : "test-key" ,
217+ "AWS_SECRET_ACCESS_KEY" : "test-secret" ,
218+ "AWS_S3_BUCKET_NAME" : "test-bucket" ,
219+ "AWS_REGION" : "us-east-1" ,
220+ "AWS_S3_ENDPOINT_URL" : "https://s3.amazonaws.com" ,
221+ "AWS_S3_ADDRESSING_STYLE" : "virtual" ,
222+ },
223+ clear = True ,
224+ )
225+ @patch ("plane.settings.storage.boto3" )
226+ def test_virtual_addressing_style (self , mock_boto3 ):
227+ """Test that virtual addressing style is configured via botocore Config"""
228+ mock_boto3 .client .return_value = Mock ()
229+
230+ storage = S3Storage ()
231+
232+ call_kwargs = mock_boto3 .client .call_args [1 ]
233+ assert call_kwargs ["config" ].s3 ["addressing_style" ] == "virtual"
234+
235+ @patch .dict (
236+ os .environ ,
237+ {
238+ "AWS_ACCESS_KEY_ID" : "test-key" ,
239+ "AWS_SECRET_ACCESS_KEY" : "test-secret" ,
240+ "AWS_S3_BUCKET_NAME" : "test-bucket" ,
241+ "AWS_REGION" : "us-east-1" ,
242+ "AWS_S3_ENDPOINT_URL" : "https://s3.amazonaws.com" ,
243+ "AWS_S3_ADDRESSING_STYLE" : "path" ,
244+ },
245+ clear = True ,
246+ )
247+ @patch ("plane.settings.storage.boto3" )
248+ def test_path_addressing_style (self , mock_boto3 ):
249+ """Test that path addressing style is configured via botocore Config"""
250+ mock_boto3 .client .return_value = Mock ()
251+
252+ storage = S3Storage ()
253+
254+ call_kwargs = mock_boto3 .client .call_args [1 ]
255+ assert call_kwargs ["config" ].s3 ["addressing_style" ] == "path"
256+
257+ @patch .dict (
258+ os .environ ,
259+ {
260+ "AWS_ACCESS_KEY_ID" : "test-key" ,
261+ "AWS_SECRET_ACCESS_KEY" : "test-secret" ,
262+ "AWS_S3_BUCKET_NAME" : "test-bucket" ,
263+ "AWS_REGION" : "us-east-1" ,
264+ "AWS_S3_ENDPOINT_URL" : "https://s3.amazonaws.com" ,
265+ },
266+ clear = True ,
267+ )
268+ @patch ("plane.settings.storage.boto3" )
269+ def test_auto_addressing_style_by_default (self , mock_boto3 ):
270+ """Test that auto addressing style is used by default (no s3 config in botocore Config)"""
271+ mock_boto3 .client .return_value = Mock ()
272+
273+ storage = S3Storage ()
274+
275+ call_kwargs = mock_boto3 .client .call_args [1 ]
276+ # When addressing_style is 'auto' or not set, botocore Config should not have s3 dict
277+ assert "s3" not in call_kwargs ["config" ]._user_provided_options
278+
279+ @patch .dict (
280+ os .environ ,
281+ {
282+ "AWS_ACCESS_KEY_ID" : "test-key" ,
283+ "AWS_SECRET_ACCESS_KEY" : "test-secret" ,
284+ "AWS_S3_BUCKET_NAME" : "test-bucket" ,
285+ "AWS_REGION" : "us-east-1" ,
286+ "AWS_S3_ENDPOINT_URL" : "https://nyc3.digitaloceanspaces.com" ,
287+ "AWS_S3_ADDRESSING_STYLE" : "virtual" ,
288+ },
289+ clear = True ,
290+ )
291+ @patch ("plane.settings.storage.boto3" )
292+ def test_virtual_style_with_digitalocean_spaces (self , mock_boto3 ):
293+ """Test virtual addressing style works with DigitalOcean Spaces"""
294+ mock_boto3 .client .return_value = Mock ()
295+
296+ storage = S3Storage ()
297+
298+ call_kwargs = mock_boto3 .client .call_args [1 ]
299+ assert call_kwargs ["config" ].s3 ["addressing_style" ] == "virtual"
300+ assert call_kwargs ["endpoint_url" ] == "https://nyc3.digitaloceanspaces.com"
0 commit comments