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 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.find_soffice", return_value="soffice"), patch( "tools.office_to_pdf.subprocess.run", side_effect=fake_run ): result = self._tool(root, task).execute( source="/workspace/task/source.docx", output="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) if __name__ == "__main__": unittest.main()