""" Tests for Issue #132: Template System and CSS Injection This module tests template selection and custom CSS injection functionality for client-side markdown rendering. """ import pytest import tempfile import os from pathlib import Path from unittest.mock import patch, MagicMock import json # Add project root to path for imports import sys project_root = Path(__file__).parent.parent.parent.parent sys.path.insert(0, str(project_root)) class TestIssue132TemplateSystem: """Test template selection and CSS injection functionality.""" def setup_method(self): """Set up test environment.""" # Create temporary directory for test outputs self.temp_dir = tempfile.mkdtemp() self.markdown_content = """# Template Test This is a test document for template system validation. ## Features - Multiple templates - Custom CSS support - Responsive design """ def teardown_method(self): """Clean up test environment.""" # Clean up temporary files import shutil shutil.rmtree(self.temp_dir, ignore_errors=True) def test_default_template_generates_basic_html(self): """Test that default template generates basic HTML structure - Issue #132.""" input_file = Path(self.temp_dir) / "default.md" input_file.write_text(self.markdown_content) output_file = Path(self.temp_dir) / "default.html" # Template system IS implemented - test actual functionality from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file) ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # Should contain basic HTML5 structure assert '' in html_content assert '' in html_content assert '' in html_content def test_github_template_option(self): """Test GitHub-style template selection - Issue #132.""" input_file = Path(self.temp_dir) / "github.md" input_file.write_text(self.markdown_content) output_file = Path(self.temp_dir) / "github.html" # Template system IS implemented - test GitHub template from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file), '--theme', 'github' ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() assert 'border-bottom: 1px solid #d0d7de' in html_content # GitHub heading style def test_template_loading_from_filesystem(self): """Test template system uses embedded templates - Issue #132.""" # Templates are embedded in code, not loaded from filesystem # Test that template system provides all expected templates from markitect.plugins.builtin.markdown_commands import TEMPLATE_STYLES # Should have all expected templates available expected_templates = ['basic', 'github', 'academic', 'dark'] for template_name in expected_templates: assert template_name in TEMPLATE_STYLES template_config = TEMPLATE_STYLES[template_name] # Each template should have required style properties assert 'body_color' in template_config assert 'font_family' in template_config assert 'max_width' in template_config # Test that templates are properly formatted with variable placeholders from markitect.plugins.builtin.markdown_commands import generate_html_with_embedded_markdown test_html = generate_html_with_embedded_markdown("# Test", "Test Title", "basic", "", {}) # HTML template should be properly formatted assert '<!DOCTYPE html>' in test_html assert 'Test Title' in test_html assert '# Test' in test_html def test_template_variable_substitution(self): """Test template variable substitution system - Issue #132.""" input_file = Path(self.temp_dir) / "variables.md" input_file.write_text("# Variable Test\n\nTesting substitution.") output_file = Path(self.temp_dir) / "variables.html" # Template engine IS implemented - test actual functionality from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file) ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # Variables should be substituted with actual values assert '{{ markdown_json }}' not in html_content # Should be replaced assert '{{ title }}' not in html_content # Should be replaced assert '{{ css_content }}' not in html_content # Should be replaced # Should contain actual markdown content as JSON assert '# Variable Test' in html_content def test_custom_css_injection(self): """Test custom CSS injection into templates - Issue #132.""" custom_css = """ body { font-family: 'Comic Sans MS', cursive; background-color: #f0f0f0; } .markdown-content { max-width: 800px; margin: 0 auto; } """ # Create CSS file css_file = Path(self.temp_dir) / "custom.css" css_file.write_text(custom_css) input_file = Path(self.temp_dir) / "styled.md" input_file.write_text(self.markdown_content) output_file = Path(self.temp_dir) / "styled.html" # CSS injection IS implemented - test actual functionality from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file), '--css', str(css_file) ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # Custom CSS should be injected assert 'Comic Sans MS' in html_content assert 'background-color: #f0f0f0' in html_content def test_css_content_embedded_in_html(self): """Test that CSS content is properly embedded in HTML - Issue #132.""" custom_css = "body { color: red; }" css_file = Path(self.temp_dir) / "red.css" css_file.write_text(custom_css) input_file = Path(self.temp_dir) / "red_test.md" input_file.write_text("# Red Test\n\nShould be red text.") output_file = Path(self.temp_dir) / "red_test.html" # CSS embedding IS implemented - test actual functionality from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file), '--css', str(css_file) ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # CSS should be embedded in <style> tags assert '<style>' in html_content assert 'body { color: red; }' in html_content assert '</style>' in html_content def test_template_with_markdown_parser_integration(self): """Test template integration with JavaScript markdown parser - Issue #132.""" input_file = Path(self.temp_dir) / "integration.md" input_file.write_text("# Integration Test\n\nTesting parser integration.") output_file = Path(self.temp_dir) / "integration.html" # Integration IS implemented - test actual functionality from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file) ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # Should contain markdown parser script assert 'marked.min.js' in html_content assert 'marked.parse' in html_content assert 'Integration Test' in html_content # Should contain rendering JavaScript assert 'DOMContentLoaded' in html_content assert 'getElementById' in html_content assert 'innerHTML' in html_content def test_multiple_templates_available(self): """Test that multiple template options are available - Issue #132.""" # Test template availability theme_options = ['basic', 'github', 'academic', 'dark'] from markitect.plugins.builtin.markdown_commands import md_render_command from click.testing import CliRunner # Create test markdown file input_file = Path(self.temp_dir) / "template_test.md" input_file.write_text("# Template Test\n\nTesting multiple templates.") runner = CliRunner() for theme in theme_options: output_file = Path(self.temp_dir) / f"{theme}_output.html" result = runner.invoke(md_render_command, [ str(input_file), '--output', str(output_file), '--theme', theme ]) # Should be able to specify different templates assert result.exit_code == 0 assert output_file.exists() # Verify template-specific styling html_content = output_file.read_text() assert '<title>Template Test' in html_content def test_dark_theme_template_specific_styling(self): """Test that dark theme has appropriate dark styling - Issue #132.""" input_file = Path(self.temp_dir) / "dark_test.md" input_file.write_text("# Dark Theme Test\n\n> Blockquote test\n\n```code block```") output_file = Path(self.temp_dir) / "dark_test.html" from markitect.plugins.builtin.markdown_commands import md_render_command from click.testing import CliRunner runner = CliRunner() result = runner.invoke(md_render_command, [ str(input_file), '--output', str(output_file), '--theme', 'dark' ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # Verify dark theme specific colors assert 'background-color: #0d1117' in html_content # Dark background assert 'color: #e1e4e8' in html_content # Light text assert 'color: #58a6ff' in html_content # Blue headings assert 'background-color: #161b22' in html_content # Dark code blocks assert 'border-left: 4px solid #58a6ff' in html_content # Blue blockquote border def test_invalid_template_handling(self): """Test error handling for invalid template names - Issue #132.""" input_file = Path(self.temp_dir) / "invalid.md" input_file.write_text("# Invalid Template Test") # Error handling IS implemented - test invalid template from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--theme', 'nonexistent_template' ]) # Should exit with error code for invalid template choice assert result.exit_code != 0 assert ('invalid choice' in result.output.lower() or 'not one of' in result.output.lower() or 'unknown theme' in result.output.lower()) def test_template_title_extraction_from_markdown(self): """Test title extraction from markdown for template variables - Issue #132.""" markdown_with_title = """# Main Title This document should use "Main Title" as the HTML title. """ input_file = Path(self.temp_dir) / "title_test.md" input_file.write_text(markdown_with_title) output_file = Path(self.temp_dir) / "title_test.html" # Title extraction IS implemented - test actual functionality from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file) ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # HTML title should be extracted from first heading assert 'Main Title' in html_content def test_responsive_template_css(self): """Test that default templates include responsive CSS - Issue #132.""" input_file = Path(self.temp_dir) / "responsive.md" input_file.write_text("# Responsive Test\n\nTesting responsive design.") output_file = Path(self.temp_dir) / "responsive.html" # Responsive CSS IS implemented - test actual functionality from markitect.cli import cli from click.testing import CliRunner runner = CliRunner() result = runner.invoke(cli, [ 'md-render', str(input_file), '--output', str(output_file) ]) assert result.exit_code == 0 assert output_file.exists() html_content = output_file.read_text() # Should include viewport meta tag assert '