import test from 'node:test' import assert from 'node:assert/strict' const { stableOperationId } = await import(new URL('../utils/idempotency.js', import.meta.url).href) const { stableTaskIdentityKey, stableTaskOperationIdentity } = await import(new URL('../utils/task-identity.js', import.meta.url).href) test('PDA operation id is stable ASCII and within the backend 128 character limit', () => { const payload = { itemStates: Object.fromEntries(Array.from({ length: 500 }, (_, index) => [`明细-${index}`, 'PICKED'])), reason: '中文异常原因'.repeat(100) } const first = stableOperationId('submit', 'operator-1-task-2-container-3', payload) const replay = stableOperationId('submit', 'operator-1-task-2-container-3', payload) assert.equal(first, replay) assert.ok(first.length <= 128) assert.match(first, /^[\x20-\x7E]+$/) }) test('PDA operation id changes when the draft changes', () => { const first = stableOperationId('submit', 'operator-task-container', { item: 'PICKED' }) const second = stableOperationId('submit', 'operator-task-container', { item: 'SKIPPED' }) assert.notEqual(first, second) }) test('real container number changes do not move the draft or idempotency identity', () => { const before = { operatorId: 7, taskId: 11, loadingPlanId: 13, containerBookingId: 17, currentContainerNo: 'REAL-001' } const after = { ...before, currentContainerNo: 'REAL-002' } const payload = { item: 'PICKED' } assert.equal(stableTaskIdentityKey(before), stableTaskIdentityKey(after)) assert.equal(stableOperationId('submit', stableTaskOperationIdentity(before), payload), stableOperationId('submit', stableTaskOperationIdentity(after), payload)) }) test('container booking mismatch is rejected by stable task binding', () => { const original = { operatorId: 7, taskId: 11, loadingPlanId: 13, containerBookingId: 17 } const differentBooking = { ...original, containerBookingId: 18 } assert.equal(stableTaskIdentityKey(original), stableTaskIdentityKey(differentBooking)) assert.notEqual(stableTaskOperationIdentity(original), stableTaskOperationIdentity(differentBooking)) })