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') })