test_oa_initiator_select_by_node.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. """OA 发起人自选:按节点 map"""
  2. import unittest
  3. from unittest.mock import MagicMock, patch
  4. from app.services.oa_engine import (
  5. OaEngineError,
  6. _create_tasks_for_node,
  7. _ids_for_initiator_select_node,
  8. _normalize_initiator_select_by_node,
  9. )
  10. class TestNormalizeMap(unittest.TestCase):
  11. def test_normalize_dedupe_preserve_order(self):
  12. raw = {"n1": ["u1", "u1", " u2 ", ""], "n2": "bad"}
  13. out = _normalize_initiator_select_by_node(raw)
  14. self.assertEqual(out["n1"], ["u1", "u2"])
  15. self.assertNotIn("n2", out)
  16. def test_ids_for_node(self):
  17. m = {"a1": ["u9"]}
  18. self.assertEqual(_ids_for_initiator_select_node(m, "a1"), ["u9"])
  19. self.assertEqual(_ids_for_initiator_select_node(m, "missing"), [])
  20. class TestCreateTasksInitiatorSelect(unittest.TestCase):
  21. def _inst(self):
  22. inst = MagicMock()
  23. inst.id = "inst1"
  24. inst.tenant_no = "zkxw"
  25. inst.initiator_user_id = "init"
  26. inst.initiator_dept_id = "d1"
  27. inst.current_round = 1
  28. return inst
  29. def test_cc_empty_skips_without_resolve(self):
  30. db = MagicMock()
  31. node = {
  32. "id": "cc1",
  33. "type": "cc",
  34. "name": "抄送人",
  35. "approverConfig": {"assigneeType": "initiator_select"},
  36. }
  37. ver = MagicMock()
  38. ver.advanced_settings_json = "{}"
  39. with patch(
  40. "app.services.oa_engine.resolve_cc_assignees",
  41. return_value=([], {"resolve_source": "", "skipped": [{"type": "initiator_select"}]}),
  42. ) as resolve:
  43. created = _create_tasks_for_node(
  44. db,
  45. inst=self._inst(),
  46. node=node,
  47. ver=ver,
  48. user_id="init",
  49. initiator_select_by_node={},
  50. )
  51. resolve.assert_called_once()
  52. self.assertEqual(created, [])
  53. def test_approval_empty_raises(self):
  54. db = MagicMock()
  55. node = {
  56. "id": "a1",
  57. "type": "approval",
  58. "name": "审批人",
  59. "approverConfig": {"assigneeType": "initiator_select", "signMode": "or"},
  60. }
  61. ver = MagicMock()
  62. ver.advanced_settings_json = "{}"
  63. with self.assertRaises(OaEngineError):
  64. _create_tasks_for_node(
  65. db,
  66. inst=self._inst(),
  67. node=node,
  68. ver=ver,
  69. user_id="init",
  70. initiator_select_by_node={"a1": []},
  71. )
  72. def test_approval_uses_node_ids(self):
  73. db = MagicMock()
  74. node = {
  75. "id": "a1",
  76. "type": "approval",
  77. "name": "审批人",
  78. "approverConfig": {"assigneeType": "initiator_select", "signMode": "or"},
  79. }
  80. ver = MagicMock()
  81. ver.advanced_settings_json = "{}"
  82. with patch(
  83. "app.services.oa_engine.resolve_assignees",
  84. return_value=(["u1"], {"resolve_source": "initiator_select"}),
  85. ) as resolve:
  86. with patch("app.services.oa_engine.generate_uuid", return_value="t1"):
  87. with patch("app.services.oa_engine._next_task_order_num", return_value=1):
  88. created = _create_tasks_for_node(
  89. db,
  90. inst=self._inst(),
  91. node=node,
  92. ver=ver,
  93. user_id="init",
  94. initiator_select_by_node={"a1": ["u1"], "other": ["u9"]},
  95. )
  96. self.assertEqual(len(created), 1)
  97. kwargs = resolve.call_args.kwargs
  98. self.assertEqual(kwargs.get("initiator_select_user_ids"), ["u1"])
  99. if __name__ == "__main__":
  100. unittest.main()