Big-Link-Man/tests/integration/test_template_integration.py

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