const assert = require('node:assert/strict'); const test = require('node:test'); const { DesktopExecutionTaskError, buildAutoListingDesktopTaskInputs, buildTaskCode, mapTask, normalizeProgress, normalizeTaskType, } = require('../src/services/desktopExecutionTaskService'); test('desktop task types are normalized and unknown executors are rejected', () => { assert.equal(normalizeTaskType('product-test'), 'product_test'); assert.equal(normalizeTaskType('presale'), 'presale'); assert.throws( () => normalizeTaskType('unknown-action'), (error) => error instanceof DesktopExecutionTaskError && error.code === 'DESKTOP_TASK_TYPE_INVALID' ); }); test('desktop task codes are time ordered and collision resistant', () => { const code = buildTaskCode(new Date('2026-08-23T08:09:10.000Z'), () => Buffer.from('01020304', 'hex')); assert.equal(code, 'DT2026082308091001020304'); }); test('desktop task progress derives a bounded percentage', () => { assert.deepEqual(normalizeProgress({ stage: 'shop', current: 3, total: 4, message: '处理中' }), { stage: 'shop', current: 3, total: 4, percent: 75, message: '处理中', }); assert.equal(normalizeProgress({ current: 8, total: 4 }).percent, 100); assert.equal(normalizeProgress({ percent: -3 }).percent, 0); }); test('stored task rows expose stable camelCase snapshots', () => { const task = mapTask({ id: 7, task_code: 'DT1', task_type: 'presale', source_type: 'selection_fission_item', source_id: '17', source_code: 'SF-17', assigned_user_id: 9, status: 'running', input_json: '{"runDate":"2026-08-23"}', progress_current: 2, progress_total: 5, progress_percent: 40, }); assert.equal(task.id, 7); assert.equal(task.assignedUserId, 9); assert.equal(task.input.runDate, '2026-08-23'); assert.equal(task.sourceType, 'selection_fission_item'); assert.equal(task.sourceId, '17'); assert.equal(task.sourceCode, 'SF-17'); assert.deepEqual(task.progress, { stage: '', current: 2, total: 5, percent: 40, message: '' }); }); test('automatic listing wrappers preserve the original child task identity and target shop', () => { const tasks = buildAutoListingDesktopTaskInputs({ id: 3, schemeCode: 'PLAN-3', listingShopId: 'shop-9', listingShopName: '旗舰店', listingTasks: [ { id: 17, taskCode: 'SF-17', listingStatus: 'pending', selectedSpuCode: 'SPU001', selectedSpuName: '桌子', selectedProductTitle: '实木桌子', }, { id: 18, taskCode: 'SF-18', listingStatus: 'listed', listedItemId: 'PDD18', selectedSpuCode: 'SPU002' }, ], }, { id: 9, name: '陆南亭', username: 'ln亭' }); assert.equal(tasks.length, 1); assert.equal(tasks[0].taskType, 'auto_listing'); assert.equal(tasks[0].sourceId, '17'); assert.equal(tasks[0].sourceCode, 'SF-17'); assert.equal(tasks[0].input.sourceTaskCode, 'SF-17'); assert.equal(tasks[0].targetShopId, 'shop-9'); assert.equal(tasks[0].assignedUserId, 9); }); test('automatic listing wrappers assign delegated work to the selected user and device', () => { const tasks = buildAutoListingDesktopTaskInputs({ id: 3, schemeCode: 'PLAN-3', listingShopId: 'shop-9', listingShopName: '旗舰店', listingShopSnapshot: { sessionId: '27', routingMode: 'delegated', executorUserId: 12, executorUserName: '同事甲', executorUsername: 'peer', executorClientId: 'device-12', }, listingTasks: [{ id: 17, taskCode: 'SF-17', listingStatus: 'pending', selectedSpuCode: 'SPU001', selectedProductTitle: '实木桌子', }], }, { id: 9, name: '发起人', username: 'requester' }); assert.equal(tasks[0].assignedUserId, 12); assert.equal(tasks[0].assignedUserName, '同事甲'); assert.equal(tasks[0].input.executorClientId, 'device-12'); assert.equal(tasks[0].input.executorSessionId, '27'); assert.equal(tasks[0].input.routingMode, 'delegated'); assert.equal(tasks[0].input.requestedByUserId, 9); });