协议样本、生产产出和盘点明细按行更新并保留原 id;补齐存储证明质检预填、离职人员显示名,以及样本采集通知模板字段。 Co-authored-by: Cursor <cursoragent@cursor.com>
344 lines
15 KiB
Python
344 lines
15 KiB
Python
"""储存证质检信息:类型键、payload 与自动补空。"""
|
|
import unittest
|
|
from datetime import datetime
|
|
from types import SimpleNamespace
|
|
|
|
from app.crud.sample_storage_cert_qc import _row_to_dict
|
|
from app.services.sample_storage_cert_qc import (
|
|
SAMPLE_TYPE_KEY_PERINATAL_HSC,
|
|
SAMPLE_TYPE_KEY_UC_MSC,
|
|
empty_detail,
|
|
normalize_payload,
|
|
resolve_sample_type_key,
|
|
supports_storage_cert_qc,
|
|
)
|
|
from app.services.sample_storage_cert_qc_prefill import (
|
|
batch_kind_from_name,
|
|
build_suggested,
|
|
match_cd34_param,
|
|
merge_prefill,
|
|
qual_yin_yang,
|
|
sum_cryo_volume,
|
|
)
|
|
|
|
|
|
class TestResolveSampleTypeKey(unittest.TestCase):
|
|
def test_hsc(self):
|
|
self.assertEqual(resolve_sample_type_key("围产期造血干细胞"), SAMPLE_TYPE_KEY_PERINATAL_HSC)
|
|
|
|
def test_msc(self):
|
|
self.assertEqual(resolve_sample_type_key("脐带间充质干细胞"), SAMPLE_TYPE_KEY_UC_MSC)
|
|
|
|
def test_other(self):
|
|
self.assertIsNone(resolve_sample_type_key("胎盘亚全能干细胞"))
|
|
self.assertIsNone(resolve_sample_type_key(""))
|
|
|
|
def test_supports(self):
|
|
self.assertTrue(supports_storage_cert_qc("围产期造血干细胞"))
|
|
self.assertFalse(supports_storage_cert_qc("其他"))
|
|
|
|
|
|
class TestNormalizePayload(unittest.TestCase):
|
|
def test_rejects_non_object(self):
|
|
with self.assertRaises(ValueError):
|
|
normalize_payload([])
|
|
with self.assertRaises(ValueError):
|
|
normalize_payload("x")
|
|
|
|
def test_keeps_dict_stringifies_keys(self):
|
|
out = normalize_payload({"viability_pct": 90.4, 1: "bad"})
|
|
self.assertEqual(out["viability_pct"], 90.4)
|
|
self.assertNotIn(1, out)
|
|
|
|
|
|
class TestEmptyDetail(unittest.TestCase):
|
|
def test_shape(self):
|
|
d = empty_detail(
|
|
sample_code="B1",
|
|
lab_flow_code="LAB-001",
|
|
protocol_code="P1",
|
|
mother_name="张三",
|
|
sample_type_name="围产期造血干细胞",
|
|
sample_type_key="perinatal_hsc",
|
|
)
|
|
self.assertFalse(d["filledFlag"])
|
|
self.assertEqual(d["payload"], {})
|
|
self.assertEqual(d["sampleCode"], "B1")
|
|
self.assertEqual(d["labFlowCode"], "LAB-001")
|
|
|
|
def test_lab_flow_defaults_empty(self):
|
|
d = empty_detail(sample_code="B1")
|
|
self.assertEqual(d["labFlowCode"], "")
|
|
|
|
|
|
class TestRowToDict(unittest.TestCase):
|
|
def test_filled(self):
|
|
row = SimpleNamespace(
|
|
id="1",
|
|
sample_code="B1",
|
|
sample_type_key="perinatal_hsc",
|
|
collection_protocol_id="P",
|
|
qc_work_order_id="W",
|
|
filled_flag="1",
|
|
payload='{"viability_pct":"90"}',
|
|
create_time=None,
|
|
update_time=None,
|
|
)
|
|
d = _row_to_dict(
|
|
row,
|
|
lab_flow_code="LAB-001",
|
|
protocol_code="C1",
|
|
mother_name="李",
|
|
sample_type_name="围产期造血干细胞",
|
|
)
|
|
self.assertTrue(d["filledFlag"])
|
|
self.assertEqual(d["payload"]["viability_pct"], "90")
|
|
self.assertEqual(d["sampleCode"], "B1")
|
|
self.assertEqual(d["labFlowCode"], "LAB-001")
|
|
self.assertEqual(d["protocolCode"], "C1")
|
|
|
|
|
|
def _task(item_name, stamp, params, batch_kind=""):
|
|
values = [value for _name, value in params if str(value).strip()]
|
|
return {
|
|
"item_name": item_name,
|
|
"stamp": stamp,
|
|
"params": params,
|
|
"values": values,
|
|
"batch_kind": batch_kind,
|
|
}
|
|
|
|
|
|
class TestStorageCertPrefill(unittest.TestCase):
|
|
def test_cd34_param_names(self):
|
|
self.assertEqual(match_cd34_param("有核细胞数TNC/*108(个)"), "tnc_1e8")
|
|
self.assertEqual(match_cd34_param("CD34+细胞数/*106(个)"), "cd34_count_1e6")
|
|
self.assertEqual(match_cd34_param('CD34+ CD45dim 细胞数/*105(个)'), "cd34_cd45dim_1e5")
|
|
|
|
def test_volume_needs_both_numbers(self):
|
|
self.assertEqual(sum_cryo_volume(10.5, 2), "12.5")
|
|
self.assertEqual(sum_cryo_volume(10, None), "")
|
|
self.assertEqual(sum_cryo_volume(None, 2), "")
|
|
|
|
def test_qual_only_explicit_yin_yang(self):
|
|
self.assertEqual(qual_yin_yang(["阴性"]), "阴")
|
|
self.assertEqual(qual_yin_yang(["通过"]), "")
|
|
self.assertEqual(qual_yin_yang(["阴", "阳"]), "")
|
|
self.assertEqual(qual_yin_yang(["未检出"]), "")
|
|
|
|
def test_hsc_fills_known_values_and_skips_unconfirmed(self):
|
|
older = datetime(2026, 1, 1, 8, 0)
|
|
newer = datetime(2026, 2, 2, 9, 0)
|
|
suggested = build_suggested(
|
|
sample_type_key="perinatal_hsc",
|
|
collection_time=datetime(2026, 1, 1, 13, 45),
|
|
reception_time=datetime(2026, 1, 2, 9, 0),
|
|
enriched_blood_weight_g=20,
|
|
cryopreservation_volume_ml=9.1,
|
|
gate_tasks=[
|
|
_task(
|
|
"CD34+细胞流式",
|
|
older,
|
|
[("有核细胞数TNC/*108(个)", "1.1"), ("CD34+细胞数/*106(个)", "2.2")],
|
|
),
|
|
_task(
|
|
"CD34+细胞流式",
|
|
newer,
|
|
[
|
|
("有核细胞数TNC/*10E8", "8.27"),
|
|
("CD34+细胞数/*106(个)", "55.5"),
|
|
("CD34+ CD45dim 细胞数/*105(个)", "1.14"),
|
|
],
|
|
),
|
|
],
|
|
latest_freeze_date=datetime(2026, 3, 3, 16, 0),
|
|
)
|
|
self.assertEqual(suggested["collection_time"], "2026-01-01 13:45")
|
|
self.assertEqual(suggested["receive_time"], "2026-01-02 09:00")
|
|
self.assertEqual(suggested["cryo_volume_ml"], "29.1")
|
|
self.assertEqual(suggested["tnc_1e8"], "8.27")
|
|
self.assertEqual(suggested["cd34_count_1e6"], "55.5")
|
|
self.assertEqual(suggested["cd34_cd45dim_1e5"], "1.14")
|
|
self.assertEqual(suggested["storage_date"], "2026-03-03")
|
|
self.assertEqual(suggested["storage_years"], "20年")
|
|
self.assertEqual(suggested["bacteria_test"], "阴性")
|
|
self.assertEqual(suggested["result_comment"], "合格")
|
|
self.assertNotIn("hbsag", suggested)
|
|
self.assertNotIn("mother_hbsag", suggested)
|
|
self.assertNotIn("viability_pct", suggested)
|
|
self.assertNotIn("hla_typing", suggested)
|
|
self.assertNotIn("report_issue_date", suggested)
|
|
|
|
def test_hsc_serology_reads_batch_item_param(self):
|
|
self.assertEqual(batch_kind_from_name("B0000075-脐血"), "脐血")
|
|
self.assertEqual(batch_kind_from_name("B0000075-母血"), "母血")
|
|
stamp = datetime(2026, 7, 4, 9, 0)
|
|
suggested = build_suggested(
|
|
sample_type_key="perinatal_hsc",
|
|
gate_tasks=[
|
|
_task(
|
|
"乙肝五项定性",
|
|
stamp,
|
|
[
|
|
("乙型肝炎病毒表面抗原", "阴性"),
|
|
("抗乙型肝炎病毒表面抗体", "阳性"),
|
|
],
|
|
"脐血",
|
|
),
|
|
_task("抗丙型肝炎病毒抗体", stamp, [("抗丙型肝炎病毒抗体", "阳性")], "脐血"),
|
|
_task("抗梅毒螺旋体特异抗体", stamp, [("抗梅毒螺旋体特异抗体", "阴性")], "脐血"),
|
|
_task("抗人类免疫缺陷病毒抗体", stamp, [("抗人类免疫缺陷病毒抗体", "阴性")], "脐血"),
|
|
_task("乙肝五项定性", stamp, [("乙型肝炎病毒表面抗原", "阳性")], "母血"),
|
|
_task("乙型肝炎病毒DNA", stamp, [("乙型肝炎病毒DNA", "阴性")], "母血"),
|
|
_task(
|
|
"人类免疫缺陷病毒I型核酸(HIV-1 RNA)定量,实时荧光定量PCR",
|
|
stamp,
|
|
[],
|
|
"母血",
|
|
),
|
|
_task("丙型肝炎病毒RNA", stamp, [("丙型肝炎病毒RNA", "通过")], "母血"),
|
|
],
|
|
)
|
|
self.assertEqual(suggested["hbsag"], "阴性")
|
|
self.assertEqual(suggested["anti_hcv"], "阳性")
|
|
self.assertEqual(suggested["anti_tp"], "阴性")
|
|
self.assertEqual(suggested["anti_hiv"], "阴性")
|
|
self.assertNotIn("cmv_igm", suggested)
|
|
self.assertEqual(suggested["mother_hbsag"], "阳性")
|
|
self.assertEqual(suggested["mother_hbv_dna"], "阴性")
|
|
self.assertNotIn("mother_hiv1_rna", suggested)
|
|
self.assertNotIn("mother_hcv_rna", suggested)
|
|
self.assertEqual(suggested["bacteria_test"], "阴性")
|
|
self.assertNotIn("viability_pct", suggested)
|
|
|
|
def test_uc_msc_fixed_values_and_process_qual(self):
|
|
suggested = build_suggested(
|
|
sample_type_key="uc_msc",
|
|
receive_temperature="常温",
|
|
storage_total_tubes=17,
|
|
available_cell_count_1e7=8.5,
|
|
process_tasks=[
|
|
_task("内毒素(透析液)检测", datetime(2026, 1, 1), [("结果", "阴性")]),
|
|
_task("真菌培养及鉴定", datetime(2026, 1, 2), [("结论", "通过")]),
|
|
_task("支原体培养+药敏", datetime(2026, 1, 3), [("结果", "阳")]),
|
|
],
|
|
latest_freeze_date=datetime(2026, 4, 4),
|
|
)
|
|
self.assertEqual(suggested["transport_temp_c"], "常温")
|
|
self.assertEqual(suggested["storage_tube_count"], "17")
|
|
self.assertEqual(suggested["available_cell_count_1e7"], "8.5")
|
|
self.assertEqual(suggested["endotoxin_test"], "阴性")
|
|
self.assertNotIn("fungus_test", suggested)
|
|
self.assertEqual(suggested["mycoplasma_test"], "阳性")
|
|
self.assertEqual(suggested["bacteria_test"], "阴性")
|
|
self.assertEqual(suggested["result_judgment"], "合格")
|
|
self.assertNotIn("mother_hbsag", suggested)
|
|
self.assertEqual(suggested["available_cell_type"], "间充质干细胞")
|
|
self.assertEqual(suggested["available_cell_morphology"], "短梭/贴壁型")
|
|
self.assertEqual(suggested["available_immunophenotype"], "符合间充质干细胞表型特性")
|
|
self.assertEqual(suggested["freeze_method"], "程序降温盒降温")
|
|
self.assertEqual(suggested["storage_temp"], "-196℃")
|
|
self.assertEqual(suggested["storage_years"], "20年")
|
|
self.assertEqual(suggested["storage_date_p2"], "2026-04-04")
|
|
self.assertNotIn("available_viability_pct", suggested)
|
|
self.assertNotIn("report_issue_date", suggested)
|
|
|
|
def test_uc_msc_mother_blood_and_ignores_bacteria_culture(self):
|
|
stamp = datetime(2026, 5, 5, 8, 0)
|
|
suggested = build_suggested(
|
|
sample_type_key="uc_msc",
|
|
gate_tasks=[
|
|
_task(
|
|
"乙肝五项定性",
|
|
stamp,
|
|
[
|
|
("乙型肝炎病毒表面抗原", "阳性"),
|
|
("抗乙型肝炎病毒表面抗体", "阴性"),
|
|
],
|
|
"母血",
|
|
),
|
|
_task("乙型肝炎病毒DNA", stamp, [], "母血"),
|
|
],
|
|
process_tasks=[
|
|
_task("需氧菌培养及鉴定(相关体液)", stamp, [("需氧菌培养及鉴定(相关体液)", "阳性")]),
|
|
_task(
|
|
"支原体培养+药敏",
|
|
stamp,
|
|
[("解脲(Uu)支原体培养", "阴性"), ("人型(Mh)支原体培养", "阴性")],
|
|
),
|
|
],
|
|
)
|
|
self.assertEqual(suggested["mother_hbsag"], "阳性")
|
|
self.assertNotIn("mother_hbv_dna", suggested)
|
|
self.assertEqual(suggested["mycoplasma_test"], "阴性")
|
|
self.assertEqual(suggested["bacteria_test"], "阴性")
|
|
self.assertNotIn("hbsag", suggested)
|
|
|
|
def test_shared_mother_blood_fills_sample_without_its_own(self):
|
|
stamp = datetime(2026, 7, 4, 9, 0)
|
|
shared = [
|
|
_task(
|
|
"乙肝五项定性",
|
|
stamp,
|
|
[
|
|
("乙型肝炎病毒表面抗原", "阴性"),
|
|
("抗乙型肝炎病毒表面抗体", "阳性"),
|
|
],
|
|
"母血",
|
|
),
|
|
_task("乙型肝炎病毒DNA", stamp, [("乙型肝炎病毒DNA", "阴性")], "母血"),
|
|
_task("抗丙型肝炎病毒抗体", stamp, [("抗丙型肝炎病毒抗体", "阴性")], "母血"),
|
|
_task("丙型肝炎病毒RNA", stamp, [("丙型肝炎病毒RNA", "阴性")], "母血"),
|
|
_task("抗梅毒螺旋体特异抗体", stamp, [("抗梅毒螺旋体特异抗体", "阴性")], "母血"),
|
|
_task("抗巨细胞病毒抗体IgM定量", stamp, [("抗巨细胞病毒抗体IgM定量", "阴性")], "母血"),
|
|
_task("抗人类免疫缺陷病毒抗体", stamp, [("抗人类免疫缺陷病毒抗体", "阴性")], "母血"),
|
|
_task(
|
|
"人类免疫缺陷病毒I型核酸(HIV-1 RNA)定量,实时荧光定量PCR",
|
|
stamp,
|
|
[("人类免疫缺陷病毒核酸(1型) (HIV-1RNA)", "阴性")],
|
|
"母血",
|
|
),
|
|
_task("乙肝五项定性", stamp, [("乙型肝炎病毒表面抗原", "阳性")], "脐血"),
|
|
]
|
|
suggested = build_suggested(sample_type_key="uc_msc", shared_mother_tasks=shared)
|
|
self.assertEqual(suggested["mother_hbsag"], "阴性")
|
|
self.assertEqual(suggested["mother_hbv_dna"], "阴性")
|
|
self.assertEqual(suggested["mother_anti_hcv"], "阴性")
|
|
self.assertEqual(suggested["mother_hcv_rna"], "阴性")
|
|
self.assertEqual(suggested["mother_anti_tp"], "阴性")
|
|
self.assertEqual(suggested["mother_cmv_igm"], "阴性")
|
|
self.assertEqual(suggested["mother_anti_hiv"], "阴性")
|
|
self.assertEqual(suggested["mother_hiv1_rna"], "阴性")
|
|
self.assertNotIn("hbsag", suggested)
|
|
|
|
def test_own_mother_blood_wins_and_shared_only_fills_gaps(self):
|
|
stamp = datetime(2026, 7, 4, 9, 0)
|
|
suggested = build_suggested(
|
|
sample_type_key="perinatal_hsc",
|
|
gate_tasks=[
|
|
_task("乙肝五项定性", stamp, [("乙型肝炎病毒表面抗原", "阳性")], "脐血"),
|
|
_task("乙肝五项定性", stamp, [("乙型肝炎病毒表面抗原", "阳性")], "母血"),
|
|
],
|
|
shared_mother_tasks=[
|
|
_task("乙肝五项定性", stamp, [("乙型肝炎病毒表面抗原", "阴性")], "母血"),
|
|
_task("乙型肝炎病毒DNA", stamp, [("乙型肝炎病毒DNA", "阴性")], "母血"),
|
|
_task("乙肝五项定性", stamp, [("乙型肝炎病毒表面抗原", "阴性")], "脐血"),
|
|
],
|
|
)
|
|
self.assertEqual(suggested["hbsag"], "阳性")
|
|
self.assertEqual(suggested["mother_hbsag"], "阳性")
|
|
self.assertEqual(suggested["mother_hbv_dna"], "阴性")
|
|
|
|
def test_merge_keeps_saved_values(self):
|
|
merged = merge_prefill(
|
|
{"storage_years": "30年", "collection_time": ""},
|
|
{"storage_years": "20年", "collection_time": "2026-01-01 13:45", "hbsag": ""},
|
|
)
|
|
self.assertEqual(merged["storage_years"], "30年")
|
|
self.assertEqual(merged["collection_time"], "2026-01-01 13:45")
|
|
self.assertNotIn("hbsag", merged)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|