190 lines
6.5 KiB
Python
190 lines
6.5 KiB
Python
"""
|
|
Unit tests for deployment target assignment logic
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import Mock, MagicMock
|
|
from src.generation.deployment_assignment import (
|
|
resolve_hostname_to_id,
|
|
validate_and_resolve_targets,
|
|
assign_site_for_article
|
|
)
|
|
from src.database.models import SiteDeployment
|
|
|
|
|
|
class TestResolveHostnameToId:
|
|
"""Test resolve_hostname_to_id function"""
|
|
|
|
def test_resolve_valid_hostname(self):
|
|
"""Test resolving a valid hostname"""
|
|
mock_repo = Mock()
|
|
mock_deployment = Mock(spec=SiteDeployment)
|
|
mock_deployment.id = 5
|
|
mock_repo.get_by_hostname.return_value = mock_deployment
|
|
|
|
result = resolve_hostname_to_id("www.example.com", mock_repo)
|
|
|
|
assert result == 5
|
|
mock_repo.get_by_hostname.assert_called_once_with("www.example.com")
|
|
|
|
def test_resolve_invalid_hostname(self):
|
|
"""Test resolving an invalid hostname returns None"""
|
|
mock_repo = Mock()
|
|
mock_repo.get_by_hostname.return_value = None
|
|
|
|
result = resolve_hostname_to_id("nonexistent.com", mock_repo)
|
|
|
|
assert result is None
|
|
mock_repo.get_by_hostname.assert_called_once_with("nonexistent.com")
|
|
|
|
|
|
class TestValidateAndResolveTargets:
|
|
"""Test validate_and_resolve_targets function"""
|
|
|
|
def test_validate_empty_list(self):
|
|
"""Test validating an empty list returns empty dict"""
|
|
mock_repo = Mock()
|
|
|
|
result = validate_and_resolve_targets([], mock_repo)
|
|
|
|
assert result == {}
|
|
mock_repo.get_by_hostname.assert_not_called()
|
|
|
|
def test_validate_all_valid_hostnames(self):
|
|
"""Test validating all valid hostnames"""
|
|
mock_repo = Mock()
|
|
|
|
def mock_get_by_hostname(hostname):
|
|
deployments = {
|
|
"www.domain1.com": Mock(id=1),
|
|
"www.domain2.com": Mock(id=2),
|
|
"www.domain3.com": Mock(id=3)
|
|
}
|
|
return deployments.get(hostname)
|
|
|
|
mock_repo.get_by_hostname.side_effect = mock_get_by_hostname
|
|
|
|
hostnames = ["www.domain1.com", "www.domain2.com", "www.domain3.com"]
|
|
result = validate_and_resolve_targets(hostnames, mock_repo)
|
|
|
|
assert result == {
|
|
"www.domain1.com": 1,
|
|
"www.domain2.com": 2,
|
|
"www.domain3.com": 3
|
|
}
|
|
assert mock_repo.get_by_hostname.call_count == 3
|
|
|
|
def test_validate_with_invalid_hostname(self):
|
|
"""Test validation fails with invalid hostname"""
|
|
mock_repo = Mock()
|
|
|
|
def mock_get_by_hostname(hostname):
|
|
if hostname == "www.domain1.com":
|
|
return Mock(id=1)
|
|
return None
|
|
|
|
mock_repo.get_by_hostname.side_effect = mock_get_by_hostname
|
|
|
|
hostnames = ["www.domain1.com", "invalid.com"]
|
|
|
|
with pytest.raises(ValueError) as exc_info:
|
|
validate_and_resolve_targets(hostnames, mock_repo)
|
|
|
|
assert "invalid.com" in str(exc_info.value)
|
|
assert "not found in database" in str(exc_info.value)
|
|
|
|
def test_validate_with_multiple_invalid_hostnames(self):
|
|
"""Test validation fails with multiple invalid hostnames"""
|
|
mock_repo = Mock()
|
|
mock_repo.get_by_hostname.return_value = None
|
|
|
|
hostnames = ["invalid1.com", "invalid2.com", "invalid3.com"]
|
|
|
|
with pytest.raises(ValueError) as exc_info:
|
|
validate_and_resolve_targets(hostnames, mock_repo)
|
|
|
|
error_msg = str(exc_info.value)
|
|
assert "invalid1.com" in error_msg
|
|
assert "invalid2.com" in error_msg
|
|
assert "invalid3.com" in error_msg
|
|
|
|
def test_validate_with_empty_string_hostname(self):
|
|
"""Test validation fails with empty string hostname"""
|
|
mock_repo = Mock()
|
|
|
|
hostnames = ["www.valid.com", ""]
|
|
|
|
with pytest.raises(ValueError) as exc_info:
|
|
validate_and_resolve_targets(hostnames, mock_repo)
|
|
|
|
assert "Invalid hostname" in str(exc_info.value)
|
|
|
|
def test_validate_with_non_string_hostname(self):
|
|
"""Test validation fails with non-string hostname"""
|
|
mock_repo = Mock()
|
|
|
|
hostnames = ["www.valid.com", 123]
|
|
|
|
with pytest.raises(ValueError) as exc_info:
|
|
validate_and_resolve_targets(hostnames, mock_repo)
|
|
|
|
assert "Invalid hostname" in str(exc_info.value)
|
|
|
|
|
|
class TestAssignSiteForArticle:
|
|
"""Test assign_site_for_article function"""
|
|
|
|
def test_assign_with_empty_targets(self):
|
|
"""Test assignment with no targets returns None"""
|
|
result = assign_site_for_article(0, {})
|
|
assert result is None
|
|
|
|
result = assign_site_for_article(5, {})
|
|
assert result is None
|
|
|
|
def test_assign_within_target_range(self):
|
|
"""Test assignment within target range"""
|
|
resolved_targets = {
|
|
"www.domain1.com": 5,
|
|
"www.domain2.com": 8,
|
|
"www.domain3.com": 12
|
|
}
|
|
|
|
assert assign_site_for_article(0, resolved_targets) == 5
|
|
assert assign_site_for_article(1, resolved_targets) == 8
|
|
assert assign_site_for_article(2, resolved_targets) == 12
|
|
|
|
def test_assign_beyond_target_range(self):
|
|
"""Test assignment beyond target range returns None"""
|
|
resolved_targets = {
|
|
"www.domain1.com": 5,
|
|
"www.domain2.com": 8,
|
|
"www.domain3.com": 12
|
|
}
|
|
|
|
assert assign_site_for_article(3, resolved_targets) is None
|
|
assert assign_site_for_article(4, resolved_targets) is None
|
|
assert assign_site_for_article(10, resolved_targets) is None
|
|
|
|
def test_assign_single_target(self):
|
|
"""Test assignment with single target"""
|
|
resolved_targets = {"www.domain1.com": 5}
|
|
|
|
assert assign_site_for_article(0, resolved_targets) == 5
|
|
assert assign_site_for_article(1, resolved_targets) is None
|
|
assert assign_site_for_article(2, resolved_targets) is None
|
|
|
|
def test_assign_with_ten_articles_three_targets(self):
|
|
"""Test assignment scenario: 10 articles, 3 targets"""
|
|
resolved_targets = {
|
|
"www.domain1.com": 5,
|
|
"www.domain2.com": 8,
|
|
"www.domain3.com": 12
|
|
}
|
|
|
|
results = [assign_site_for_article(i, resolved_targets) for i in range(10)]
|
|
|
|
expected = [5, 8, 12, None, None, None, None, None, None, None]
|
|
assert results == expected
|
|
|