#!/usr/bin/env python3 from __future__ import annotations import tempfile import unittest from pathlib import Path from unittest.mock import patch from redmine_ticket_entities import extract_entities from redmine_tickets import ( is_closed_status, maybe_convert_to_textile, resolve_body_text, build_parser, inject_default_sync_command, ) import argparse class OpenOnlyTest(unittest.TestCase): def test_closed(self): self.assertTrue(is_closed_status({"status": {"name": "Closed", "is_closed": True}})) self.assertTrue(is_closed_status({"status": {"name": "Closed"}})) self.assertFalse(is_closed_status({"status": {"name": "New"}})) class EntityTightenTest(unittest.TestCase): def test_item_no_and_noise(self): text = "Order ID: 1013179 UPS 1ZT33T62A898848403 item 212345678 SKU-ABC-99 order-mode responsive-title" ents = extract_entities(text) types = {e["type"]: e["value"] for e in ents} self.assertEqual("1ZT33T62A898848403", types.get("tracking_ups")) self.assertIn("order_id", types) self.assertEqual("1013179", types["order_id"]) self.assertEqual("212345678", types.get("item_no")) # HTML noise should not become order_id values = [e["value"] for e in ents if e["type"] == "order_id"] self.assertNotIn("responsive-title", values) self.assertNotIn("lation-mode", values) class BodyFileTextileTest(unittest.TestCase): def test_body_file(self): with tempfile.TemporaryDirectory() as td: p = Path(td) / "note.md" p.write_text("# Hello\n\nWorld", encoding="utf-8") ns = argparse.Namespace(body=None, body_file=p, to_textile=False) self.assertIn("Hello", resolve_body_text(ns)) def test_to_textile_without_pandoc(self): with patch("shutil.which", return_value=None): out = maybe_convert_to_textile("plain") self.assertEqual("plain", out) class CliFlagsTest(unittest.TestCase): def test_flags(self): args = build_parser().parse_args( inject_default_sync_command( [ "search", "--open-only", "--where", "assigned_to IS NULL", "--max-tickets", "5", ] ) ) self.assertTrue(args.open_only) args2 = build_parser().parse_args( inject_default_sync_command( ["browse", "--open-only", "--no-preview", "--once"] ) ) self.assertTrue(args2.open_only) self.assertTrue(args2.no_preview) args3 = build_parser().parse_args( inject_default_sync_command( [ "note", "--issue-id", "1", "--body-file", "/tmp/x", "--to-textile", "--private", ] ) ) self.assertTrue(args3.to_textile) if __name__ == "__main__": unittest.main()