108 lines
3.9 KiB
Python
108 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
from __future__ import annotations
|
|
|
|
import tempfile
|
|
import unittest
|
|
from pathlib import Path
|
|
|
|
from redmine_ticket_drafts import (
|
|
KIND_CUSTOMER_EMAIL,
|
|
KIND_INTERNAL_NOTE,
|
|
add_draft,
|
|
assert_write_target_allowed,
|
|
host_is_safe_for_writes,
|
|
kind_label,
|
|
list_drafts,
|
|
load_draft,
|
|
mark_draft_applied,
|
|
normalize_kind,
|
|
)
|
|
|
|
|
|
class DraftKindsTest(unittest.TestCase):
|
|
def test_normalize_legacy(self):
|
|
self.assertEqual(KIND_INTERNAL_NOTE, normalize_kind("note"))
|
|
self.assertEqual(KIND_CUSTOMER_EMAIL, normalize_kind("helpdesk_reply"))
|
|
|
|
def test_customer_email_cannot_be_private(self):
|
|
with tempfile.TemporaryDirectory() as td:
|
|
with self.assertRaises(ValueError):
|
|
add_draft(Path(td), issue_id=1, kind=KIND_CUSTOMER_EMAIL, body="hi", private=True)
|
|
|
|
def test_labels_are_explicit(self):
|
|
self.assertIn("NOT email", kind_label(KIND_INTERNAL_NOTE))
|
|
self.assertIn("WILL email", kind_label(KIND_CUSTOMER_EMAIL))
|
|
|
|
def test_queue_and_list(self):
|
|
with tempfile.TemporaryDirectory() as td:
|
|
root = Path(td)
|
|
p = add_draft(root, issue_id=42, kind=KIND_INTERNAL_NOTE, body="staff only", private=True)
|
|
self.assertTrue(p.is_file())
|
|
items = list_drafts(root, status="pending")
|
|
self.assertEqual(1, len(items))
|
|
self.assertFalse(items[0].get("emails_customer"))
|
|
p2 = add_draft(root, issue_id=43, kind=KIND_CUSTOMER_EMAIL, body="hello customer")
|
|
items = list_drafts(root, status="pending")
|
|
self.assertEqual(2, len(items))
|
|
cust = [i for i in items if i["kind"] == KIND_CUSTOMER_EMAIL][0]
|
|
self.assertTrue(cust.get("emails_customer"))
|
|
mark_draft_applied(root, cust["id"], result={"ok": True})
|
|
pending = list_drafts(root, status="pending")
|
|
self.assertEqual(1, len(pending))
|
|
|
|
def test_write_target_safety(self):
|
|
self.assertTrue(host_is_safe_for_writes("http://192.168.50.170/"))
|
|
self.assertTrue(host_is_safe_for_writes("http://retired.int.ldrprep.com"))
|
|
self.assertFalse(host_is_safe_for_writes("https://rm.ldrprep.com"))
|
|
with self.assertRaises(RuntimeError):
|
|
assert_write_target_allowed("https://rm.ldrprep.com", allow_prod_writes=False)
|
|
assert_write_target_allowed("https://rm.ldrprep.com", allow_prod_writes=True)
|
|
assert_write_target_allowed("http://192.168.50.170", allow_prod_writes=False)
|
|
|
|
|
|
class CliParseSafetyTest(unittest.TestCase):
|
|
def test_customer_email_requires_confirm_flag(self):
|
|
from redmine_tickets import build_parser, inject_default_sync_command
|
|
|
|
parser = build_parser()
|
|
# Missing mandatory confirm flag should fail parse
|
|
with self.assertRaises(SystemExit):
|
|
parser.parse_args(
|
|
inject_default_sync_command(
|
|
[
|
|
"--project",
|
|
"customer-service",
|
|
"customer-email",
|
|
"--issue-id",
|
|
"1",
|
|
"--body",
|
|
"hi",
|
|
]
|
|
)
|
|
)
|
|
|
|
def test_note_command_exists(self):
|
|
from redmine_tickets import build_parser, inject_default_sync_command
|
|
|
|
args = build_parser().parse_args(
|
|
inject_default_sync_command(
|
|
[
|
|
"--project",
|
|
"customer-service",
|
|
"note",
|
|
"--issue-id",
|
|
"1",
|
|
"--body",
|
|
"internal only",
|
|
"--private",
|
|
]
|
|
)
|
|
)
|
|
self.assertEqual("note", args.command)
|
|
self.assertTrue(args.private)
|
|
self.assertFalse(args.apply)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|