279 lines
9.0 KiB
Python
279 lines
9.0 KiB
Python
"""
|
|
Integration tests for template service with content generation
|
|
"""
|
|
|
|
import pytest
|
|
from unittest.mock import patch
|
|
from src.database.models import Project, User, GeneratedContent, SiteDeployment
|
|
from src.database.repositories import (
|
|
ProjectRepository,
|
|
GeneratedContentRepository,
|
|
SiteDeploymentRepository
|
|
)
|
|
from src.templating.service import TemplateService
|
|
from src.generation.service import ContentGenerator
|
|
from src.generation.ai_client import AIClient, PromptManager
|
|
|
|
|
|
@pytest.fixture
|
|
def test_user(db_session):
|
|
"""Create a test user"""
|
|
user = User(
|
|
username="testuser_template",
|
|
hashed_password="hashed",
|
|
role="User"
|
|
)
|
|
db_session.add(user)
|
|
db_session.commit()
|
|
return user
|
|
|
|
|
|
@pytest.fixture
|
|
def test_project(db_session, test_user):
|
|
"""Create a test project"""
|
|
project_data = {
|
|
"main_keyword": "template testing",
|
|
"word_count": 1000,
|
|
"term_frequency": 2,
|
|
"h2_total": 5,
|
|
"h2_exact": 1,
|
|
"h3_total": 8,
|
|
"h3_exact": 1,
|
|
"entities": ["entity1", "entity2"],
|
|
"related_searches": ["search1", "search2"]
|
|
}
|
|
|
|
project_repo = ProjectRepository(db_session)
|
|
project = project_repo.create(test_user.id, "Template Test Project", project_data)
|
|
|
|
return project
|
|
|
|
|
|
@pytest.fixture
|
|
def test_site_deployment(db_session):
|
|
"""Create a test site deployment"""
|
|
site_repo = SiteDeploymentRepository(db_session)
|
|
site = site_repo.create(
|
|
site_name="Test Site",
|
|
custom_hostname="test.example.com",
|
|
storage_zone_id=12345,
|
|
storage_zone_name="test-storage",
|
|
storage_zone_password="test-password",
|
|
storage_zone_region="DE",
|
|
pull_zone_id=67890,
|
|
pull_zone_bcdn_hostname="test.b-cdn.net"
|
|
)
|
|
return site
|
|
|
|
|
|
@pytest.fixture
|
|
def test_generated_content(db_session, test_project):
|
|
"""Create test generated content"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
content = content_repo.create(
|
|
project_id=test_project.id,
|
|
tier="tier1",
|
|
keyword="template testing",
|
|
title="Test Article About Template Testing",
|
|
outline={"outline": [{"h2": "Introduction", "h3": ["Overview", "Benefits"]}]},
|
|
content="<h2>Introduction</h2><p>This is test content.</p><h3>Overview</h3><p>More content here.</p>",
|
|
word_count=500,
|
|
status="generated"
|
|
)
|
|
return content
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_template_service_with_database(db_session):
|
|
"""Test TemplateService instantiation with database session"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
template_service = TemplateService(content_repo=content_repo)
|
|
|
|
assert template_service is not None
|
|
assert template_service.content_repo == content_repo
|
|
assert len(template_service.get_available_templates()) >= 4
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_format_content_end_to_end(db_session, test_generated_content):
|
|
"""Test formatting content and storing in database"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
template_service = TemplateService(content_repo=content_repo)
|
|
|
|
formatted = template_service.format_content(
|
|
content=test_generated_content.content,
|
|
title=test_generated_content.title,
|
|
meta_description="Test meta description",
|
|
template_name="basic"
|
|
)
|
|
|
|
assert "<!DOCTYPE html>" in formatted
|
|
assert test_generated_content.title in formatted
|
|
assert "Test meta description" in formatted
|
|
assert test_generated_content.content in formatted
|
|
|
|
test_generated_content.formatted_html = formatted
|
|
test_generated_content.template_used = "basic"
|
|
content_repo.update(test_generated_content)
|
|
|
|
retrieved = content_repo.get_by_id(test_generated_content.id)
|
|
assert retrieved.formatted_html is not None
|
|
assert retrieved.template_used == "basic"
|
|
assert "<!DOCTYPE html>" in retrieved.formatted_html
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_template_selection_with_site_deployment(
|
|
db_session,
|
|
test_generated_content,
|
|
test_site_deployment
|
|
):
|
|
"""Test template selection based on site deployment"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
site_repo = SiteDeploymentRepository(db_session)
|
|
template_service = TemplateService(content_repo=content_repo)
|
|
|
|
test_generated_content.site_deployment_id = test_site_deployment.id
|
|
content_repo.update(test_generated_content)
|
|
|
|
template_name = template_service.select_template_for_content(
|
|
site_deployment_id=test_site_deployment.id,
|
|
site_deployment_repo=site_repo
|
|
)
|
|
|
|
available = template_service.get_available_templates()
|
|
assert template_name in available
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_template_selection_without_site_deployment(db_session, test_generated_content):
|
|
"""Test random template selection when no site deployment"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
template_service = TemplateService(content_repo=content_repo)
|
|
|
|
template_name = template_service.select_template_for_content(
|
|
site_deployment_id=None,
|
|
site_deployment_repo=None
|
|
)
|
|
|
|
available = template_service.get_available_templates()
|
|
assert template_name in available
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_content_generator_apply_template(
|
|
db_session,
|
|
test_project,
|
|
test_generated_content
|
|
):
|
|
"""Test ContentGenerator.apply_template method"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
project_repo = ProjectRepository(db_session)
|
|
|
|
mock_ai_client = None
|
|
mock_prompt_manager = None
|
|
|
|
generator = ContentGenerator(
|
|
ai_client=mock_ai_client,
|
|
prompt_manager=mock_prompt_manager,
|
|
project_repo=project_repo,
|
|
content_repo=content_repo
|
|
)
|
|
|
|
success = generator.apply_template(test_generated_content.id)
|
|
|
|
assert success is True
|
|
|
|
retrieved = content_repo.get_by_id(test_generated_content.id)
|
|
assert retrieved.formatted_html is not None
|
|
assert retrieved.template_used is not None
|
|
assert "<!DOCTYPE html>" in retrieved.formatted_html
|
|
assert retrieved.title in retrieved.formatted_html
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_multiple_content_different_templates(db_session, test_project):
|
|
"""Test that multiple content items can use different templates"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
template_service = TemplateService(content_repo=content_repo)
|
|
|
|
content_items = []
|
|
for i in range(4):
|
|
content = content_repo.create(
|
|
project_id=test_project.id,
|
|
tier="tier1",
|
|
keyword=f"keyword {i}",
|
|
title=f"Test Article {i}",
|
|
outline={"outline": [{"h2": "Section", "h3": ["Sub"]}]},
|
|
content=f"<h2>Section {i}</h2><p>Content {i}</p>",
|
|
word_count=300,
|
|
status="generated"
|
|
)
|
|
content_items.append(content)
|
|
|
|
templates = ["basic", "modern", "classic", "minimal"]
|
|
|
|
for content, template_name in zip(content_items, templates):
|
|
formatted = template_service.format_content(
|
|
content=content.content,
|
|
title=content.title,
|
|
meta_description=f"Description {content.id}",
|
|
template_name=template_name
|
|
)
|
|
|
|
content.formatted_html = formatted
|
|
content.template_used = template_name
|
|
content_repo.update(content)
|
|
|
|
for content, expected_template in zip(content_items, templates):
|
|
retrieved = content_repo.get_by_id(content.id)
|
|
assert retrieved.template_used == expected_template
|
|
assert retrieved.formatted_html is not None
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_apply_template_with_missing_content(db_session, test_project):
|
|
"""Test apply_template with non-existent content ID"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
project_repo = ProjectRepository(db_session)
|
|
|
|
generator = ContentGenerator(
|
|
ai_client=None,
|
|
prompt_manager=None,
|
|
project_repo=project_repo,
|
|
content_repo=content_repo
|
|
)
|
|
|
|
success = generator.apply_template(content_id=99999)
|
|
|
|
assert success is False
|
|
|
|
|
|
@pytest.mark.integration
|
|
def test_formatted_html_storage(
|
|
db_session,
|
|
test_generated_content
|
|
):
|
|
"""Test that formatted HTML is correctly stored in database"""
|
|
content_repo = GeneratedContentRepository(db_session)
|
|
template_service = TemplateService(content_repo=content_repo)
|
|
|
|
formatted = template_service.format_content(
|
|
content=test_generated_content.content,
|
|
title=test_generated_content.title,
|
|
meta_description="Meta description",
|
|
template_name="modern"
|
|
)
|
|
|
|
test_generated_content.formatted_html = formatted
|
|
test_generated_content.template_used = "modern"
|
|
test_generated_content.site_deployment_id = None
|
|
|
|
updated = content_repo.update(test_generated_content)
|
|
|
|
retrieved = content_repo.get_by_id(test_generated_content.id)
|
|
assert retrieved.formatted_html == formatted
|
|
assert retrieved.template_used == "modern"
|
|
assert retrieved.site_deployment_id is None
|
|
|