"""采集协议单创建/更新子表持久化与字段名规范化测试。""" import unittest from unittest.mock import MagicMock, patch from app.crud.collection_protocol import ( _normalize_fields, attachments_to_urls, lookup_attachments_by_urls, urls_to_attachment_list, upsert_party_customer, ) class TestNormalizeFields(unittest.TestCase): def test_camel_case_to_snake(self): raw = { "customerId": "c1", "motherName": "张三", "motherBirthYm": "199001", "apgar1min": 9.5, "apgar5min": 10, } out = _normalize_fields(raw) self.assertEqual(out["customer_id"], "c1") self.assertEqual(out["mother_name"], "张三") self.assertEqual(out["mother_birth_ym"], "199001") self.assertEqual(out["apgar_1min"], 9.5) self.assertEqual(out["apgar_5min"], 10) class TestAttachmentsHelpers(unittest.TestCase): def test_attachments_to_urls(self): urls = attachments_to_urls( [{"fileUrl": "http://a/1.jpg"}, {"fileUrl": "http://a/2.jpg"}] ) self.assertEqual(urls, "http://a/1.jpg,http://a/2.jpg") def test_urls_to_attachment_list(self): items = urls_to_attachment_list("http://x/a.pdf,http://x/b.png") self.assertEqual(len(items), 2) self.assertEqual(items[0]["fileUrl"], "http://x/a.pdf") def test_urls_to_attachment_list_uses_original_name_from_db(self): db = MagicMock() att = MagicMock() att.id = "att-1" att.original_name = "合同扫描件.pdf" att.file_url = "protocol/2025/05/16/abc.pdf" att.file_size = 2048 att.file_type = "application/pdf" q = MagicMock() db.query.return_value = q q.filter.return_value = q q.first.return_value = att items = urls_to_attachment_list("protocol/2025/05/16/abc.pdf", db, "t1") self.assertEqual(len(items), 1) self.assertEqual(items[0]["fileName"], "合同扫描件.pdf") self.assertEqual(items[0]["id"], "att-1") def test_urls_to_attachment_list_uses_prefetched_map(self): att = MagicMock() att.id = "att-2" att.original_name = "报告.pdf" att.file_url = "qc/a.pdf" att.file_size = 1024 att.file_type = "application/pdf" items = urls_to_attachment_list( "qc/a.pdf,qc/missing.pdf", db=MagicMock(), tenant_no="t1", attachment_by_url={"qc/a.pdf": att}, ) self.assertEqual(len(items), 2) self.assertEqual(items[0]["fileName"], "报告.pdf") self.assertEqual(items[0]["id"], "att-2") self.assertEqual(items[1]["fileName"], "missing.pdf") self.assertNotIn("id", items[1]) def test_lookup_attachments_by_urls_batches_exact_match(self): db = MagicMock() att = MagicMock() att.file_url = "qc/a.pdf" q = MagicMock() db.query.return_value = q q.filter.return_value = q q.all.return_value = [att] out = lookup_attachments_by_urls(db, ["qc/a.pdf", "qc/a.pdf", ""], "t1") self.assertEqual(out["qc/a.pdf"], att) db.query.assert_called_once() class TestUpsertPartyCustomer(unittest.TestCase): @patch("app.crud.collection_protocol.get_party_customer") def test_upsert_applies_camel_case_fields(self, mock_get): mock_get.return_value = None db = MagicMock() fields = { "motherName": "李四", "motherPhone": "13800000000", "motherIdCard": "110101199001011234", "motherBirthYm": "199001", "fatherName": "王五", } upsert_party_customer(db, "proto-1", "t1", "u1", **fields) added = db.add.call_args[0][0] self.assertEqual(added.mother_name, "李四") self.assertEqual(added.mother_phone, "13800000000") self.assertEqual(added.mother_id_card, "110101199001011234") self.assertEqual(added.mother_birth_ym, "199001") self.assertEqual(added.father_name, "王五") if __name__ == "__main__": unittest.main()