Big-Link-Man/tests/unit/test_deployment_assignment.py

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