"""Report engine unit tests (FASE-2.1).""" import os import sys from unittest.mock import MagicMock import pytest from app.services.report_engine import ReportEngine @pytest.fixture def engine(tmp_path, monkeypatch): templates = tmp_path / "templates" styles = templates / "styles" styles.mkdir(parents=True) (styles / "report.css").write_text("body { color: #0e7490; }", encoding="utf-8") (templates / "coverage_report.html").write_text( "

{{ company_name }}

{{ score }}

", encoding="utf-8", ) out_dir = tmp_path / "out" monkeypatch.setattr("app.services.report_engine.settings.REPORT_TEMPLATES_DIR", str(templates)) monkeypatch.setattr("app.services.report_engine.settings.REPORT_OUTPUT_DIR", str(out_dir)) monkeypatch.setattr("app.services.report_engine.settings.COMPANY_NAME", "Test Org") return ReportEngine() def test_render_html_injects_company_and_timestamp(engine): html = engine.render_html("coverage_report", {"score": 42}) assert "Test Org" in html assert "42" in html def test_generate_pdf_writes_file(engine, monkeypatch, tmp_path): """WeasyPrint is stubbed so tests run without GTK/Pango system libraries.""" def _write_pdf(output_path, stylesheets=None): with open(output_path, "wb") as f: f.write(b"%PDF-1.4 mock") mock_html_instance = MagicMock() mock_html_instance.write_pdf.side_effect = _write_pdf mock_wp = MagicMock() mock_wp.HTML.return_value = mock_html_instance mock_wp.CSS = MagicMock() for key in list(sys.modules): if key == "weasyprint" or key.startswith("weasyprint."): monkeypatch.delitem(sys.modules, key, raising=False) monkeypatch.setitem(sys.modules, "weasyprint", mock_wp) path = engine.generate_pdf("coverage_report", {"score": 99}) assert path.endswith(".pdf") assert os.path.isfile(path) mock_html_instance.write_pdf.assert_called_once() def test_generate_html_file_writes_file(engine): path = engine.generate_html("coverage_report", {"score": 7}) assert path.endswith(".html") assert os.path.isfile(path) with open(path, encoding="utf-8") as f: assert "Test Org" in f.read()