| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199 |
- """细胞产品来源链质检 — 节点展平与编排"""
- import unittest
- from unittest.mock import MagicMock, patch
- from app.crud.cell_product import _flatten_lineage_nodes, get_product_lineage_qc
- class TestFlattenLineageNodes(unittest.TestCase):
- def test_current_only_when_no_ancestors(self):
- chain = {
- "current": {
- "id": "cp-cur",
- "productCode": "C-CUR",
- "productName": "当前",
- "nodeType": "cell_product",
- "passage": "P2",
- "isCurrent": True,
- },
- "ancestors": [],
- }
- nodes = _flatten_lineage_nodes(chain)
- self.assertEqual(len(nodes), 1)
- self.assertEqual(nodes[0]["id"], "cp-cur")
- self.assertTrue(nodes[0]["isCurrent"])
- def test_sample_then_parent_then_current_order(self):
- sample = {
- "id": "s1",
- "nodeType": "sample",
- "sampleCode": "YB001",
- "receptionSource": "cell_storage",
- "receptionSourceLabel": "细胞存储",
- }
- parent = {
- "id": "cp-p1",
- "productCode": "C-P1",
- "productName": "父代",
- "nodeType": "cell_product",
- "passage": "P1",
- "isCurrent": False,
- }
- current = {
- "id": "cp-cur",
- "productCode": "C-CUR",
- "productName": "当前",
- "nodeType": "cell_product",
- "passage": "P2",
- "isCurrent": True,
- }
- chain = {
- "current": current,
- "ancestors": [
- {
- "node": parent,
- "edge": {},
- "parent": {"node": sample, "edge": {}, "parent": None},
- }
- ],
- }
- nodes = _flatten_lineage_nodes(chain)
- self.assertEqual([n["id"] for n in nodes], ["s1", "cp-p1", "cp-cur"])
- self.assertEqual(nodes[0]["nodeType"], "sample")
- self.assertTrue(nodes[-1]["isCurrent"])
- def test_dedupe_same_node_type_and_id(self):
- parent = {
- "id": "cp-p1",
- "nodeType": "cell_product",
- "productCode": "C-P1",
- "productName": "父",
- "passage": "P1",
- "isCurrent": False,
- }
- current = {
- "id": "cp-cur",
- "nodeType": "cell_product",
- "productCode": "C-CUR",
- "productName": "当前",
- "passage": "P2",
- "isCurrent": True,
- }
- chain = {
- "current": current,
- "ancestors": [
- {"node": parent, "edge": {}, "parent": None},
- {"node": dict(parent), "edge": {}, "parent": None},
- ],
- }
- nodes = _flatten_lineage_nodes(chain)
- ids = [n["id"] for n in nodes]
- self.assertEqual(ids.count("cp-p1"), 1)
- self.assertEqual(ids[-1], "cp-cur")
- def test_parent_array_multi_input(self):
- s1 = {"id": "s1", "nodeType": "sample", "sampleCode": "A", "receptionSource": "cell_storage"}
- s2 = {"id": "s2", "nodeType": "sample", "sampleCode": "B", "receptionSource": "cell_storage"}
- parent = {
- "id": "cp-p1",
- "nodeType": "cell_product",
- "productCode": "P1",
- "productName": "父",
- "passage": "P1",
- "isCurrent": False,
- }
- current = {
- "id": "cp-cur",
- "nodeType": "cell_product",
- "productCode": "CUR",
- "productName": "当前",
- "passage": "P2",
- "isCurrent": True,
- }
- chain = {
- "current": current,
- "ancestors": [
- {
- "node": parent,
- "edge": {},
- "parent": [
- {"node": s1, "edge": {}, "parent": None},
- {"node": s2, "edge": {}, "parent": None},
- ],
- }
- ],
- }
- nodes = _flatten_lineage_nodes(chain)
- ids = [n["id"] for n in nodes]
- self.assertIn("s1", ids)
- self.assertIn("s2", ids)
- self.assertEqual(ids[-1], "cp-cur")
- class TestGetProductLineageQc(unittest.TestCase):
- @patch("app.crud.cell_product.get_product_chain")
- @patch("app.crud.cell_product._load_lineage_qc_for_nodes")
- def test_missing_product_returns_none(self, _load, get_chain):
- get_chain.return_value = None
- db = MagicMock()
- self.assertIsNone(get_product_lineage_qc(db, "missing", "zkxw"))
- _load.assert_not_called()
- @patch("app.crud.cell_product.get_product_chain")
- @patch("app.crud.cell_product._load_lineage_qc_for_nodes")
- def test_returns_product_header_and_nodes(self, load_nodes, get_chain):
- get_chain.return_value = {
- "current": {
- "id": "cp1",
- "productCode": "C1",
- "productName": "产品1",
- "nodeType": "cell_product",
- "passage": "P1",
- "isCurrent": True,
- },
- "ancestors": [],
- }
- load_nodes.return_value = [
- {
- "nodeType": "cell_product",
- "id": "cp1",
- "label": "C1",
- "productName": "产品1",
- "passage": "P1",
- "receptionSource": None,
- "isCurrent": True,
- "workOrders": [
- {
- "id": "wo1",
- "workOrderNo": "WO1",
- "workOrderType": "temporary",
- "workOrderStatus": "ywc",
- "workOrderStatusLabel": "已完成",
- "tasks": [
- {
- "id": "t1",
- "taskNo": "T1",
- "itemName": "无菌",
- "results": [{"paramName": "结果", "paramValue": "阴性"}],
- "attachmentFiles": [],
- "remark": "",
- "conclusion": "tg",
- }
- ],
- }
- ],
- }
- ]
- db = MagicMock()
- out = get_product_lineage_qc(db, "cp1", "zkxw")
- self.assertEqual(out["productId"], "cp1")
- self.assertEqual(out["productCode"], "C1")
- self.assertEqual(len(out["nodes"]), 1)
- self.assertEqual(
- out["nodes"][0]["workOrders"][0]["tasks"][0]["results"][0]["paramValue"],
- "阴性",
- )
- if __name__ == "__main__":
- unittest.main()
|