Remove 5 dead test files referencing deleted/renamed modules

These tests import classes and functions that no longer exist:
- ContentGenerationService (renamed to ContentGenerator)
- ContentRuleEngine, ContentHTMLParser (rule_engine.py deprecated)
- ContentAugmenter (depends on dead rule_engine imports)
- get_domain_from_site (removed from site_page_generator)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
main
PeninsulaInd 2026-02-20 22:19:19 -06:00
parent 0c559654b4
commit 785fc9c7ac
5 changed files with 0 additions and 1144 deletions

View File

@ -1,194 +0,0 @@
"""
Integration tests for content generation pipeline
"""
import pytest
import os
from unittest.mock import Mock, patch
from src.database.models import Project, User, GeneratedContent
from src.database.repositories import ProjectRepository, GeneratedContentRepository
from src.generation.service import ContentGenerationService
from src.generation.job_config import JobConfig, TierConfig, ModelConfig
@pytest.fixture
def test_project(db_session):
"""Create a test project"""
user = User(
username="testuser",
hashed_password="hashed",
role="User"
)
db_session.add(user)
db_session.commit()
project_data = {
"main_keyword": "test automation",
"word_count": 1000,
"term_frequency": 3,
"h2_total": 5,
"h2_exact": 1,
"h2_related_search": 1,
"h2_entities": 2,
"h3_total": 10,
"h3_exact": 1,
"h3_related_search": 2,
"h3_entities": 3,
"entities": ["automation tool", "testing framework", "ci/cd"],
"related_searches": ["test automation best practices", "automation frameworks"]
}
project_repo = ProjectRepository(db_session)
project = project_repo.create(user.id, "Test Project", project_data)
return project
@pytest.mark.integration
def test_generated_content_repository(db_session, test_project):
"""Test GeneratedContentRepository CRUD operations"""
repo = GeneratedContentRepository(db_session)
content = repo.create(test_project.id, tier=1)
assert content.id is not None
assert content.project_id == test_project.id
assert content.tier == 1
assert content.status == "pending"
assert content.generation_stage == "title"
retrieved = repo.get_by_id(content.id)
assert retrieved is not None
assert retrieved.id == content.id
project_contents = repo.get_by_project_id(test_project.id)
assert len(project_contents) == 1
assert project_contents[0].id == content.id
content.title = "Test Title"
content.status = "completed"
updated = repo.update(content)
assert updated.title == "Test Title"
assert updated.status == "completed"
success = repo.set_active(content.id, test_project.id, tier=1)
assert success is True
active = repo.get_active_by_project(test_project.id, tier=1)
assert active is not None
assert active.id == content.id
assert active.is_active is True
@pytest.mark.integration
@patch.dict(os.environ, {"AI_API_KEY": "test-key"})
def test_content_generation_service_initialization(db_session):
"""Test ContentGenerationService initializes correctly"""
with patch('src.generation.ai_client.OpenAI'):
service = ContentGenerationService(db_session)
assert service.session is not None
assert service.config is not None
assert service.ai_client is not None
assert service.content_repo is not None
assert service.rule_engine is not None
assert service.validator is not None
assert service.augmenter is not None
@pytest.mark.integration
@patch.dict(os.environ, {"AI_API_KEY": "test-key"})
def test_content_generation_flow_mocked(db_session, test_project):
"""Test full content generation flow with mocked AI"""
with patch('src.generation.ai_client.OpenAI'):
service = ContentGenerationService(db_session)
service.ai_client.generate = Mock(return_value="Test Automation: Complete Guide")
outline = {
"h1": "Test Automation Overview",
"sections": [
{"h2": "Test Automation Basics", "h3s": ["Getting Started", "Best Practices"]},
{"h2": "Advanced Topics", "h3s": ["CI/CD Integration"]},
{"h2": "Frequently Asked Questions", "h3s": ["What is test automation?", "How to start?"]}
]
}
service.ai_client.generate_json = Mock(return_value=outline)
html_content = """
<h1>Test Automation Overview</h1>
<p>Test automation is essential for modern software development.</p>
<h2>Test Automation Basics</h2>
<p>Understanding test automation fundamentals is crucial.</p>
<h3>Getting Started</h3>
<p>Begin with test automation frameworks and tools.</p>
<h3>Best Practices</h3>
<p>Follow test automation best practices for success.</p>
<h2>Advanced Topics</h2>
<p>Explore advanced test automation techniques.</p>
<h3>CI/CD Integration</h3>
<p>Integrate test automation with ci/cd pipelines.</p>
<h2>Frequently Asked Questions</h2>
<h3>What is test automation?</h3>
<p>What is test automation? Test automation is the practice of running tests automatically.</p>
<h3>How to start?</h3>
<p>How to start? Begin by selecting an automation tool and testing framework.</p>
"""
service.ai_client.generate = Mock(side_effect=[
"Test Automation: Complete Guide",
html_content
])
try:
content = service.generate_article(
project=test_project,
tier=1,
title_model="test-model",
outline_model="test-model",
content_model="test-model",
max_retries=1
)
assert content is not None
assert content.title is not None
assert content.outline is not None
assert content.status in ["completed", "failed"]
except Exception as e:
pytest.skip(f"Generation failed (expected in mocked test): {e}")
@pytest.mark.integration
def test_job_config_validation():
"""Test JobConfig validation"""
models = ModelConfig(
title="anthropic/claude-3.5-sonnet",
outline="anthropic/claude-3.5-sonnet",
content="anthropic/claude-3.5-sonnet"
)
tier = TierConfig(
tier=1,
article_count=5,
models=models
)
job = JobConfig(
job_name="Integration Test Job",
project_id=1,
tiers=[tier]
)
assert job.get_total_articles() == 5
assert len(job.tiers) == 1
assert job.tiers[0].tier == 1

