""" Unit tests for site provisioning """ import pytest from unittest.mock import Mock, MagicMock, patch from src.generation.site_provisioning import ( generate_random_suffix, slugify_keyword, create_bunnynet_site, provision_keyword_sites, create_generic_sites ) from src.deployment.bunnynet import StorageZoneResult, PullZoneResult, BunnyNetAPIError class TestHelperFunctions: """Tests for helper functions""" def test_generate_random_suffix(self): suffix = generate_random_suffix(4) assert len(suffix) == 4 assert suffix.isalnum() def test_generate_random_suffix_custom_length(self): suffix = generate_random_suffix(8) assert len(suffix) == 8 def test_slugify_keyword(self): assert slugify_keyword("Engine Repair") == "engine-repair" assert slugify_keyword("Car Maintenance!") == "car-maintenance" assert slugify_keyword(" spaces ") == "spaces" assert slugify_keyword("Multiple Spaces") == "multiple-spaces" class TestCreateBunnynetSite: """Tests for create_bunnynet_site function""" @patch('src.generation.site_provisioning.generate_random_suffix') def test_successful_site_creation(self, mock_suffix): mock_suffix.return_value = "abc123" bunny_client = Mock() bunny_client.create_storage_zone.return_value = StorageZoneResult( id=100, name="engine-repair-abc123", password="test_password", region="DE" ) bunny_client.create_pull_zone.return_value = PullZoneResult( id=200, name="engine-repair-abc123", hostname="engine-repair-abc123.b-cdn.net" ) site_repo = Mock() created_site = Mock() created_site.id = 1 site_repo.create.return_value = created_site result = create_bunnynet_site("engine-repair", bunny_client, site_repo, region="DE") assert result == created_site bunny_client.create_storage_zone.assert_called_once_with( name="engine-repair-abc123", region="DE" ) bunny_client.create_pull_zone.assert_called_once_with( name="engine-repair-abc123", storage_zone_id=100 ) site_repo.create.assert_called_once() def test_api_error_propagates(self): bunny_client = Mock() bunny_client.create_storage_zone.side_effect = BunnyNetAPIError("API Error") site_repo = Mock() with pytest.raises(BunnyNetAPIError): create_bunnynet_site("test", bunny_client, site_repo) class TestProvisionKeywordSites: """Tests for provision_keyword_sites function""" @patch('src.generation.site_provisioning.create_bunnynet_site') def test_provision_multiple_keywords(self, mock_create_site): mock_sites = [Mock(id=i) for i in range(5)] mock_create_site.side_effect = mock_sites bunny_client = Mock() site_repo = Mock() keywords = [ {"keyword": "engine repair", "count": 3}, {"keyword": "car maintenance", "count": 2} ] result = provision_keyword_sites(keywords, bunny_client, site_repo, region="DE") assert len(result) == 5 assert mock_create_site.call_count == 5 calls = mock_create_site.call_args_list # Check first call was for engine-repair assert calls[0].kwargs['name_prefix'] == "engine-repair" # Check 4th call (index 3) was for car-maintenance assert calls[3].kwargs['name_prefix'] == "car-maintenance" @patch('src.generation.site_provisioning.create_bunnynet_site') def test_skip_empty_keywords(self, mock_create_site): bunny_client = Mock() site_repo = Mock() keywords = [ {"keyword": "", "count": 3}, {"count": 2} ] result = provision_keyword_sites(keywords, bunny_client, site_repo) assert len(result) == 0 mock_create_site.assert_not_called() class TestCreateGenericSites: """Tests for create_generic_sites function""" @patch('src.generation.site_provisioning.create_bunnynet_site') def test_create_multiple_generic_sites(self, mock_create_site): mock_sites = [Mock(id=i) for i in range(3)] mock_create_site.side_effect = mock_sites bunny_client = Mock() site_repo = Mock() result = create_generic_sites(3, "shaft machining", bunny_client, site_repo, region="NY") assert len(result) == 3 assert mock_create_site.call_count == 3 calls = mock_create_site.call_args_list assert all(call.kwargs.get('name_prefix') == "shaft-machining" for call in calls) assert all(call.kwargs.get('region') == "NY" for call in calls)