Files
zkxw/web-admin/src/utils/protocol-audit-flatten.test.ts
T
zlwuandCursor 5dc695a138 fix(web-admin): 协议单扁平行列表展示所属项目与项目组
采集协议单管理(细胞存储/科研捐赠)展平样本行时未拷贝项目归属字段,导致表格列空白;补齐展平字段并增加回归单测。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-05 16:45:33 +08:00

185 lines
6.4 KiB
TypeScript

// web-admin/src/utils/protocol-audit-flatten.test.ts
import { describe, it } from 'node:test'
import assert from 'node:assert/strict'
import {
flattenProtocolAuditRows,
extractCollectDate,
uniqueProtocolsFromFlatRows,
firstPayTimeLines
} from './protocol-audit-flatten'
describe('extractCollectDate', () => {
it('takes YYYY-MM-DD from datetime', () => {
assert.equal(extractCollectDate('2025-09-15 08:51:00'), '2025-09-15')
assert.equal(extractCollectDate('2025-09-15T08:51:00'), '2025-09-15')
})
it('empty → empty', () => {
assert.equal(extractCollectDate(''), '')
assert.equal(extractCollectDate(undefined), '')
})
})
describe('flattenProtocolAuditRows', () => {
it('one protocol two samples → two rows, both co-stored', () => {
const rows = flattenProtocolAuditRows([
{
id: 'p1',
protocolNo: 'ZKZX1',
motherName: '郭梦朵',
projectName: '测试项目',
teamName: '陈星项目组111',
sampleCollectTime: '2025-09-15 08:51:00',
sampleItems: [
{ sampleTypeName: '脐带血', sampleCode: 'A1', labStorageCode: 'B0000004' },
{ sampleTypeName: '胎盘', sampleCode: 'A2', labStorageCode: 'B0000004A' }
]
}
])
assert.equal(rows.length, 2)
assert.equal(rows[0].isCoStored, true)
assert.equal(rows[1].isCoStored, true)
assert.equal(rows[0].collectDate, '2025-09-15')
assert.equal(rows[0].labStorageCode, 'B0000004')
assert.equal(rows[1].labStorageCode, 'B0000004A')
assert.equal(rows[0].protocolId, 'p1')
assert.equal(rows[0].projectName, '测试项目')
assert.equal(rows[0].teamName, '陈星项目组111')
assert.equal(rows[1].projectName, '测试项目')
assert.equal(rows[1].teamName, '陈星项目组111')
})
it('copies protocol project attribution onto each flat row for table props', () => {
const rows = flattenProtocolAuditRows([
{
id: 'p-attr',
projectName: '归属项目',
teamName: '归属项目组',
sampleItems: [{ sampleCode: 'ZKZX34000199', sampleTypeName: '围产期造血干细胞' }]
}
])
assert.equal(rows.length, 1)
assert.equal(rows[0].projectName, '归属项目')
assert.equal(rows[0].teamName, '归属项目组')
assert.equal(rows[0].sampleCode, 'ZKZX34000199')
})
it('zero samples → one placeholder row, not co-stored', () => {
const rows = flattenProtocolAuditRows([{ id: 'p2', protocolNo: 'ZKZX2', sampleItems: [] }])
assert.equal(rows.length, 1)
assert.equal(rows[0].isCoStored, false)
assert.equal(rows[0].labStorageCode, '')
})
it('one sample → not co-stored', () => {
const rows = flattenProtocolAuditRows([
{
id: 'p3',
sampleItems: [{ sampleTypeName: '脐带血', sampleCode: 'C1', labStorageCode: 'B7' }]
}
])
assert.equal(rows.length, 1)
assert.equal(rows[0].isCoStored, false)
})
it('donationNo maps to protocolNo', () => {
const rows = flattenProtocolAuditRows([
{
id: 'd1',
donationNo: 'JZ-001',
sampleItems: [{ sampleTypeName: '脐带血', sampleCode: 'D1', labStorageCode: 'B9' }]
}
])
assert.equal(rows[0].protocolNo, 'JZ-001')
})
it('passes research donation excel-parity fields from protocol', () => {
const rows = flattenProtocolAuditRows([
{
id: 'd2',
donationNo: 'JZ-002',
monthlyVerifyNo: '202508001',
donationStatus: 'sdfq',
voidDesc: '母血乙肝阳性',
newbornDeliveryTime: '2025-08-29 12:26:00',
newbornSex: '0',
newbornWeightGram: 3000,
deliveryMode: 'sc',
birthOrder: 1,
maternalBloodCollectTime: '2025-08-29 13:30:00',
consentFormUrls: 'https://x/a.pdf',
infectiousDiseaseReportUrls: '',
attachmentUrls: 'https://x/b.pdf',
remark: '备注一',
sampleItems: [{ sampleTypeName: 'NK', sampleCode: 'D2', labStorageCode: 'A1' }]
}
])
assert.equal(rows[0].monthlyVerifyNo, '202508001')
assert.equal(rows[0].donationStatus, 'sdfq')
assert.equal(rows[0].voidDesc, '母血乙肝阳性')
assert.equal(rows[0].birthOrder, '1')
assert.equal(rows[0].newbornWeightGram, '3000')
assert.equal(rows[0].consentFormUrls, 'https://x/a.pdf')
assert.equal(rows[0].infectiousDiseaseReportUrls, '')
assert.equal(rows[0].attachmentUrls, 'https://x/b.pdf')
assert.equal(rows[0].remark, '备注一')
})
})
describe('uniqueProtocolsFromFlatRows', () => {
it('dedupes by protocolId keeping first protocol ref', () => {
const flat = flattenProtocolAuditRows([
{
id: 'p1',
motherName: 'A',
sampleItems: [
{ sampleCode: '1', labStorageCode: 'B1' },
{ sampleCode: '2', labStorageCode: 'B2' }
]
}
])
const uniq = uniqueProtocolsFromFlatRows(flat)
assert.equal(uniq.length, 1)
assert.equal(String(uniq[0].id), 'p1')
})
})
describe('firstPayTimeLines', () => {
it('prefers firstPayTransferTime from summary', () => {
const lines = firstPayTimeLines({
firstPayTransferTime: '2025-09-20 14:30:00',
paymentDetails: [
{ installmentNo: 1, transferTime: '2025-09-15 09:20:00' },
{ installmentNo: 2, transferTime: '2025-10-15 10:05:00' }
]
})
assert.deepEqual(lines, ['2025-09-20 14:30:00'])
})
it('only first period; ignores later installments', () => {
const lines = firstPayTimeLines({
paymentDetails: [
{ installmentNo: 1, transferTime: '2025-09-15 09:20:00', installmentDueDate: '2025-09-01' },
{ installmentNo: 2, transferTime: '2025-10-15 10:05:00' },
{ installmentNo: 3, transferTime: '2025-11-15 11:00:00' }
]
})
assert.deepEqual(lines, ['2025-09-15 09:20:00'])
})
it('among period-1 transfers picks the earliest transferTime', () => {
const lines = firstPayTimeLines({
paymentDetails: [
{ installmentNo: 1, transferTime: '2025-09-15 09:20:00' },
{ installmentNo: 1, transferTime: '2025-09-20 14:30:00' },
{ installmentNo: 1, transferTime: '2025-09-18 08:00:00' },
{ installmentNo: 2, transferTime: '2025-10-15 10:05:00' }
]
})
assert.deepEqual(lines, ['2025-09-15 09:20:00'])
})
it('empty when period 1 has no transferTime', () => {
const lines = firstPayTimeLines({
paymentDetails: [{ installmentNo: 1, installmentDueDate: '2025-09-01' }]
})
assert.deepEqual(lines, [])
})
})