View File

@ -1,93 +0,0 @@
"""
Unit tests for content augmenter
"""
import pytest
from src.generation.augmenter import ContentAugmenter
@pytest.fixture
def augmenter():
return ContentAugmenter()
def test_augment_outline_add_h2_keyword(augmenter):
"""Test adding keyword to H2 headings"""
outline = {
"h1": "Main Title",
"sections": [
{"h2": "Introduction", "h3s": []},
{"h2": "Advanced Topics", "h3s": []}
]
}
missing = {"h2_exact": 1}
result, log = augmenter.augment_outline(
outline, missing, "test keyword", [], []
)
assert "test keyword" in result["sections"][0]["h2"].lower()
assert log["headings_modified"] > 0
def test_augment_outline_add_h3_entities(augmenter):
"""Test adding entity-based H3 headings"""
outline = {
"h1": "Main Title",
"sections": [
{"h2": "Section 1", "h3s": []}
]
}
missing = {"h3_entities": 2}
entities = ["entity1", "entity2", "entity3"]
result, log = augmenter.augment_outline(
outline, missing, "keyword", entities, []
)
assert log["h3_added"] == 2
assert any("entity1" in h3.lower()
for s in result["sections"]
for h3 in s.get("h3s", []))
def test_augment_content_insert_keywords(augmenter):
"""Test inserting keywords into content"""
html = "<p>This is a paragraph with enough words to allow keyword insertion for testing purposes.</p>"
missing = {"keyword_mentions": 2}
result, log = augmenter.augment_content(
html, missing, "keyword", [], []
)
assert log["keywords_inserted"] > 0
assert "keyword" in result.lower()
def test_augment_content_insert_entities(augmenter):
"""Test inserting entities into content"""
html = "<p>This is a long paragraph with many words that allows us to insert various terms naturally.</p>"
missing = {"entity_mentions": 2}
entities = ["entity1", "entity2"]
result, log = augmenter.augment_content(
html, missing, "keyword", entities, []
)
assert log["entities_inserted"] > 0
def test_add_paragraph_with_terms(augmenter):
"""Test adding a new paragraph with specific terms"""
html = "<h1>Title</h1><p>Existing content</p>"
terms = ["term1", "term2", "term3"]
result = augmenter.add_paragraph_with_terms(
html, terms, "entity", "main keyword"
)
assert "term1" in result or "term2" in result or "term3" in result
assert "main keyword" in result

View File

