test_cell_product_chain.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. """细胞产品来源链路 — 科研捐赠样本解析与多进一回归"""
  2. import unittest
  3. from unittest.mock import MagicMock, patch
  4. from app.crud.cell_product import (
  5. _ancestor_sample_chain_link,
  6. _donation_sample_chain_node,
  7. _edge_meta,
  8. _find_donation_sample,
  9. _nest_ancestor_parent,
  10. )
  11. class TestDonationSampleChainResolution(unittest.TestCase):
  12. def _mock_wo(self, **kwargs):
  13. wo = MagicMock()
  14. wo.reception_source = kwargs.get("reception_source", "research_donation")
  15. wo.protocol_sample_id = kwargs.get("protocol_sample_id", "ds-001")
  16. wo.sample_code = kwargs.get("sample_code", "JZ202605270001")
  17. wo.protocol_no = kwargs.get("protocol_no", "JZCC20260527000001")
  18. return wo
  19. def _mock_donation_sample(self):
  20. s = MagicMock()
  21. s.id = "ds-001"
  22. s.sample_code = "JZ202605270001"
  23. s.research_donation_id = "don-001"
  24. s.sample_type_id = "type-1"
  25. return s
  26. @patch("app.crud.cell_product._find_protocol_sample", return_value=None)
  27. @patch("app.crud.cell_product._find_donation_sample")
  28. @patch("app.crud.cell_product._donation_sample_customer_dict")
  29. @patch("app.crud.cell_product._sample_type_name_from_id", return_value="脐带血")
  30. def test_ancestor_link_from_donation_sample_by_code(
  31. self, _type_name, customer_dict, find_donation, _find_proto
  32. ):
  33. find_donation.return_value = self._mock_donation_sample()
  34. customer_dict.return_value = {"motherName": "测试母亲"}
  35. db = MagicMock()
  36. sample_input = MagicMock(
  37. input_id="",
  38. input_code="JZ202605270001",
  39. input_name="",
  40. )
  41. wo = self._mock_wo()
  42. edge = {"taskNo": "SCRW001", "workOrderNo": "SCGD001"}
  43. link = _ancestor_sample_chain_link(db, "zkxw", sample_input, wo, edge)
  44. self.assertIsNotNone(link)
  45. self.assertEqual(link["node"]["nodeType"], "sample")
  46. self.assertEqual(link["node"]["receptionSource"], "research_donation")
  47. self.assertEqual(link["node"]["sampleCode"], "JZ202605270001")
  48. self.assertEqual(link["node"]["customer"]["motherName"], "测试母亲")
  49. find_donation.assert_called_once()
  50. @patch("app.crud.cell_product._find_protocol_sample", return_value=None)
  51. @patch("app.crud.cell_product._donation_sample_customer_dict", return_value={})
  52. @patch("app.crud.cell_product._sample_type_name_from_id", return_value="")
  53. @patch("app.crud.cell_product._find_donation_sample")
  54. def test_ancestor_link_fallback_to_work_order_sample_id(
  55. self, find_donation, _type_name, _customer, _find_proto
  56. ):
  57. find_donation.return_value = self._mock_donation_sample()
  58. db = MagicMock()
  59. sample_input = MagicMock(input_id="", input_code="", input_name="")
  60. wo = self._mock_wo()
  61. link = _ancestor_sample_chain_link(db, "zkxw", sample_input, wo, {})
  62. self.assertIsNotNone(link)
  63. self.assertEqual(link["node"]["id"], "ds-001")
  64. self.assertEqual(find_donation.call_args[0][4], wo)
  65. def test_donation_sample_chain_node_fields(self):
  66. db = MagicMock()
  67. with patch(
  68. "app.crud.cell_product._donation_sample_customer_dict",
  69. return_value={"motherName": "A"},
  70. ):
  71. link = _donation_sample_chain_node(
  72. db,
  73. "zkxw",
  74. self._mock_donation_sample(),
  75. wo=self._mock_wo(),
  76. edge={"taskId": "t1"},
  77. sample_type_name="脐带",
  78. )
  79. node = link["node"]
  80. self.assertEqual(node["collectionProtocolId"], "don-001")
  81. self.assertEqual(node["receptionSourceLabel"], "科研捐赠")
  82. self.assertEqual(node["sampleTypeName"], "脐带")
  83. class TestChainEdgeMeta(unittest.TestCase):
  84. def test_edge_meta_work_order_type_labels(self):
  85. task = MagicMock(task_no="T001", task_name="制备", id="task-1")
  86. wo = MagicMock(work_order_no="WO001", work_order_type="temporary")
  87. edge = _edge_meta(task, wo)
  88. self.assertEqual(edge["workOrderType"], "temporary")
  89. self.assertEqual(edge["workOrderTypeLabel"], "临时生产")
  90. wo.work_order_type = "outbound"
  91. edge = _edge_meta(task, wo)
  92. self.assertEqual(edge["workOrderType"], "outbound")
  93. self.assertEqual(edge["workOrderTypeLabel"], "出库生产")
  94. wo.work_order_type = "inbound"
  95. edge = _edge_meta(task, wo)
  96. self.assertEqual(edge["workOrderType"], "inbound")
  97. self.assertEqual(edge["workOrderTypeLabel"], "入库生产")
  98. class TestNestAncestorParent(unittest.TestCase):
  99. def test_nest_empty(self):
  100. self.assertIsNone(_nest_ancestor_parent([]))
  101. def test_nest_single(self):
  102. item = {"node": {"id": "a"}}
  103. self.assertIs(_nest_ancestor_parent([item]), item)
  104. def test_nest_multi(self):
  105. items = [{"node": {"id": "a"}}, {"node": {"id": "b"}}]
  106. self.assertEqual(_nest_ancestor_parent(items), items)
  107. if __name__ == "__main__":
  108. unittest.main()