185 lines
6.1 KiB
Python
185 lines
6.1 KiB
Python
"""
|
|
Unit tests for SiteDeploymentRepository
|
|
Story 6.3: Database Schema Updates for Multi-Cloud
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, MagicMock
|
|
from sqlalchemy.exc import IntegrityError
|
|
from src.database.repositories import SiteDeploymentRepository
|
|
from src.database.models import SiteDeployment
|
|
|
|
|
|
@pytest.fixture
|
|
def mock_session():
|
|
return Mock()
|
|
|
|
|
|
@pytest.fixture
|
|
def site_deployment_repo(mock_session):
|
|
return SiteDeploymentRepository(mock_session)
|
|
|
|
|
|
def test_create_site_deployment_bunny_default(site_deployment_repo, mock_session):
|
|
"""Test creating site deployment with default bunny provider (backward compatibility)"""
|
|
mock_session.add = Mock()
|
|
mock_session.commit = Mock()
|
|
mock_session.refresh = Mock()
|
|
|
|
deployment = site_deployment_repo.create(
|
|
site_name="Test Site",
|
|
storage_zone_id=1,
|
|
storage_zone_name="test-zone",
|
|
storage_zone_password="test-password",
|
|
storage_zone_region="DE",
|
|
pull_zone_id=1,
|
|
pull_zone_bcdn_hostname="test.b-cdn.net"
|
|
)
|
|
|
|
assert mock_session.add.called
|
|
assert mock_session.commit.called
|
|
assert mock_session.refresh.called
|
|
|
|
added_deployment = mock_session.add.call_args[0][0]
|
|
assert added_deployment.storage_provider == "bunny"
|
|
assert added_deployment.s3_bucket_name is None
|
|
assert added_deployment.s3_bucket_region is None
|
|
|
|
|
|
def test_create_site_deployment_with_s3_fields(site_deployment_repo, mock_session):
|
|
"""Test creating site deployment with S3 provider and S3 fields"""
|
|
mock_session.add = Mock()
|
|
mock_session.commit = Mock()
|
|
mock_session.refresh = Mock()
|
|
|
|
deployment = site_deployment_repo.create(
|
|
site_name="S3 Site",
|
|
storage_zone_id=1,
|
|
storage_zone_name="test-zone",
|
|
storage_zone_password="test-password",
|
|
storage_zone_region="DE",
|
|
pull_zone_id=1,
|
|
pull_zone_bcdn_hostname="test.b-cdn.net",
|
|
storage_provider="s3",
|
|
s3_bucket_name="my-bucket",
|
|
s3_bucket_region="us-east-1",
|
|
s3_custom_domain="cdn.example.com",
|
|
s3_endpoint_url=None
|
|
)
|
|
|
|
assert mock_session.add.called
|
|
assert mock_session.commit.called
|
|
|
|
added_deployment = mock_session.add.call_args[0][0]
|
|
assert added_deployment.storage_provider == "s3"
|
|
assert added_deployment.s3_bucket_name == "my-bucket"
|
|
assert added_deployment.s3_bucket_region == "us-east-1"
|
|
assert added_deployment.s3_custom_domain == "cdn.example.com"
|
|
assert added_deployment.s3_endpoint_url is None
|
|
|
|
|
|
def test_create_site_deployment_s3_compatible(site_deployment_repo, mock_session):
|
|
"""Test creating site deployment with S3-compatible provider and custom endpoint"""
|
|
mock_session.add = Mock()
|
|
mock_session.commit = Mock()
|
|
mock_session.refresh = Mock()
|
|
|
|
deployment = site_deployment_repo.create(
|
|
site_name="DO Spaces Site",
|
|
storage_zone_id=1,
|
|
storage_zone_name="test-zone",
|
|
storage_zone_password="test-password",
|
|
storage_zone_region="DE",
|
|
pull_zone_id=1,
|
|
pull_zone_bcdn_hostname="test.b-cdn.net",
|
|
storage_provider="s3_compatible",
|
|
s3_bucket_name="my-spaces-bucket",
|
|
s3_bucket_region="nyc3",
|
|
s3_endpoint_url="https://nyc3.digitaloceanspaces.com"
|
|
)
|
|
|
|
added_deployment = mock_session.add.call_args[0][0]
|
|
assert added_deployment.storage_provider == "s3_compatible"
|
|
assert added_deployment.s3_bucket_name == "my-spaces-bucket"
|
|
assert added_deployment.s3_bucket_region == "nyc3"
|
|
assert added_deployment.s3_endpoint_url == "https://nyc3.digitaloceanspaces.com"
|
|
|
|
|
|
def test_create_site_deployment_explicit_bunny(site_deployment_repo, mock_session):
|
|
"""Test creating site deployment with explicit bunny provider"""
|
|
mock_session.add = Mock()
|
|
mock_session.commit = Mock()
|
|
mock_session.refresh = Mock()
|
|
|
|
deployment = site_deployment_repo.create(
|
|
site_name="Bunny Site",
|
|
storage_zone_id=1,
|
|
storage_zone_name="test-zone",
|
|
storage_zone_password="test-password",
|
|
storage_zone_region="DE",
|
|
pull_zone_id=1,
|
|
pull_zone_bcdn_hostname="test.b-cdn.net",
|
|
storage_provider="bunny"
|
|
)
|
|
|
|
added_deployment = mock_session.add.call_args[0][0]
|
|
assert added_deployment.storage_provider == "bunny"
|
|
|
|
|
|
def test_create_site_deployment_duplicate_hostname_raises_error(site_deployment_repo, mock_session):
|
|
"""Test creating site deployment with duplicate hostname raises error"""
|
|
mock_session.add = Mock()
|
|
mock_session.commit = Mock(side_effect=IntegrityError("", "", ""))
|
|
mock_session.rollback = Mock()
|
|
|
|
with pytest.raises(ValueError) as exc_info:
|
|
site_deployment_repo.create(
|
|
site_name="Test Site",
|
|
storage_zone_id=1,
|
|
storage_zone_name="test-zone",
|
|
storage_zone_password="test-password",
|
|
storage_zone_region="DE",
|
|
pull_zone_id=1,
|
|
pull_zone_bcdn_hostname="test.b-cdn.net"
|
|
)
|
|
|
|
assert "already exists" in str(exc_info.value)
|
|
assert mock_session.rollback.called
|
|
|
|
|
|
def test_get_by_id(site_deployment_repo, mock_session):
|
|
"""Test getting site deployment by ID"""
|
|
mock_deployment = Mock(spec=SiteDeployment, id=1, site_name="Test Site")
|
|
|
|
mock_query = Mock()
|
|
mock_filter = Mock()
|
|
mock_filter.first = Mock(return_value=mock_deployment)
|
|
mock_query.filter = Mock(return_value=mock_filter)
|
|
mock_session.query = Mock(return_value=mock_query)
|
|
|
|
deployment = site_deployment_repo.get_by_id(1)
|
|
|
|
assert deployment == mock_deployment
|
|
assert mock_session.query.called
|
|
|
|
|
|
def test_get_all(site_deployment_repo, mock_session):
|
|
"""Test getting all site deployments"""
|
|
mock_deployments = [
|
|
Mock(spec=SiteDeployment, id=1, site_name="Site 1"),
|
|
Mock(spec=SiteDeployment, id=2, site_name="Site 2")
|
|
]
|
|
|
|
mock_query = Mock()
|
|
mock_query.all = Mock(return_value=mock_deployments)
|
|
mock_session.query = Mock(return_value=mock_query)
|
|
|
|
deployments = site_deployment_repo.get_all()
|
|
|
|
assert len(deployments) == 2
|
|
assert mock_session.query.called
|
|
|
|
|
|
|
|
|