@ -1,217 +0,0 @@
"""
Unit tests for content generation service
"""
import pytest
import json
from unittest.mock import Mock, MagicMock, patch
from src.generation.service import ContentGenerationService, GenerationError
from src.database.models import Project, GeneratedContent
from src.generation.rule_engine import ValidationResult
@pytest.fixture
def mock_session():
return Mock()
@pytest.fixture
def mock_config():
config = Mock()
config.ai_service.max_tokens = 4000
config.content_rules.cora_validation.round_averages_down = True
config.content_rules.cora_validation.tier_1_strict = True
return config
@pytest.fixture
def mock_project():
project = Mock(spec=Project)
project.id = 1
project.main_keyword = "test keyword"
project.word_count = 1000
project.term_frequency = 2
project.tier = 1
project.h2_total = 5
project.h2_exact = 1
project.h2_related_search = 1
project.h2_entities = 2
project.h3_total = 10
project.h3_exact = 1
project.h3_related_search = 2
project.h3_entities = 3
project.entities = ["entity1", "entity2", "entity3"]
project.related_searches = ["search1", "search2", "search3"]
return project
@pytest.fixture
def service(mock_session, mock_config):
with patch('src.generation.service.AIClient'):
service = ContentGenerationService(mock_session, mock_config)
return service
def test_service_initialization(service):
"""Test service initializes correctly"""
assert service.session is not None
assert service.config is not None
assert service.ai_client is not None
assert service.content_repo is not None
assert service.rule_engine is not None
def test_generate_title_success(service, mock_project):
"""Test successful title generation"""
service.ai_client.generate = Mock(return_value="Test Keyword Complete Guide")
service.validator.validate_title = Mock(return_value=(True, []))
content_record = Mock(spec=GeneratedContent)
content_record.title_attempts = 0
service.content_repo.update = Mock()
result = service._generate_title(mock_project, content_record, "test-model", 3)
assert result == "Test Keyword Complete Guide"
assert service.ai_client.generate.called
def test_generate_title_validation_retry(service, mock_project):
"""Test title generation retries on validation failure"""
service.ai_client.generate = Mock(side_effect=[
"Wrong Title",
"Test Keyword Guide"
])
service.validator.validate_title = Mock(side_effect=[
(False, ["Missing keyword"]),
(True, [])
])
content_record = Mock(spec=GeneratedContent)
content_record.title_attempts = 0
service.content_repo.update = Mock()
result = service._generate_title(mock_project, content_record, "test-model", 3)
assert result == "Test Keyword Guide"
assert service.ai_client.generate.call_count == 2
def test_generate_title_max_retries_exceeded(service, mock_project):
"""Test title generation fails after max retries"""
service.ai_client.generate = Mock(return_value="Wrong Title")
service.validator.validate_title = Mock(return_value=(False, ["Missing keyword"]))
content_record = Mock(spec=GeneratedContent)
content_record.title_attempts = 0
service.content_repo.update = Mock()
with pytest.raises(GenerationError, match="validation failed"):
service._generate_title(mock_project, content_record, "test-model", 2)
def test_generate_outline_success(service, mock_project):
"""Test successful outline generation"""
outline_data = {
"h1": "Test Keyword Overview",
"sections": [
{"h2": "Test Keyword Basics", "h3s": ["Sub 1", "Sub 2"]},
{"h2": "Advanced Topics", "h3s": ["Sub 3"]}
]
}
service.ai_client.generate_json = Mock(return_value=outline_data)
service.validator.validate_outline = Mock(return_value=(True, [], {}))
content_record = Mock(spec=GeneratedContent)
content_record.outline_attempts = 0
service.content_repo.update = Mock()
result = service._generate_outline(
mock_project, "Test Title", content_record, "test-model", 3
)
assert result == outline_data
assert service.ai_client.generate_json.called
def test_generate_outline_with_augmentation(service, mock_project):
"""Test outline generation with programmatic augmentation"""
initial_outline = {
"h1": "Test Keyword Overview",
"sections": [
{"h2": "Introduction", "h3s": []}
]
}
augmented_outline = {
"h1": "Test Keyword Overview",
"sections": [
{"h2": "Test Keyword Introduction", "h3s": ["Sub 1"]},
{"h2": "Advanced Topics", "h3s": []}
]
}
service.ai_client.generate_json = Mock(return_value=initial_outline)
service.validator.validate_outline = Mock(side_effect=[
(False, ["Not enough H2s"], {"h2_exact": 1}),
(True, [], {})
])
service.augmenter.augment_outline = Mock(return_value=(augmented_outline, {}))
content_record = Mock(spec=GeneratedContent)
content_record.outline_attempts = 0
content_record.augmented = False
service.content_repo.update = Mock()
result = service._generate_outline(
mock_project, "Test Title", content_record, "test-model", 3
)
assert service.augmenter.augment_outline.called
def test_generate_content_success(service, mock_project):
"""Test successful content generation"""
html_content = "<h1>Test</h1><p>Content</p>"
service.ai_client.generate = Mock(return_value=html_content)
validation_result = Mock(spec=ValidationResult)
validation_result.passed = True
validation_result.errors = []
validation_result.warnings = []
validation_result.to_dict = Mock(return_value={})
service.validator.validate_content = Mock(return_value=(True, validation_result))
content_record = Mock(spec=GeneratedContent)
content_record.content_attempts = 0
service.content_repo.update = Mock()
outline = {"h1": "Test", "sections": []}
result = service._generate_content(
mock_project, "Test Title", outline, content_record, "test-model", 3
)
assert result == html_content
def test_format_outline_for_prompt(service):
"""Test outline formatting for content prompt"""
outline = {
"h1": "Main Heading",
"sections": [
{"h2": "Section 1", "h3s": ["Sub 1", "Sub 2"]},
{"h2": "Section 2", "h3s": ["Sub 3"]}
]
}
result = service._format_outline_for_prompt(outline)
assert "H1: Main Heading" in result
assert "H2: Section 1" in result
assert "H3: Sub 1" in result
assert "H2: Section 2" in result

