tests
This commit is contained in:
parent
54f37f9521
commit
3a7254708e
19 changed files with 1560 additions and 1237 deletions
|
|
@ -1,30 +1,63 @@
|
|||
import { beforeEach, describe, expect, it, mock } from 'bun:test';
|
||||
import type { ExecutionContext, IServiceContainer } from '@stock-bot/types';
|
||||
import { beforeEach, describe, expect, it, mock, type Mock } from 'bun:test';
|
||||
import type { ExecutionContext, IServiceContainer, ServiceTypes } from '@stock-bot/types';
|
||||
import { BaseHandler } from '../src/base/BaseHandler';
|
||||
import { Handler, Operation, QueueSchedule, ScheduledOperation } from '../src/decorators/decorators';
|
||||
import { createJobHandler } from '../src/utils/create-job-handler';
|
||||
import type { Logger } from '@stock-bot/logger';
|
||||
import type { QueueManager, Queue } from '@stock-bot/queue';
|
||||
import type { CacheProvider } from '@stock-bot/cache';
|
||||
|
||||
type MockLogger = {
|
||||
info: Mock<(message: string, meta?: any) => void>;
|
||||
error: Mock<(message: string, meta?: any) => void>;
|
||||
warn: Mock<(message: string, meta?: any) => void>;
|
||||
debug: Mock<(message: string, meta?: any) => void>;
|
||||
};
|
||||
|
||||
type MockQueue = {
|
||||
add: Mock<(name: string, data: any, options?: any) => Promise<void>>;
|
||||
};
|
||||
|
||||
type MockQueueManager = {
|
||||
getQueue: Mock<(name: string) => MockQueue>;
|
||||
};
|
||||
|
||||
type MockCache = {
|
||||
get: Mock<(key: string) => Promise<any>>;
|
||||
set: Mock<(key: string, value: any, ttl?: number) => Promise<void>>;
|
||||
del: Mock<(key: string) => Promise<void>>;
|
||||
};
|
||||
|
||||
// Mock service container
|
||||
const createMockServices = (): IServiceContainer => ({
|
||||
logger: {
|
||||
const createMockServices = (): IServiceContainer => {
|
||||
const mockLogger: MockLogger = {
|
||||
info: mock(() => {}),
|
||||
error: mock(() => {}),
|
||||
warn: mock(() => {}),
|
||||
debug: mock(() => {}),
|
||||
} as any,
|
||||
cache: null,
|
||||
globalCache: null,
|
||||
queueManager: {
|
||||
getQueue: mock(() => ({
|
||||
add: mock(() => Promise.resolve()),
|
||||
})),
|
||||
} as any,
|
||||
proxy: null,
|
||||
browser: null,
|
||||
mongodb: null,
|
||||
postgres: null,
|
||||
questdb: null,
|
||||
});
|
||||
};
|
||||
|
||||
const mockQueue: MockQueue = {
|
||||
add: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockQueueManager: MockQueueManager = {
|
||||
getQueue: mock(() => mockQueue),
|
||||
};
|
||||
|
||||
return {
|
||||
logger: mockLogger as unknown as ServiceTypes['logger'],
|
||||
cache: null,
|
||||
globalCache: null,
|
||||
queueManager: mockQueueManager as unknown as ServiceTypes['queueManager'],
|
||||
proxy: null,
|
||||
browser: null,
|
||||
mongodb: null,
|
||||
postgres: null,
|
||||
questdb: null,
|
||||
queue: mockQueue as unknown as ServiceTypes['queue'],
|
||||
};
|
||||
};
|
||||
|
||||
describe('BaseHandler', () => {
|
||||
let mockServices: IServiceContainer;
|
||||
|
|
@ -43,7 +76,7 @@ describe('BaseHandler', () => {
|
|||
@Handler('test')
|
||||
class TestHandler extends BaseHandler {
|
||||
@Operation('testOp')
|
||||
async handleTestOp(payload: any) {
|
||||
async handleTestOp(payload: unknown) {
|
||||
return { result: 'success', payload };
|
||||
}
|
||||
}
|
||||
|
|
@ -74,18 +107,19 @@ describe('BaseHandler', () => {
|
|||
});
|
||||
|
||||
it('should schedule operations', async () => {
|
||||
const mockQueue = {
|
||||
const mockQueue: MockQueue = {
|
||||
add: mock(() => Promise.resolve()),
|
||||
};
|
||||
mockServices.queueManager = {
|
||||
const mockQueueManager: MockQueueManager = {
|
||||
getQueue: mock(() => mockQueue),
|
||||
} as any;
|
||||
};
|
||||
mockServices.queueManager = mockQueueManager as unknown as ServiceTypes['queueManager'];
|
||||
|
||||
const handler = new BaseHandler(mockServices, 'test-handler');
|
||||
|
||||
await handler.scheduleOperation('test-op', { data: 'test' }, { delay: 1000 });
|
||||
|
||||
expect(mockServices.queueManager.getQueue).toHaveBeenCalledWith('test-handler');
|
||||
expect(mockQueueManager.getQueue).toHaveBeenCalledWith('test-handler');
|
||||
expect(mockQueue.add).toHaveBeenCalledWith(
|
||||
'test-op',
|
||||
{
|
||||
|
|
@ -99,13 +133,13 @@ describe('BaseHandler', () => {
|
|||
|
||||
describe('cache helpers', () => {
|
||||
it('should handle cache operations with namespace', async () => {
|
||||
const mockCache = {
|
||||
const mockCache: MockCache = {
|
||||
set: mock(() => Promise.resolve()),
|
||||
get: mock(() => Promise.resolve('cached-value')),
|
||||
del: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
mockServices.cache = mockCache as any;
|
||||
mockServices.cache = mockCache as unknown as ServiceTypes['cache'];
|
||||
const handler = new BaseHandler(mockServices, 'my-handler');
|
||||
|
||||
await handler['cacheSet']('key', 'value', 3600);
|
||||
|
|
@ -164,7 +198,8 @@ describe('Decorators', () => {
|
|||
@Handler('test-handler')
|
||||
class TestClass {}
|
||||
|
||||
expect((TestClass as any).__handlerName).toBe('test-handler');
|
||||
const decoratedClass = TestClass as typeof TestClass & { __handlerName: string };
|
||||
expect(decoratedClass.__handlerName).toBe('test-handler');
|
||||
});
|
||||
|
||||
it('should apply Operation decorator', () => {
|
||||
|
|
@ -173,7 +208,10 @@ describe('Decorators', () => {
|
|||
myMethod() {}
|
||||
}
|
||||
|
||||
const operations = (TestClass as any).__operations;
|
||||
const decoratedClass = TestClass as typeof TestClass & {
|
||||
__operations: Array<{ name: string; method: string }>;
|
||||
};
|
||||
const operations = decoratedClass.__operations;
|
||||
expect(operations).toBeDefined();
|
||||
expect(operations).toHaveLength(1);
|
||||
expect(operations[0]).toMatchObject({
|
||||
|
|
@ -192,7 +230,16 @@ describe('Decorators', () => {
|
|||
scheduledMethod() {}
|
||||
}
|
||||
|
||||
const schedules = (TestClass as any).__schedules;
|
||||
const decoratedClass = TestClass as typeof TestClass & {
|
||||
__schedules: Array<{
|
||||
operation: string;
|
||||
cronPattern: string;
|
||||
priority: number;
|
||||
payload: any;
|
||||
batch: { size: number; delayInHours: number };
|
||||
}>;
|
||||
};
|
||||
const schedules = decoratedClass.__schedules;
|
||||
expect(schedules).toBeDefined();
|
||||
expect(schedules).toHaveLength(1);
|
||||
expect(schedules[0]).toMatchObject({
|
||||
|
|
@ -210,7 +257,14 @@ describe('Decorators', () => {
|
|||
queueMethod() {}
|
||||
}
|
||||
|
||||
const schedules = (TestClass as any).__schedules;
|
||||
const decoratedClass = TestClass as typeof TestClass & {
|
||||
__schedules: Array<{
|
||||
operation: string;
|
||||
cronPattern: string;
|
||||
priority: number;
|
||||
}>;
|
||||
};
|
||||
const schedules = decoratedClass.__schedules;
|
||||
expect(schedules).toBeDefined();
|
||||
expect(schedules[0]).toMatchObject({
|
||||
operation: 'queueMethod',
|
||||
|
|
@ -222,7 +276,13 @@ describe('Decorators', () => {
|
|||
|
||||
describe('createJobHandler', () => {
|
||||
it('should create a job handler', async () => {
|
||||
const handlerFn = mock(async (payload: any) => ({ success: true, payload }));
|
||||
type TestPayload = { data: string };
|
||||
type TestResult = { success: boolean; payload: TestPayload };
|
||||
|
||||
const handlerFn = mock(async (payload: TestPayload): Promise<TestResult> => ({
|
||||
success: true,
|
||||
payload
|
||||
}));
|
||||
const jobHandler = createJobHandler(handlerFn);
|
||||
|
||||
const result = await jobHandler({ data: 'test' });
|
||||
|
|
@ -239,4 +299,4 @@ describe('createJobHandler', () => {
|
|||
|
||||
await expect(jobHandler({})).rejects.toThrow('Handler error');
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue