import copy import tempfile import unittest from pathlib import Path from unittest.mock import Mock, patch import pymupdf from copienator import EvaluationWorkspace, atomic_write_json, read_json from copienator.commands import correction, resolve_manual class ManualResolutionStateTests(unittest.TestCase): def test_acknowledgement_clears_only_this_target_and_copy(self): for error in ("wrg-lbl:B?", "wrg-lbl:B?delayed", "wrg-lbl:B?exists", "al:(->)B?(->)C?", "al:(delayed)B"): with self.subTest(error=error): source = {"id": "01", "result": {"error": error, "delayed": [ ["wrong-label", "B"], ["add-label", "B"], ["add-label", "C"]]}} other = {"id": "02", "result": {"error": error, "delayed": [["wrong-label", "B"]]}} before_other = copy.deepcopy(other) results = {"A": [[source, other]]} resolve_manual.set_suffix_and_clean_error(results, "01", "A", None, "B") self.assertEqual(source["result"]["delayed"], [["add-label", "C"]]) self.assertNotIn("B?", source["result"]["error"]) self.assertEqual(other, before_other) resolve_manual.set_suffix_and_clean_error(results, "01", "A", None, "C") self.assertNotIn("delayed", source["result"]) def fixture(self, root, operator): copies = root / "Copies" / "Copie01" copies.mkdir(parents=True) for label in ("A", "B"): with pymupdf.open() as doc: page = doc.new_page(width=200, height=200) page.insert_text((20, 40), label) doc.save(copies / f"{label}.pdf") atomic_write_json(root / "correction.json", { "A": [[{"id": "01", "result": {"error": "wrg-lbl:B?", "delayed": [["wrong-label", "B"]]}}]], "B": [[{"id": "01", "result": {"error": ""}}]], }) (root / "manual_resolutions.txt").write_text(f"Copie01 A {operator} B|\n") return EvaluationWorkspace(root) def test_every_resolution_acknowledges_pending_conflict(self): for operator in (*resolve_manual.OPERATORS, "c{50}1>", "c{50}2x"): with self.subTest(operator=operator), tempfile.TemporaryDirectory() as temporary: workspace = self.fixture(Path(temporary), operator) resolve_manual.resolve_manual(workspace) result = read_json(workspace.correction_file)["A"][0][0]["result"] self.assertNotIn("delayed", result) self.assertFalse(workspace.manual_resolutions_file.exists()) def test_refaire_does_not_recreate_a_resolved_source_conflict(self): with tempfile.TemporaryDirectory() as temporary: workspace = self.fixture(Path(temporary), "x>") resolve_manual.resolve_manual(workspace) (workspace.groups_dir / "B").mkdir(parents=True) args = correction.build_parser().parse_args([str(workspace.root), "--refaire"]) correction.configure_runtime(workspace, [], args, api_client=Mock()) with patch.object(correction.grouping, "get_pdf_height", return_value=400), patch.object( correction.grouping, "create_jpg" ), patch.object(correction, "process_single_task", return_value=[]): self.assertEqual(correction.run_configured(args), 0) self.assertFalse(workspace.manual_resolutions_file.exists()) self.assertNotIn("delayed", correction.results["A"][0][0]["result"])