Files
shanxia2.0/web-admin/scripts/cert-link-rules.test.ts
T
wuzilongandCursor 8e9536332a feat: 保存运输证件、报销付款和开发流程的当前实现。
补齐证书齐备、证件折算、移动用证和合同绑定,并带上报销批量发放、付款备注以及个人开发流程升级,便于继续讨论已安排计划的调整规则。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-11-04 21:42:33 +08:00

91 lines
3.5 KiB
TypeScript

import assert from 'node:assert/strict'
import test from 'node:test'
import {
addDraftProducts,
canRestoreProduct,
canSaveNewLink,
canSaveProductEdit,
certChoiceLabel,
certChoiceState,
removeDraftProduct
} from '../src/views/m/pl/plan-cert/cert-link-rules'
import { replaceCertProducts } from '../src/views/pl/quota-cert/model'
const saved = { id: 'scope-1', contractProductId: 'line-1', scopeStatus: 'active' as const }
const other = { id: 'scope-2', contractProductId: 'line-2', scopeStatus: 'inactive' as const }
test('void and already linked certificates cannot be newly selected', () => {
const taken = new Set(['purchase:linked'])
assert.equal(certChoiceState({ id: 'voided', status: 'void' }, 'purchase', taken), 'void')
assert.equal(certChoiceState({ id: 'closed', status: 'closed' }, 'purchase', taken), 'closed')
assert.equal(
certChoiceLabel({ id: 'closed', status: 'closed', certNo: 'G1' }, 'purchase', taken),
'G1(已核销)'
)
assert.equal(certChoiceState({ id: 'linked', status: 'active' }, 'purchase', taken), 'taken')
assert.equal(certChoiceState({ id: 'free', status: 'active' }, 'purchase', taken), 'open')
assert.match(certChoiceLabel({ id: 'voided', status: 'void', certNo: 'G1' }, 'purchase', taken), /已作废/)
assert.match(certChoiceLabel({ id: 'linked', status: 'active', certNo: 'G2' }, 'purchase', taken), /已关联/)
})
test('a new link needs one available product and an edit saves only after the scope changes', () => {
assert.equal(canSaveNewLink([]), false)
assert.equal(canSaveNewLink([{ contractProductId: 'line-1', scopeStatus: 'inactive' }]), false)
assert.equal(canSaveNewLink([{ contractProductId: 'line-1', scopeStatus: 'active' }]), true)
assert.equal(canSaveProductEdit([saved], [saved]), false)
assert.equal(
canSaveProductEdit([saved], [{ ...saved, scopeStatus: 'inactive' }]),
true
)
})
test('saved products stay in the set and only change availability', () => {
assert.equal(canRestoreProduct('void', 'inactive'), false)
assert.equal(canRestoreProduct('void', 'active'), true)
assert.equal(canRestoreProduct('active', 'inactive'), true)
const removed = removeDraftProduct([saved, { contractProductId: 'draft', scopeStatus: 'active' }], 'line-1')
assert.deepEqual(
removed.map((product) => product.contractProductId),
['line-1', 'draft']
)
assert.deepEqual(
removeDraftProduct(removed, 'draft').map((product) => product.contractProductId),
['line-1']
)
const added = addDraftProducts([saved], ['line-1', 'line-3'])
assert.deepEqual(
added.map((product) => product.contractProductId),
['line-1', 'line-3']
)
assert.equal(added[0].id, 'scope-1')
})
test('replacing one certificate keeps the other certificate and the product id', () => {
const bindings = [
{
id: 'link-1',
certType: 'purchase' as const,
certId: 'cert-1',
linkStatus: 'active' as const,
products: [saved, other]
},
{
id: 'link-2',
certType: 'transport' as const,
certId: 'cert-2',
linkStatus: 'active' as const,
products: [{ id: 'scope-3', contractProductId: 'line-9', scopeStatus: 'active' as const }]
}
]
const next = replaceCertProducts(bindings, 'purchase', 'cert-1', [
{ ...saved, scopeStatus: 'inactive' },
other
])
assert.equal(next.length, 2)
assert.equal(next[0].id, 'link-2')
assert.equal(next[1].id, 'link-1')
assert.equal(next[1].products[0].id, 'scope-1')
assert.equal(next[1].products[0].scopeStatus, 'inactive')
assert.equal(next[1].products[1].contractProductId, 'line-2')
})