const test = require('node:test'); const assert = require('node:assert/strict'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); const { runTaskFile } = require('../../scripts/run_erp_task'); const { runCreateOrderTask } = require('../../scripts/run_create_order'); const fixturePath = path.join(__dirname, 'fixtures', 'erp-task-team-single-ready.json'); function tempTaskFile(payload) { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'erp-task-runner-')); const filePath = path.join(dir, 'task.json'); fs.writeFileSync(filePath, JSON.stringify(payload), 'utf8'); return filePath; } test('runTaskFile returns a dry-run summary for a valid task', async () => { const result = await runTaskFile(fixturePath, { mode: 'dry-run', config: { safety: { allowRealSubmit: false } }, auditDir: fs.mkdtempSync(path.join(os.tmpdir(), 'erp-task-runner-audit-')), }); assert.equal(result.status, 'dry_run'); assert.equal(result.operation, 'create_order'); assert.equal(result.route, 'team_single'); assert.equal(result.plannedExecutor, 'team_single'); }); test('runTaskFile returns invalid_task without invoking a handler', async () => { let called = false; const taskPath = tempTaskFile({ status: 'ready', operation: 'create_order', task: { schemaVersion: 'erp-task-v1', operation: 'create_order', fields: {}, }, }); const result = await runTaskFile(taskPath, { mode: 'execute', config: { safety: { allowRealSubmit: true } }, handlers: { team_single: async () => { called = true; return { status: 'completed' }; }, }, }); assert.equal(result.status, 'invalid_task'); assert.equal(called, false); }); test('runCreateOrderTask rejects a non-create task before dispatch', async () => { const taskPath = tempTaskFile({ status: 'ready', operation: 'update_order', task: { schemaVersion: 'erp-task-v1', operation: 'update_order', identifier: 'LW-270520A-A', updatePlan: { status: 'ready', actions: [] }, }, }); const result = await runCreateOrderTask(taskPath, { mode: 'dry-run', config: { safety: { allowRealSubmit: false } }, }); assert.equal(result.status, 'invalid_task'); assert.match(result.violations.join('\n'), /expected operation create_order/i); }); test('runTaskFile returns a safe completed summary from a stubbed handler', async () => { const taskPath = tempTaskFile({ status: 'ready', operation: 'export_confirmation', task: { schemaVersion: 'erp-task-v1', operation: 'export_confirmation', identifier: 'D14079', exportTypes: ['confirmation'], originalText: '确认真实保存 ERP', }, }); const result = await runTaskFile(taskPath, { mode: 'execute', config: { safety: { allowRealSubmit: true } }, handlers: { export_confirmation: async (task) => ({ status: 'completed', identifiers: { childOrderNo: task.identifier }, artifacts: [{ type: 'xingyou-confirm', path: 'outputs/D14079.doc' }], customerMessage: '确认件源文件已导出。', }), }, }); assert.equal(result.status, 'completed'); assert.equal(result.operation, 'export_confirmation'); assert.equal(result.identifiers.childOrderNo, 'D14079'); assert.equal(result.artifacts[0].type, 'xingyou-confirm'); assert.match(result.customerMessage, /确认件/); });