Spaces:
Sleeping
Sleeping
| """ | |
| Unit tests for S3Config module. | |
| Feature: 015-sqlite-s3-backup | |
| """ | |
| import os | |
| import pytest | |
| from unittest.mock import patch, MagicMock | |
| from src.services.s3_config import ( | |
| S3Config, | |
| S3CredentialsError, | |
| S3BucketNotFoundError, | |
| S3ConnectionError | |
| ) | |
| class TestS3ConfigFromEnv: | |
| """Tests for S3Config.from_env() factory method.""" | |
| def test_from_env_valid_config(self): | |
| """Test loading valid S3 configuration from environment.""" | |
| config = S3Config.from_env() | |
| assert config.enabled is True | |
| assert config.bucket == 'test-bucket' | |
| assert config.access_key == 'test-access-key' | |
| assert config.secret_key == 'test-secret-key' | |
| assert config.region == 'us-west-2' | |
| assert config.upload_timeout == 60 | |
| assert config.download_timeout == 30 | |
| assert config.debounce_seconds == 300 | |
| def test_from_env_missing_config(self): | |
| """Test that missing S3_BACKUP_ENABLED defaults to disabled.""" | |
| config = S3Config.from_env() | |
| assert config.enabled is False | |
| def test_from_env_partial_config(self): | |
| """Test that partial configuration disables the feature with warning.""" | |
| config = S3Config.from_env() | |
| assert config.enabled is False | |
| class TestS3ConfigValidateCredentials: | |
| """Tests for S3Config.validate_credentials() method.""" | |
| def test_validate_credentials_success(self, mock_boto_client): | |
| """Test successful credential validation.""" | |
| # Setup mock | |
| mock_s3 = MagicMock() | |
| mock_boto_client.return_value = mock_s3 | |
| mock_s3.head_bucket.return_value = {} | |
| # Create config | |
| config = S3Config( | |
| enabled=True, | |
| bucket='test-bucket', | |
| access_key='test-key', | |
| secret_key='test-secret' | |
| ) | |
| # Validate | |
| result = config.validate_credentials() | |
| assert result is True | |
| mock_s3.head_bucket.assert_called_once_with(Bucket='test-bucket') | |
| def test_validate_credentials_bucket_not_found(self, mock_boto_client): | |
| """Test validation with non-existent bucket.""" | |
| # Setup mock | |
| mock_s3 = MagicMock() | |
| mock_boto_client.return_value = mock_s3 | |
| from botocore.exceptions import ClientError | |
| mock_s3.head_bucket.side_effect = ClientError( | |
| {'Error': {'Code': '404'}}, | |
| 'HeadBucket' | |
| ) | |
| # Create config | |
| config = S3Config( | |
| enabled=True, | |
| bucket='nonexistent-bucket', | |
| access_key='test-key', | |
| secret_key='test-secret' | |
| ) | |
| # Validate | |
| result = config.validate_credentials() | |
| assert result is False | |
| def test_validate_credentials_access_denied(self, mock_boto_client): | |
| """Test validation with invalid credentials.""" | |
| # Setup mock | |
| mock_s3 = MagicMock() | |
| mock_boto_client.return_value = mock_s3 | |
| from botocore.exceptions import ClientError | |
| mock_s3.head_bucket.side_effect = ClientError( | |
| {'Error': {'Code': '403'}}, | |
| 'HeadBucket' | |
| ) | |
| # Create config | |
| config = S3Config( | |
| enabled=True, | |
| bucket='test-bucket', | |
| access_key='invalid-key', | |
| secret_key='invalid-secret' | |
| ) | |
| # Validate | |
| result = config.validate_credentials() | |
| assert result is False | |