View File

@ -1,451 +0,0 @@
"""
Unit tests for content rule engine
"""
import pytest
from unittest.mock import Mock
from src.generation.rule_engine import (
ContentRuleEngine,
ContentHTMLParser,
ValidationResult,
ValidationIssue
)
from src.database.models import Project
from src.core.config import Config
@pytest.fixture
def mock_config():
"""Mock configuration for tests"""
config = Mock()
config.get = Mock(side_effect=lambda key, default={}: {
"content_rules.universal": {
"min_content_length": 1000,
"max_content_length": 5000,
"title_exact_match_required": True,
"h1_exact_match_required": True,
"h2_exact_match_min": 1,
"h3_exact_match_min": 1,
"faq_section_required": True,
"image_alt_text_keyword_required": True,
"image_alt_text_entity_required": True
},
"content_rules.cora_validation": {
"enabled": True,
"tier_1_strict": True,
"tier_2_plus_warn_only": True,
"round_averages_down": True
}
}.get(key, default))
return config
@pytest.fixture
def sample_project():
"""Sample project with CORA data"""
project = Mock(spec=Project)
project.id = 1
project.main_keyword = "shaft machining"
project.tier = 1
project.entities = ["CNC", "lathe", "precision"]
project.related_searches = ["shaft machining process", "machining techniques"]
project.h1_exact = 1
project.h1_related_search = 0
project.h1_entities = 1
project.h2_total = 5
project.h2_exact = 1
project.h2_related_search = 2
project.h2_entities = 2
project.h3_total = 8
project.h3_exact = 1
project.h3_related_search = 3
project.h3_entities = 3
return project
class TestContentHTMLParser:
"""Tests for HTML parser"""
def test_parse_title(self):
html = "<html><head><title>Shaft Machining Guide</title></head></html>"
parser = ContentHTMLParser()
parser.feed(html)
assert parser.title == "Shaft Machining Guide"
def test_parse_meta_description(self):
html = '<html><head><meta name="description" content="Complete guide to shaft machining"></head></html>'
parser = ContentHTMLParser()
parser.feed(html)
assert parser.meta_description == "Complete guide to shaft machining"
def test_parse_headings(self):
html = """
<html><body>
<h1>Main Heading about Shaft Machining</h1>
<h2>Understanding CNC</h2>
<h2>Shaft Machining Process</h2>
<h3>What is a lathe?</h3>
<h3>Precision techniques</h3>
<h3>FAQ about shaft machining</h3>
</body></html>
"""
parser = ContentHTMLParser()
parser.feed(html)
assert len(parser.h1_tags) == 1
assert "Shaft Machining" in parser.h1_tags[0]
assert len(parser.h2_tags) == 2
assert len(parser.h3_tags) == 3
def test_parse_images(self):
html = """
<html><body>
<img src="image1.jpg" alt="Shaft machining with CNC lathe">
<img src="image2.jpg" alt="Precision tools">
</body></html>
"""
parser = ContentHTMLParser()
parser.feed(html)
assert len(parser.images) == 2
assert parser.images[0]["alt"] == "Shaft machining with CNC lathe"
assert parser.images[1]["alt"] == "Precision tools"
def test_parse_links(self):
html = """
<html><body>
<a href="/home">Home Page</a>
<a href="/article">Related Article</a>
</body></html>
"""
parser = ContentHTMLParser()
parser.feed(html)
assert len(parser.links) == 2
assert parser.links[0]["href"] == "/home"
assert "Home Page" in parser.links[0]["text"]
def test_parse_text_content(self):
html = """
<html><body>
<h1>Title</h1>
<p>This is some content about shaft machining and CNC operations.</p>
<p>More content here with precision lathe work.</p>
</body></html>
"""
parser = ContentHTMLParser()
parser.feed(html)
assert "shaft machining" in parser.text_content.lower()
assert "CNC" in parser.text_content
assert len(parser.text_content.split()) > 10
class TestValidationResult:
"""Tests for ValidationResult class"""
def test_initial_state(self):
result = ValidationResult(passed=True)
assert result.passed is True
assert len(result.errors) == 0
assert len(result.warnings) == 0
def test_add_error(self):
result = ValidationResult(passed=True)
result.add_error("test_rule", "Test error", expected=5, actual=3)
assert result.passed is False
assert len(result.errors) == 1
assert result.errors[0].rule_name == "test_rule"
assert result.errors[0].severity == "error"
def test_add_warning(self):
result = ValidationResult(passed=True)
result.add_warning("test_rule", "Test warning", expected=5, actual=4)
assert result.passed is True
assert len(result.warnings) == 1
assert result.warnings[0].severity == "warning"
def test_to_dict(self):
result = ValidationResult(passed=False)
result.add_error("rule1", "Error message", expected=5, actual=3)
result.add_warning("rule2", "Warning message", expected=10, actual=8)
data = result.to_dict()
assert data["passed"] is False
assert len(data["errors"]) == 1
assert len(data["warnings"]) == 1
assert data["errors"][0]["rule"] == "rule1"
assert data["warnings"][0]["rule"] == "rule2"
class TestUniversalRules:
"""Tests for universal rule validation"""
def test_content_length_validation(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
short_html = "<html><body><h1>Shaft machining</h1><p>Short content.</p></body></html>"
result = engine.validate(short_html, sample_project)
assert not result.passed
assert any("too short" in e.message for e in result.errors)
def test_title_keyword_required(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
html_without_keyword = "<html><head><title>Generic Title</title></head><body>" + "word " * 1500 + "</body></html>"
result = engine.validate(html_without_keyword, sample_project)
assert any("title" in e.rule_name.lower() for e in result.errors)
def test_h1_keyword_required(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Generic Heading</h1>
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
assert any("h1" in e.rule_name.lower() for e in result.errors)
def test_h2_keyword_minimum(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Shaft Machining Basics</h1>
<h2>Generic Topic</h2>
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
assert any("h2_exact_match_min" in e.rule_name for e in result.errors)
def test_faq_section_required(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Shaft Machining Basics</h1>
<h2>Shaft Machining Process</h2>
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
assert any("faq" in e.rule_name.lower() for e in result.errors)
def test_image_alt_text_validation(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Shaft Machining Basics</h1>
<h2>FAQ about shaft machining</h2>
<h2>Shaft Machining Techniques</h2>
<h3>What is shaft machining?</h3>
<img src="test.jpg" alt="Generic image">
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
assert any("image_alt_text" in e.rule_name for e in result.errors)
class TestCORAValidation:
"""Tests for CORA-specific validation"""
def test_tier_1_strict_validation(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
sample_project.tier = 1
sample_project.h2_total = 5
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Shaft Machining with CNC</h1>
<h2>Shaft Machining Process</h2>
<h2>Understanding CNC</h2>
<h3>What is shaft machining?</h3>
<h3>FAQ</h3>
<img src="test.jpg" alt="Shaft machining with CNC lathe">
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
h2_errors = [e for e in result.errors if "h2_total" in e.rule_name]
assert len(h2_errors) > 0
assert h2_errors[0].expected == 5
assert h2_errors[0].actual == 2
def test_tier_2_warning_only(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
sample_project.tier = 2
sample_project.h2_total = 5
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Shaft Machining with CNC</h1>
<h2>Shaft Machining Process</h2>
<h2>Understanding CNC</h2>
<h3>What is shaft machining?</h3>
<h3>FAQ</h3>
<img src="test.jpg" alt="Shaft machining with CNC lathe">
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
h2_warnings = [w for w in result.warnings if "h2_total" in w.rule_name]
assert len(h2_warnings) > 0
h2_errors = [e for e in result.errors if "h2_total" in e.rule_name]
assert len(h2_errors) == 0
def test_keyword_entity_counting(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Shaft Machining Basics</h1>
<h2>Shaft Machining Process</h2>
<h2>Understanding CNC Operations</h2>
<h2>Working with Precision Lathe</h2>
<h3>What is shaft machining?</h3>
<h3>CNC Techniques</h3>
<h3>FAQ</h3>
<img src="test.jpg" alt="Shaft machining with CNC">
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
parser = ContentHTMLParser()
parser.feed(html)
counts = engine._count_keyword_entities(parser, sample_project)
assert counts["h1_exact"] == 1
assert counts["h2_exact"] == 1
assert counts["h2_entities"] >= 2
assert counts["h3_exact"] == 1
def test_round_averages_down(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
sample_project.h2_total = 5.6
html = """
<html>
<head><title>Shaft Machining Guide</title></head>
<body>
<h1>Shaft Machining with CNC</h1>
<h2>Shaft Machining Process</h2>
<h2>Understanding CNC</h2>
<h2>Lathe Operations</h2>
<h2>Precision Work</h2>
<h2>Best Practices</h2>
<h3>What is shaft machining?</h3>
<h3>FAQ</h3>
<img src="test.jpg" alt="Shaft machining with CNC">
<p>""" + "word " * 1500 + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
h2_issues = [e for e in result.errors if "h2_total" in e.rule_name]
if h2_issues:
assert h2_issues[0].expected == 5
class TestValidContent:
"""Tests for content that should pass validation"""
def test_fully_compliant_content(self, mock_config, sample_project):
engine = ContentRuleEngine(mock_config)
html = """
<html>
<head><title>Complete Guide to Shaft Machining</title></head>
<body>
<h1>Shaft Machining: CNC Operations</h1>
<h2>Shaft Machining Process Explained</h2>
<p>Content about the main process...</p>
<h2>Understanding CNC Technology</h2>
<p>More content...</p>
<h2>Working with Precision Lathe</h2>
<p>Additional information...</p>
<h2>Shaft Machining Techniques</h2>
<p>Techniques details...</p>
<h2>Best Practices in CNC</h2>
<p>Best practices...</p>
<h3>What is shaft machining?</h3>
<p>Definition and explanation...</p>
<h3>CNC Lathe Operations</h3>
<p>Operations details...</p>
<h3>Precision Techniques</h3>
<p>Techniques information...</p>
<h3>Shaft Machining Process Guide</h3>
<p>Process details...</p>
<h3>Understanding Machining Techniques</h3>
<p>Techniques overview...</p>
<h3>CNC Setup and Shaft Machining Process</h3>
<p>Setup instructions...</p>
<h3>Lathe Maintenance for Machining Techniques</h3>
<p>Maintenance tips...</p>
<h3>FAQ: Common Questions about Shaft Machining</h3>
<p>Frequently asked questions...</p>
<img src="image1.jpg" alt="Shaft machining with CNC lathe">
<img src="image2.jpg" alt="Precision shaft machining setup">
<p>""" + " ".join(["shaft machining process details and information"] * 250) + """</p>
</body>
</html>
"""
result = engine.validate(html, sample_project)
assert result.passed is True
assert len(result.errors) == 0

View File

@ -1,189 +0,0 @@
"""
Unit tests for site page generator
"""
import pytest
from unittest.mock import Mock, MagicMock
from src.generation.site_page_generator import generate_site_pages, get_domain_from_site
from src.database.models import SiteDeployment, SitePage
def test_get_domain_from_site_with_custom_hostname():
site = Mock(spec=SiteDeployment)
site.custom_hostname = "www.example.com"
site.pull_zone_bcdn_hostname = "site123.b-cdn.net"
domain = get_domain_from_site(site)
assert domain == "www.example.com"
def test_get_domain_from_site_without_custom_hostname():
site = Mock(spec=SiteDeployment)
site.custom_hostname = None
site.pull_zone_bcdn_hostname = "site123.b-cdn.net"
domain = get_domain_from_site(site)
assert domain == "site123.b-cdn.net"
def test_generate_site_pages_success():
site = Mock(spec=SiteDeployment)
site.id = 1
site.custom_hostname = "www.example.com"
site.pull_zone_bcdn_hostname = "site123.b-cdn.net"
site.template_name = "modern"
page_repo = Mock()
page_repo.exists = Mock(return_value=False)
page_repo.create = Mock(return_value=Mock(spec=SitePage, id=1))
template_service = Mock()
template_service.format_content = Mock(return_value="<html>Full HTML Page</html>")
pages = generate_site_pages(site, page_repo, template_service)
assert len(pages) == 3
assert page_repo.create.call_count == 3
create_calls = page_repo.create.call_args_list
page_types_created = [call[1]["page_type"] for call in create_calls]
assert "about" in page_types_created
assert "contact" in page_types_created
assert "privacy" in page_types_created
def test_generate_site_pages_with_basic_template():
site = Mock(spec=SiteDeployment)
site.id = 2
site.custom_hostname = None
site.pull_zone_bcdn_hostname = "test-site.b-cdn.net"
site.template_name = "basic"
page_repo = Mock()
page_repo.exists = Mock(return_value=False)
page_repo.create = Mock(return_value=Mock(spec=SitePage, id=1))
template_service = Mock()
template_service.format_content = Mock(return_value="<html>Page</html>")
pages = generate_site_pages(site, page_repo, template_service)
assert len(pages) == 3
format_calls = template_service.format_content.call_args_list
for call in format_calls:
assert call[1]["template_name"] == "basic"
def test_generate_site_pages_skips_existing_pages():
site = Mock(spec=SiteDeployment)
site.id = 3
site.custom_hostname = "www.test.com"
site.template_name = "modern"
page_repo = Mock()
page_repo.exists = Mock(side_effect=[True, False, False])
page_repo.create = Mock(return_value=Mock(spec=SitePage, id=1))
template_service = Mock()
template_service.format_content = Mock(return_value="<html>Page</html>")
pages = generate_site_pages(site, page_repo, template_service)
assert len(pages) == 2
assert page_repo.create.call_count == 2
def test_generate_site_pages_uses_default_template_when_none():
site = Mock(spec=SiteDeployment)
site.id = 4
site.custom_hostname = "www.example.com"
site.template_name = None
page_repo = Mock()
page_repo.exists = Mock(return_value=False)
page_repo.create = Mock(return_value=Mock(spec=SitePage, id=1))
template_service = Mock()
template_service.format_content = Mock(return_value="<html>Page</html>")
pages = generate_site_pages(site, page_repo, template_service)
format_calls = template_service.format_content.call_args_list
for call in format_calls:
assert call[1]["template_name"] == "basic"
def test_generate_site_pages_correct_content_structure():
site = Mock(spec=SiteDeployment)
site.id = 5
site.custom_hostname = "www.test.com"
site.template_name = "modern"
page_repo = Mock()
page_repo.exists = Mock(return_value=False)
created_pages = []
def mock_create(**kwargs):
page = Mock(spec=SitePage, id=len(created_pages) + 1)
created_pages.append(kwargs)
return page
page_repo.create = mock_create
template_service = Mock()
template_service.format_content = Mock(return_value="<html>Full Page</html>")
pages = generate_site_pages(site, page_repo, template_service)
assert len(created_pages) == 3
for page_data in created_pages:
assert page_data["site_deployment_id"] == 5
assert page_data["page_type"] in ["about", "contact", "privacy"]
assert page_data["content"] == "<html>Full Page</html>"
def test_generate_site_pages_page_titles():
site = Mock(spec=SiteDeployment)
site.id = 6
site.custom_hostname = "www.test.com"
site.template_name = "basic"
page_repo = Mock()
page_repo.exists = Mock(return_value=False)
page_repo.create = Mock(return_value=Mock(spec=SitePage, id=1))
template_service = Mock()
template_service.format_content = Mock(return_value="<html>Page</html>")
pages = generate_site_pages(site, page_repo, template_service)
format_calls = template_service.format_content.call_args_list
titles_used = [call[1]["title"] for call in format_calls]
assert "About Us" in titles_used
assert "Contact" in titles_used
assert "Privacy Policy" in titles_used
def test_generate_site_pages_error_handling():
site = Mock(spec=SiteDeployment)
site.id = 7
site.custom_hostname = "www.test.com"
site.template_name = "modern"
page_repo = Mock()
page_repo.exists = Mock(return_value=False)
page_repo.create = Mock(side_effect=Exception("Database error"))
template_service = Mock()
template_service.format_content = Mock(return_value="<html>Page</html>")
with pytest.raises(Exception) as exc_info:
generate_site_pages(site, page_repo, template_service)
assert "Database error" in str(exc_info.value)