#!/usr/bin/env python3 from __future__ import annotations import tempfile import unittest from pathlib import Path from redmine_ticket_ocr import ( build_ocr_note, extract_text_from_file, looks_like_generic_scan_subject, suggest_subject_from_text, ) from redmine_tickets import KNOWN_COMMANDS, build_parser, inject_default_sync_command, is_closed_status class OcrSuggestTest(unittest.TestCase): def test_generic_subject(self): self.assertTrue(looks_like_generic_scan_subject("Scanned document from HP")) self.assertFalse(looks_like_generic_scan_subject("Invoice — Acme Corp")) def test_suggest_w2(self): text = "Form W-2 Wage and Tax Statement\nName: Jane Doe\nCompany: Acme LLC\nJanuary 15, 2026" subj = suggest_subject_from_text(text, original_subject="Scanned document") self.assertIn("W-2", subj) self.assertIn("Jane Doe", subj) def test_suggest_vendor_invoice_skips_fee_bullet(self): text = ( "- Return Check Fee up to $45.00\n" "- A 1.5% Service Charge, 18% Annually ($1.00 Minimum) will be charged\n" "Best Way Disposal\n" "Invoice Number: 2404778\n" "Invoice Due Date 9/25/2026\n" "Total Due $307.52\n" ) subj = suggest_subject_from_text(text, original_subject="Scanned document from LDR Office") self.assertIn("Invoice 2404778", subj) self.assertIn("Best Way Disposal", subj) self.assertNotIn("Return Check Fee", subj) def test_txt_extract(self): with tempfile.TemporaryDirectory() as td: p = Path(td) / "a.txt" p.write_text("hello ocr world " * 5, encoding="utf-8") text, method = extract_text_from_file(p) self.assertEqual("read", method) self.assertIn("hello", text) def test_note_builder(self): note = build_ocr_note( issue_id=1, files=[{"filename": "a.pdf", "method": "pdftotext", "text": "body"}], proposed_subject="Invoice — X", ) self.assertIn("proposed_subject: Invoice — X", note) self.assertIn("a.pdf", note) class CliRegistrationTest(unittest.TestCase): def test_commands(self): self.assertIn("ocr-rename", KNOWN_COMMANDS) self.assertIn("categories", KNOWN_COMMANDS) args = build_parser().parse_args( inject_default_sync_command( ["ocr-rename", "--issue-id", "1", "--no-queue-note", "--no-queue-subject"] ) ) self.assertEqual("ocr-rename", args.command) args2 = build_parser().parse_args( inject_default_sync_command(["categories", "list", "--refresh"]) ) self.assertEqual("categories", args2.command) args3 = build_parser().parse_args( inject_default_sync_command(["walk", "--open-only", "--max-tickets", "3"]) ) self.assertTrue(args3.open_only) if __name__ == "__main__": unittest.main()