UNPKG

@cadence-mq/core

Version:

Modern, type-safe, and performant task queue for Node.js

123 lines (100 loc) 3.55 kB
import type { TaskContext, TaskDefinition } from '../tasks/tasks.types'; import type { Job } from './jobs.types'; import { describe, expect, test } from 'vitest'; import { processJob } from './jobs.usecases'; describe('jobs usecases', () => { describe('processJob', () => { const taskExecutionContext: TaskContext = { workerId: 'test-worker-id', }; const job: Job = { id: 'test-job-id', taskName: 'test-task-name', status: 'pending', data: { test: 'test', }, scheduledAt: new Date('2025-01-01'), }; test('execute the task handler for a job, providing the job data and the task execution context and returning the handler result', async () => { const handlerArgs: unknown[] = []; const result = await processJob({ job, taskExecutionContext, taskDefinition: { taskName: 'test-task-name', handler: async (args) => { handlerArgs.push(args); return { foo: 'bar', }; }, }, }); expect(handlerArgs).eql([{ data: { test: 'test' }, context: taskExecutionContext, }]); expect(result).eql({ foo: 'bar' }); }); test('if the task fails, by default the error is thrown', async () => { const taskDefinition: TaskDefinition = { taskName: 'test-task-name', handler: async () => { throw new Error('test'); }, }; await expect(processJob({ job, taskDefinition, taskExecutionContext })).rejects.toThrow('test'); }); test('a retry can be configured on the task definition, and the job will be retried up to the configured number of times', async () => { let attempts = 0; const taskDefinition: TaskDefinition = { taskName: 'test-task-name', handler: async () => { attempts++; throw new Error('test'); }, options: { maxRetries: 2, }, }; await expect(processJob({ job, taskDefinition, taskExecutionContext })).rejects.toThrow('test'); expect(attempts).eql(3); }); test('the retry count can be configured per job', async () => { let attempts = 0; const taskDefinition: TaskDefinition = { taskName: 'test-task-name', handler: async () => { attempts++; throw new Error('test'); }, }; await expect(processJob({ job: { ...job, maxRetries: 1 }, taskDefinition, taskExecutionContext })).rejects.toThrow('test'); expect(attempts).eql(2); }); test('when both the task definition and the job have a retry count configured, the job retry count takes precedence', async () => { let attempts = 0; const taskDefinition: TaskDefinition = { taskName: 'test-task-name', handler: async () => { attempts++; throw new Error('test'); }, options: { maxRetries: 2, }, }; await expect(processJob({ job: { ...job, maxRetries: 1 }, taskDefinition, taskExecutionContext })).rejects.toThrow('test'); expect(attempts).eql(2); }); test('when the handler returns void, the result is coerced to undefined', async () => { const taskDefinition: TaskDefinition = { taskName: 'test-task-name', handler: async () => {}, }; const result = await processJob({ job, taskDefinition, taskExecutionContext }); expect(result).eql(undefined); }); }); });