zcbot/tests/test_office_to_pdf.py

101 lines
3.9 KiB
Python

from __future__ import annotations
import subprocess
import sys
import tempfile
import unittest
from pathlib import Path
from unittest.mock import patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1]))
from tools.office_to_pdf import OfficeToPdfTool
from tools import office_to_pdf as office_module
_ALL_FORMATS = frozenset({
".doc", ".docx", ".odt", ".xls", ".xlsx", ".ods", ".ppt", ".pptx", ".odp",
})
class TestOfficeToPdfTool(unittest.TestCase):
def _tool(self, root: Path, task: Path) -> OfficeToPdfTool:
return OfficeToPdfTool(base_dir=task, user_root=root)
def test_converts_container_path_on_host_and_publishes_requested_output(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
task = root / "task"
task.mkdir()
(task / "source.docx").write_bytes(b"docx")
def fake_run(cmd, **kwargs):
outdir = Path(cmd[cmd.index("--outdir") + 1])
(outdir / "source.pdf").write_bytes(b"%PDF-1.4 test")
return subprocess.CompletedProcess(cmd, 0, b"", b"")
with patch(
"tools.office_to_pdf.office_supported_suffixes", return_value=_ALL_FORMATS
), patch("tools.office_to_pdf.find_soffice", return_value="soffice"), patch(
"tools.office_to_pdf.subprocess.run", side_effect=fake_run
):
result = self._tool(root, task).execute(
source="task/source.docx",
output="task/converted/final.pdf",
)
out = task / "converted" / "final.pdf"
self.assertEqual(out.read_bytes(), b"%PDF-1.4 test")
self.assertIn("[OK] PDF created: task/converted/final.pdf", result)
def test_rejects_source_outside_user_workspace(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td) / "user"
task = root / "task"
task.mkdir(parents=True)
result = self._tool(root, task).execute(source="../../outside.docx")
self.assertIn("[Error] source path out of user workspace", result)
def test_rejects_non_office_source(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
task = root / "task"
task.mkdir()
(task / "notes.md").write_text("x", encoding="utf-8")
result = self._tool(root, task).execute(source="notes.md")
self.assertIn("[Error] unsupported Office format", result)
def test_reports_missing_writer_component_before_conversion(self):
with tempfile.TemporaryDirectory() as td:
root = Path(td)
task = root / "task"
task.mkdir()
(task / "legacy.doc").write_bytes(b"doc")
with patch(
"tools.office_to_pdf.office_supported_suffixes",
return_value=frozenset({".ppt", ".pptx", ".odp"}),
), patch("tools.office_to_pdf.subprocess.run") as run:
tool = self._tool(root, task)
result = tool.execute(source="legacy.doc")
self.assertIn("lacks the Writer component", result)
self.assertIn("PPT", tool.description)
self.assertNotIn("DOC,", tool.description)
run.assert_not_called()
def test_debian_component_detection_limits_advertised_formats(self):
office_module.office_supported_suffixes.cache_clear()
try:
with patch("tools.office_to_pdf.find_soffice", return_value="/usr/bin/soffice"), patch(
"tools.office_to_pdf._debian_office_families",
return_value=frozenset({"Impress"}),
):
supported = office_module.office_supported_suffixes()
self.assertEqual(supported, frozenset({".ppt", ".pptx", ".odp"}))
finally:
office_module.office_supported_suffixes.cache_clear()
if __name__ == "__main__":
unittest.main()