Register type=dept on main app and oa-fc-host, with PC tree-select and
narrow drawer pickers storing {id,name} path snapshots; format dept values
in print and related-summary flatten.
Co-authored-by: Cursor <cursoragent@cursor.com>
132 lines
5.2 KiB
Python
132 lines
5.2 KiB
Python
import unittest
|
|
|
|
from app.services.oa_related_approval import (
|
|
extract_related_approval_links,
|
|
flatten_form_fields_for_summary,
|
|
merge_relation_targets,
|
|
)
|
|
|
|
|
|
class TestFlatten(unittest.TestCase):
|
|
def test_skips_layout_and_summarizes_upload(self):
|
|
schema = {
|
|
"rule": [
|
|
{"type": "html", "title": "说明"},
|
|
{"type": "input", "field": "reason", "title": "事由"},
|
|
{"type": "upload", "field": "files", "title": "附件"},
|
|
{"type": "relatedApproval", "field": "prev", "title": "关联"},
|
|
{"type": "textarea", "field": "long", "title": "详细说明"},
|
|
]
|
|
}
|
|
data = {
|
|
"reason": "出差",
|
|
"files": ["https://cdn.example.com/a.png", "https://cdn.example.com/b.png"],
|
|
"prev": ["id1", "id2"],
|
|
"long": "很长很长的说明文字" * 5,
|
|
}
|
|
fields = flatten_form_fields_for_summary(schema, data)
|
|
labels = [f["label"] for f in fields]
|
|
self.assertNotIn("说明", labels)
|
|
self.assertEqual(fields[0], {"label": "事由", "value": "出差"})
|
|
self.assertEqual(
|
|
fields[1]["value"],
|
|
"https://cdn.example.com/a.png、https://cdn.example.com/b.png",
|
|
)
|
|
self.assertTrue(fields[1].get("fullWidth"))
|
|
self.assertEqual(fields[2]["value"], "已关联 2 条")
|
|
self.assertEqual(fields[2].get("relatedIds"), ["id1", "id2"])
|
|
self.assertTrue(fields[3].get("fullWidth"))
|
|
|
|
def test_dept_formats_path_names(self):
|
|
schema = {
|
|
"rule": [
|
|
{"type": "dept", "field": "dept", "title": "部门"},
|
|
{
|
|
"type": "dept",
|
|
"field": "depts",
|
|
"title": "多部门",
|
|
"props": {"multiple": True},
|
|
},
|
|
]
|
|
}
|
|
data = {
|
|
"dept": {"id": "d1", "name": "中科兴皖 / 研发"},
|
|
"depts": [
|
|
{"id": "d1", "name": "中科兴皖 / 研发"},
|
|
{"id": "d2", "name": "中科兴皖 / 质量"},
|
|
],
|
|
}
|
|
fields = flatten_form_fields_for_summary(schema, data)
|
|
by_label = {f["label"]: f["value"] for f in fields}
|
|
self.assertEqual(by_label["部门"], "中科兴皖 / 研发")
|
|
self.assertEqual(by_label["多部门"], "中科兴皖 / 研发、中科兴皖 / 质量")
|
|
|
|
def test_related_approval_field_includes_related_ids(self):
|
|
schema = {
|
|
"rule": [
|
|
{"type": "input", "field": "reason", "title": "事由"},
|
|
{"type": "relatedApproval", "field": "prev", "title": "关联审批单"},
|
|
]
|
|
}
|
|
data = {"reason": "拜访", "prev": ["id1", "", "id2", "id1"]}
|
|
fields = flatten_form_fields_for_summary(schema, data)
|
|
rel = next(f for f in fields if f["label"] == "关联审批单")
|
|
self.assertEqual(rel["value"], "已关联 2 条")
|
|
self.assertEqual(rel["relatedIds"], ["id1", "id2"])
|
|
|
|
def test_related_approval_empty_ids(self):
|
|
schema = {"rule": [{"type": "relatedApproval", "field": "prev", "title": "关联"}]}
|
|
fields = flatten_form_fields_for_summary(schema, {"prev": []})
|
|
self.assertEqual(fields[0]["value"], "已关联 0 条")
|
|
self.assertEqual(fields[0]["relatedIds"], [])
|
|
|
|
def test_upload_object_list_extracts_url(self):
|
|
schema = {"rule": [{"type": "upload", "field": "files", "title": "附件"}]}
|
|
data = {
|
|
"files": [
|
|
{"name": "a.pdf", "url": "https://cdn.example.com/a.pdf"},
|
|
{"name": "b.pdf", "response": {"data": {"fileUrl": "/mini/b.pdf"}}},
|
|
]
|
|
}
|
|
fields = flatten_form_fields_for_summary(schema, data)
|
|
self.assertEqual(
|
|
fields[0]["value"],
|
|
"https://cdn.example.com/a.pdf、/mini/b.pdf",
|
|
)
|
|
|
|
def test_extract_links_with_field_key_and_dedupe(self):
|
|
schema = {
|
|
"rule": [
|
|
{"type": "relatedApproval", "field": "relA"},
|
|
{
|
|
"type": "fcRow",
|
|
"children": [{"type": "relatedApproval", "field": "relB"}],
|
|
},
|
|
]
|
|
}
|
|
data = {"relA": ["x", "x", ""], "relB": "solo"}
|
|
links = extract_related_approval_links(schema, data)
|
|
self.assertEqual(links, [("relA", "x"), ("relB", "solo")])
|
|
|
|
|
|
class TestValidateLinkable(unittest.TestCase):
|
|
def test_rejects_non_completed(self):
|
|
from app.services.oa_related_approval import assert_linkable_instance
|
|
from app.services.oa_engine import OaEngineError
|
|
from unittest.mock import MagicMock
|
|
|
|
inst = MagicMock(status="running", initiator_user_id="u1", tenant_no="t", del_flag=0)
|
|
with self.assertRaises(OaEngineError):
|
|
assert_linkable_instance(inst, user_id="u1", tenant_no="t")
|
|
|
|
|
|
class TestMergeRelationTargets(unittest.TestCase):
|
|
def test_merge_prefers_form_fields(self):
|
|
schema = {"rule": [{"type": "relatedApproval", "field": "r1"}]}
|
|
m = merge_relation_targets(schema, {"r1": ["a"]}, ["a", "b"])
|
|
self.assertEqual(m, [("r1", "a"), (None, "b")])
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|