Files
qipai/backend/tests/task-repository.test.mjs
2026-06-18 10:20:39 +08:00

88 lines
2.3 KiB
JavaScript

import assert from 'node:assert/strict';
import { OutboxRepository } from '../dist/tasks/outbox-repository.js';
import { retryDelayMs, taskTypes } from '../dist/tasks/task-repository.js';
import { TaskWorker } from '../dist/tasks/worker.js';
assert.deepEqual(taskTypes, [
'notification.dispatch',
'order.advance',
'device.command',
'refund.query',
'statistics.aggregate',
'outbox.publish'
]);
assert.equal(retryDelayMs(1), 1000);
assert.equal(retryDelayMs(4), 8000);
assert.equal(retryDelayMs(99), 60 * 60 * 1000);
const outboxCalls = [];
const outbox = new OutboxRepository({
async execute(sql, params) {
outboxCalls.push([sql, params]);
return [{ insertId: 7, affectedRows: 1 }, []];
}
});
assert.deepEqual(
await outbox.append({
tenantId: '1',
aggregateType: 'order',
aggregateId: '88',
eventType: 'order.paid',
idempotencyKey: 'order:88:paid',
payload: { orderId: '88' }
}),
{ id: '7', created: true }
);
assert.match(outboxCalls[0][0], /INSERT IGNORE INTO qipai_outbox_events/);
const calls = [];
const task = {
id: '42',
tenantId: '1',
taskType: 'notification.dispatch',
idempotencyKey: 'notice:42',
payload: { channel: 'test' },
status: 'RUNNING',
attempts: 1,
maxAttempts: 3
};
const repository = {
async claimNext() {
calls.push('claim');
return task;
},
async complete(id) {
calls.push(`complete:${id}`);
return true;
},
async fail() {
calls.push('fail');
}
};
const worker = new TaskWorker({
repository,
handlers: new Map([['notification.dispatch', async (claimed) => {
calls.push(`handle:${claimed.id}`);
}]]),
workerId: 'test-worker'
});
assert.equal(await worker.runOnce(), true);
assert.deepEqual(calls, ['claim', 'handle:42', 'complete:42']);
const failedCalls = [];
const failedWorker = new TaskWorker({
repository: {
async claimNext() { return task; },
async complete() { return true; },
async fail(claimed, workerId, error) {
failedCalls.push([claimed.id, workerId, error.message]);
}
},
handlers: new Map(),
workerId: 'test-worker'
});
assert.equal(await failedWorker.runOnce(), true);
assert.deepEqual(failedCalls, [['42', 'test-worker', 'No handler registered for task type notification.dispatch.']]);
console.log('PASS: M01-C task retry and worker contracts are present.');