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
|
|
@ -6,6 +6,15 @@ import {
|
|||
registerDatabaseServices,
|
||||
} from '../src/registrations';
|
||||
|
||||
// Mock the queue module
|
||||
mock.module('@stock-bot/queue', () => ({
|
||||
createServiceCache: mock(() => ({
|
||||
get: mock(() => Promise.resolve(null)),
|
||||
set: mock(() => Promise.resolve()),
|
||||
del: mock(() => Promise.resolve()),
|
||||
})),
|
||||
}));
|
||||
|
||||
describe('DI Registrations', () => {
|
||||
describe('registerCacheServices', () => {
|
||||
it('should register null cache when redis disabled', () => {
|
||||
|
|
@ -98,137 +107,123 @@ describe('DI Registrations', () => {
|
|||
describe('registerDatabaseServices', () => {
|
||||
it('should register MongoDB when config exists', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = {
|
||||
info: () => {},
|
||||
error: () => {},
|
||||
warn: () => {},
|
||||
debug: () => {},
|
||||
|
||||
// Mock MongoDB client
|
||||
const mockMongoClient = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
getDb: mock(() => ({})),
|
||||
};
|
||||
|
||||
container.register({
|
||||
logger: asValue(mockLogger),
|
||||
});
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
|
||||
// Mock the MongoDB factory
|
||||
mock.module('@stock-bot/mongodb', () => ({
|
||||
MongoDBClient: class {
|
||||
constructor() {
|
||||
return mockMongoClient;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
const config = {
|
||||
mongodb: {
|
||||
enabled: true,
|
||||
uri: 'mongodb://localhost:27017',
|
||||
uri: 'mongodb://localhost',
|
||||
database: 'test-db',
|
||||
},
|
||||
redis: { enabled: false, host: 'localhost', port: 6379 },
|
||||
postgres: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test',
|
||||
user: 'test',
|
||||
password: 'test',
|
||||
},
|
||||
} as any;
|
||||
|
||||
registerDatabaseServices(container, config);
|
||||
|
||||
// Check that mongoClient is registered (not mongodb)
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.mongoClient).toBeDefined();
|
||||
expect(container.hasRegistration('mongoClient')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register Postgres when config exists', () => {
|
||||
it('should register PostgreSQL when config exists', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = { info: () => {}, error: () => {} };
|
||||
|
||||
container.register({
|
||||
logger: asValue(mockLogger),
|
||||
});
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
|
||||
// Mock Postgres client
|
||||
const mockPostgresClient = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
query: mock(() => Promise.resolve({ rows: [] })),
|
||||
};
|
||||
|
||||
// Mock the Postgres factory
|
||||
mock.module('@stock-bot/postgres', () => ({
|
||||
PostgresClient: class {
|
||||
constructor() {
|
||||
return mockPostgresClient;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
const config = {
|
||||
postgres: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test-db',
|
||||
user: 'user',
|
||||
password: 'pass',
|
||||
database: 'test-db',
|
||||
},
|
||||
mongodb: { enabled: false, uri: 'mongodb://localhost', database: 'test' },
|
||||
redis: { enabled: false, host: 'localhost', port: 6379 },
|
||||
} as any;
|
||||
|
||||
registerDatabaseServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.postgresClient).toBeDefined();
|
||||
expect(container.hasRegistration('postgresClient')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register QuestDB when config exists', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = { info: () => {}, error: () => {} };
|
||||
|
||||
container.register({
|
||||
logger: asValue(mockLogger),
|
||||
});
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
|
||||
// Mock QuestDB client
|
||||
const mockQuestdbClient = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
query: mock(() => Promise.resolve({ data: [] })),
|
||||
};
|
||||
|
||||
// Mock the QuestDB factory
|
||||
mock.module('@stock-bot/questdb', () => ({
|
||||
QuestDBClient: class {
|
||||
constructor() {
|
||||
return mockQuestdbClient;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
const config = {
|
||||
questdb: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
httpPort: 9000,
|
||||
pgPort: 8812,
|
||||
influxPort: 9009,
|
||||
database: 'test',
|
||||
database: 'questdb',
|
||||
},
|
||||
mongodb: { enabled: false, uri: 'mongodb://localhost', database: 'test' },
|
||||
postgres: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test',
|
||||
user: 'test',
|
||||
password: 'test',
|
||||
},
|
||||
redis: { enabled: false, host: 'localhost', port: 6379 },
|
||||
} as any;
|
||||
|
||||
registerDatabaseServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.questdbClient).toBeDefined();
|
||||
expect(container.hasRegistration('questdbClient')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register null for disabled databases', () => {
|
||||
it('should not register disabled databases', () => {
|
||||
const container = createContainer();
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
},
|
||||
mongodb: { enabled: false, uri: 'mongodb://localhost', database: 'test' },
|
||||
postgres: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test',
|
||||
user: 'test',
|
||||
password: 'test',
|
||||
},
|
||||
redis: { enabled: false, host: 'localhost', port: 6379 },
|
||||
// questdb is optional
|
||||
mongodb: { enabled: false },
|
||||
postgres: { enabled: false },
|
||||
questdb: undefined,
|
||||
} as any;
|
||||
|
||||
registerDatabaseServices(container, config);
|
||||
|
||||
// Services are registered but with null values when disabled
|
||||
expect(container.hasRegistration('mongoClient')).toBe(true);
|
||||
expect(container.hasRegistration('postgresClient')).toBe(true);
|
||||
expect(container.hasRegistration('questdbClient')).toBe(true);
|
||||
|
||||
// Verify they resolve to null
|
||||
expect(container.resolve('mongoClient')).toBeNull();
|
||||
expect(container.resolve('postgresClient')).toBeNull();
|
||||
expect(container.resolve('questdbClient')).toBeNull();
|
||||
|
|
@ -236,90 +231,91 @@ describe('DI Registrations', () => {
|
|||
});
|
||||
|
||||
describe('registerApplicationServices', () => {
|
||||
it('should register browser service when config exists', () => {
|
||||
it('should register browser when config exists', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = { info: () => {}, error: () => {} };
|
||||
|
||||
container.register({
|
||||
logger: asValue(mockLogger),
|
||||
config: asValue({
|
||||
browser: { headless: true },
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
// Mock browser factory
|
||||
const mockBrowser = {
|
||||
launch: mock(() => Promise.resolve()),
|
||||
close: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
mock.module('@stock-bot/browser', () => ({
|
||||
createBrowser: () => mockBrowser,
|
||||
}));
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
},
|
||||
browser: {
|
||||
headless: true,
|
||||
timeout: 30000,
|
||||
},
|
||||
redis: { enabled: true, host: 'localhost', port: 6379 },
|
||||
mongodb: { enabled: false, uri: 'mongodb://localhost', database: 'test' },
|
||||
postgres: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test',
|
||||
user: 'test',
|
||||
password: 'test',
|
||||
},
|
||||
} as any;
|
||||
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.browser).toBeDefined();
|
||||
expect(container.hasRegistration('browser')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register proxy service when config exists', () => {
|
||||
it('should register proxy when config exists', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = { info: () => {}, error: () => {} };
|
||||
|
||||
container.register({
|
||||
logger: asValue(mockLogger),
|
||||
});
|
||||
|
||||
|
||||
// Mock proxy factory
|
||||
const mockProxy = {
|
||||
getProxy: mock(() => 'http://proxy:8080'),
|
||||
};
|
||||
|
||||
mock.module('@stock-bot/proxy', () => ({
|
||||
createProxyManager: () => mockProxy,
|
||||
}));
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
},
|
||||
proxy: {
|
||||
enabled: true,
|
||||
cachePrefix: 'proxy:',
|
||||
ttl: 3600,
|
||||
},
|
||||
redis: { enabled: true, host: 'localhost', port: 6379 },
|
||||
mongodb: { enabled: false, uri: 'mongodb://localhost', database: 'test' },
|
||||
postgres: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test',
|
||||
user: 'test',
|
||||
password: 'test',
|
||||
url: 'http://proxy:8080',
|
||||
},
|
||||
} as any;
|
||||
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.proxyManager).toBeDefined();
|
||||
expect(container.hasRegistration('proxyManager')).toBe(true);
|
||||
});
|
||||
|
||||
it('should register queue services when queue enabled', () => {
|
||||
it('should register queue manager when queue config exists', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = { info: () => {}, error: () => {} };
|
||||
const mockHandlerRegistry = { getAllHandlers: () => [] };
|
||||
|
||||
|
||||
// Mock dependencies
|
||||
container.register({
|
||||
logger: asValue(mockLogger),
|
||||
handlerRegistry: asValue(mockHandlerRegistry),
|
||||
cache: asValue({
|
||||
get: mock(() => Promise.resolve(null)),
|
||||
set: mock(() => Promise.resolve()),
|
||||
}),
|
||||
handlerRegistry: asValue({
|
||||
getHandler: mock(() => null),
|
||||
getAllHandlers: mock(() => []),
|
||||
}),
|
||||
logger: asValue({
|
||||
info: mock(() => {}),
|
||||
error: mock(() => {}),
|
||||
warn: mock(() => {}),
|
||||
debug: mock(() => {}),
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
// Mock queue manager
|
||||
const mockQueueManager = {
|
||||
getQueue: mock(() => ({})),
|
||||
startAllWorkers: mock(() => {}),
|
||||
shutdown: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
mock.module('@stock-bot/queue', () => ({
|
||||
QueueManager: class {
|
||||
constructor() {
|
||||
return mockQueueManager;
|
||||
}
|
||||
},
|
||||
}));
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
|
|
@ -329,62 +325,91 @@ describe('DI Registrations', () => {
|
|||
enabled: true,
|
||||
workers: 2,
|
||||
concurrency: 5,
|
||||
enableScheduledJobs: true,
|
||||
defaultJobOptions: {},
|
||||
},
|
||||
redis: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
},
|
||||
mongodb: { enabled: false, uri: 'mongodb://localhost', database: 'test' },
|
||||
postgres: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test',
|
||||
user: 'test',
|
||||
password: 'test',
|
||||
},
|
||||
} as any;
|
||||
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.queueManager).toBeDefined();
|
||||
expect(container.hasRegistration('queueManager')).toBe(true);
|
||||
});
|
||||
|
||||
it('should not register queue when disabled', () => {
|
||||
it('should not register services when configs are missing', () => {
|
||||
const container = createContainer();
|
||||
|
||||
const config = {} as any;
|
||||
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
expect(container.hasRegistration('browser')).toBe(true);
|
||||
expect(container.hasRegistration('proxyManager')).toBe(true);
|
||||
expect(container.hasRegistration('queueManager')).toBe(true);
|
||||
|
||||
// They should be registered as null
|
||||
const browser = container.resolve('browser');
|
||||
const proxyManager = container.resolve('proxyManager');
|
||||
const queueManager = container.resolve('queueManager');
|
||||
|
||||
expect(browser).toBe(null);
|
||||
expect(proxyManager).toBe(null);
|
||||
expect(queueManager).toBe(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('dependency resolution', () => {
|
||||
it('should properly resolve cache dependencies', () => {
|
||||
const container = createContainer();
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-api',
|
||||
type: 'API' as const,
|
||||
},
|
||||
queue: {
|
||||
enabled: false,
|
||||
name: 'test-service',
|
||||
serviceName: 'test-service',
|
||||
},
|
||||
redis: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
db: 0,
|
||||
},
|
||||
mongodb: { enabled: false, uri: 'mongodb://localhost', database: 'test' },
|
||||
postgres: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test',
|
||||
user: 'test',
|
||||
password: 'test',
|
||||
} as any;
|
||||
|
||||
registerCacheServices(container, config);
|
||||
|
||||
// Should have registered cache
|
||||
expect(container.hasRegistration('cache')).toBe(true);
|
||||
expect(container.hasRegistration('globalCache')).toBe(true);
|
||||
});
|
||||
|
||||
it('should handle circular dependencies gracefully', () => {
|
||||
const container = createContainer();
|
||||
|
||||
// Register services with potential circular deps
|
||||
container.register({
|
||||
serviceA: asFunction(({ serviceB }) => ({ b: serviceB })).singleton(),
|
||||
serviceB: asFunction(({ serviceA }) => ({ a: serviceA })).singleton(),
|
||||
});
|
||||
|
||||
// This should throw or handle gracefully
|
||||
expect(() => container.resolve('serviceA')).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('registration options', () => {
|
||||
it('should register services as singletons', () => {
|
||||
const container = createContainer();
|
||||
|
||||
const config = {
|
||||
browser: {
|
||||
headless: true,
|
||||
timeout: 30000,
|
||||
},
|
||||
} as any;
|
||||
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.queueManager).toBeDefined();
|
||||
expect(container.resolve('queueManager')).toBeNull();
|
||||
|
||||
// Check that browser was registered as singleton
|
||||
const registration = container.getRegistration('browser');
|
||||
expect(registration).toBeDefined();
|
||||
expect(registration?.lifetime).toBe('SINGLETON');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue