added cli-covarage tool and fixed more tests
This commit is contained in:
parent
b63e58784c
commit
b845a8eade
57 changed files with 11917 additions and 295 deletions
215
libs/core/handlers/test/base-handler-config.test.ts
Normal file
215
libs/core/handlers/test/base-handler-config.test.ts
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
import { describe, it, expect, beforeEach, mock } from 'bun:test';
|
||||
import { BaseHandler } from '../src/base/BaseHandler';
|
||||
import type { IServiceContainer, ExecutionContext } from '@stock-bot/types';
|
||||
|
||||
// Test handler with metadata
|
||||
class ConfigTestHandler extends BaseHandler {
|
||||
static __handlerName = 'config-test';
|
||||
static __operations = [
|
||||
{ name: 'process', method: 'processData' },
|
||||
{ name: 'validate', method: 'validateData' },
|
||||
];
|
||||
static __schedules = [
|
||||
{
|
||||
operation: 'processData',
|
||||
cronPattern: '0 * * * *',
|
||||
priority: 5,
|
||||
immediately: false,
|
||||
description: 'Hourly processing',
|
||||
payload: { type: 'scheduled' },
|
||||
batch: { size: 100 },
|
||||
},
|
||||
];
|
||||
static __description = 'Test handler for configuration';
|
||||
|
||||
async processData(input: any, context: ExecutionContext) {
|
||||
return { processed: true, input };
|
||||
}
|
||||
|
||||
async validateData(input: any, context: ExecutionContext) {
|
||||
return { valid: true, input };
|
||||
}
|
||||
}
|
||||
|
||||
// Handler without metadata
|
||||
class NoMetadataHandler extends BaseHandler {}
|
||||
|
||||
describe('BaseHandler Configuration', () => {
|
||||
let mockServices: IServiceContainer;
|
||||
|
||||
beforeEach(() => {
|
||||
mockServices = {
|
||||
cache: null,
|
||||
globalCache: null,
|
||||
queueManager: null,
|
||||
proxy: null,
|
||||
browser: null,
|
||||
mongodb: null,
|
||||
postgres: null,
|
||||
questdb: null,
|
||||
} as any;
|
||||
});
|
||||
|
||||
describe('createHandlerConfig', () => {
|
||||
it('should create handler config from metadata', () => {
|
||||
const handler = new ConfigTestHandler(mockServices);
|
||||
const config = handler.createHandlerConfig();
|
||||
|
||||
expect(config.name).toBe('config-test');
|
||||
expect(Object.keys(config.operations)).toEqual(['process', 'validate']);
|
||||
expect(config.scheduledJobs).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should create job handlers for operations', () => {
|
||||
const handler = new ConfigTestHandler(mockServices);
|
||||
const config = handler.createHandlerConfig();
|
||||
|
||||
expect(typeof config.operations.process).toBe('function');
|
||||
expect(typeof config.operations.validate).toBe('function');
|
||||
});
|
||||
|
||||
it('should include scheduled job details', () => {
|
||||
const handler = new ConfigTestHandler(mockServices);
|
||||
const config = handler.createHandlerConfig();
|
||||
|
||||
const scheduledJob = config.scheduledJobs[0];
|
||||
expect(scheduledJob.type).toBe('config-test-processData');
|
||||
expect(scheduledJob.operation).toBe('process');
|
||||
expect(scheduledJob.cronPattern).toBe('0 * * * *');
|
||||
expect(scheduledJob.priority).toBe(5);
|
||||
expect(scheduledJob.immediately).toBe(false);
|
||||
expect(scheduledJob.description).toBe('Hourly processing');
|
||||
expect(scheduledJob.payload).toEqual({ type: 'scheduled' });
|
||||
expect(scheduledJob.batch).toEqual({ size: 100 });
|
||||
});
|
||||
|
||||
it('should execute operations through job handlers', async () => {
|
||||
const handler = new ConfigTestHandler(mockServices);
|
||||
const config = handler.createHandlerConfig();
|
||||
|
||||
// Mock the job execution
|
||||
const processJob = config.operations.process;
|
||||
const result = await processJob({ data: 'test' }, {} as any);
|
||||
|
||||
expect(result).toEqual({ processed: true, input: { data: 'test' } });
|
||||
});
|
||||
|
||||
it('should throw error when no metadata found', () => {
|
||||
const handler = new NoMetadataHandler(mockServices);
|
||||
|
||||
expect(() => handler.createHandlerConfig()).toThrow('Handler metadata not found');
|
||||
});
|
||||
|
||||
it('should handle schedule without matching operation', () => {
|
||||
class ScheduleOnlyHandler extends BaseHandler {
|
||||
static __handlerName = 'schedule-only';
|
||||
static __operations = [];
|
||||
static __schedules = [
|
||||
{
|
||||
operation: 'nonExistentMethod',
|
||||
cronPattern: '* * * * *',
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
const handler = new ScheduleOnlyHandler(mockServices);
|
||||
const config = handler.createHandlerConfig();
|
||||
|
||||
expect(config.operations).toEqual({});
|
||||
expect(config.scheduledJobs).toHaveLength(1);
|
||||
expect(config.scheduledJobs[0].operation).toBe('nonExistentMethod');
|
||||
});
|
||||
|
||||
it('should handle empty schedules array', () => {
|
||||
class NoScheduleHandler extends BaseHandler {
|
||||
static __handlerName = 'no-schedule';
|
||||
static __operations = [{ name: 'test', method: 'testMethod' }];
|
||||
static __schedules = [];
|
||||
|
||||
testMethod() {}
|
||||
}
|
||||
|
||||
const handler = new NoScheduleHandler(mockServices);
|
||||
const config = handler.createHandlerConfig();
|
||||
|
||||
expect(config.scheduledJobs).toEqual([]);
|
||||
expect(config.operations).toHaveProperty('test');
|
||||
});
|
||||
|
||||
it('should create execution context with proper metadata', async () => {
|
||||
const handler = new ConfigTestHandler(mockServices);
|
||||
const config = handler.createHandlerConfig();
|
||||
|
||||
// Spy on execute method
|
||||
const executeSpy = mock();
|
||||
handler.execute = executeSpy;
|
||||
executeSpy.mockResolvedValue({ result: 'test' });
|
||||
|
||||
// Execute through job handler
|
||||
await config.operations.process({ input: 'data' }, {} as any);
|
||||
|
||||
expect(executeSpy).toHaveBeenCalledWith(
|
||||
'process',
|
||||
{ input: 'data' },
|
||||
expect.objectContaining({
|
||||
type: 'queue',
|
||||
metadata: expect.objectContaining({
|
||||
source: 'queue',
|
||||
timestamp: expect.any(Number),
|
||||
}),
|
||||
})
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('extractMetadata', () => {
|
||||
it('should extract complete metadata', () => {
|
||||
const metadata = ConfigTestHandler.extractMetadata();
|
||||
|
||||
expect(metadata).not.toBeNull();
|
||||
expect(metadata?.name).toBe('config-test');
|
||||
expect(metadata?.operations).toEqual(['process', 'validate']);
|
||||
expect(metadata?.description).toBe('Test handler for configuration');
|
||||
expect(metadata?.scheduledJobs).toHaveLength(1);
|
||||
});
|
||||
|
||||
it('should return null for handler without metadata', () => {
|
||||
const metadata = NoMetadataHandler.extractMetadata();
|
||||
expect(metadata).toBeNull();
|
||||
});
|
||||
|
||||
it('should handle missing optional fields', () => {
|
||||
class MinimalHandler extends BaseHandler {
|
||||
static __handlerName = 'minimal';
|
||||
static __operations = [];
|
||||
}
|
||||
|
||||
const metadata = MinimalHandler.extractMetadata();
|
||||
|
||||
expect(metadata).not.toBeNull();
|
||||
expect(metadata?.name).toBe('minimal');
|
||||
expect(metadata?.operations).toEqual([]);
|
||||
expect(metadata?.scheduledJobs).toEqual([]);
|
||||
expect(metadata?.description).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should map schedule operations correctly', () => {
|
||||
class MappedScheduleHandler extends BaseHandler {
|
||||
static __handlerName = 'mapped';
|
||||
static __operations = [
|
||||
{ name: 'op1', method: 'method1' },
|
||||
{ name: 'op2', method: 'method2' },
|
||||
];
|
||||
static __schedules = [
|
||||
{ operation: 'method1', cronPattern: '* * * * *' },
|
||||
{ operation: 'method2', cronPattern: '0 * * * *' },
|
||||
];
|
||||
}
|
||||
|
||||
const metadata = MappedScheduleHandler.extractMetadata();
|
||||
|
||||
expect(metadata?.scheduledJobs[0].operation).toBe('op1');
|
||||
expect(metadata?.scheduledJobs[1].operation).toBe('op2');
|
||||
});
|
||||
});
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue