tests
This commit is contained in:
parent
54f37f9521
commit
3a7254708e
19 changed files with 1560 additions and 1237 deletions
|
|
@ -1,46 +1,93 @@
|
|||
import { describe, expect, it } from 'bun:test';
|
||||
import { describe, expect, it, mock } from 'bun:test';
|
||||
import { createContainer, asValue } from 'awilix';
|
||||
import type { AwilixContainer } from 'awilix';
|
||||
import { CacheFactory } from '../src/factories';
|
||||
import type { CacheProvider } from '@stock-bot/cache';
|
||||
import type { ServiceDefinitions } from '../src/container/types';
|
||||
|
||||
describe('DI Factories', () => {
|
||||
describe('CacheFactory', () => {
|
||||
const mockCache: CacheProvider = {
|
||||
get: mock(async () => null),
|
||||
set: mock(async () => {}),
|
||||
del: mock(async () => {}),
|
||||
clear: mock(async () => {}),
|
||||
has: mock(async () => false),
|
||||
keys: mock(async () => []),
|
||||
ttl: mock(async () => -1),
|
||||
type: 'memory',
|
||||
};
|
||||
|
||||
const createMockContainer = (cache: CacheProvider | null = mockCache): AwilixContainer<ServiceDefinitions> => {
|
||||
const container = createContainer<ServiceDefinitions>();
|
||||
container.register({
|
||||
cache: asValue(cache),
|
||||
});
|
||||
return container;
|
||||
};
|
||||
|
||||
it('should be exported', () => {
|
||||
expect(CacheFactory).toBeDefined();
|
||||
});
|
||||
|
||||
it('should create cache with configuration', () => {
|
||||
const cacheConfig = {
|
||||
redisConfig: {
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
db: 1,
|
||||
},
|
||||
keyPrefix: 'test:',
|
||||
};
|
||||
|
||||
const cache = CacheFactory.create(cacheConfig);
|
||||
expect(cache).toBeDefined();
|
||||
it('should create namespaced cache', () => {
|
||||
const namespacedCache = CacheFactory.createNamespacedCache(mockCache, 'test-namespace');
|
||||
|
||||
expect(namespacedCache).toBeDefined();
|
||||
expect(namespacedCache).toBeInstanceOf(Object);
|
||||
// NamespacedCache wraps the base cache but doesn't expose type property
|
||||
});
|
||||
|
||||
it('should create null cache without config', () => {
|
||||
const cache = CacheFactory.create();
|
||||
expect(cache).toBeDefined();
|
||||
expect(cache.type).toBe('null');
|
||||
it('should create cache for service', () => {
|
||||
const container = createMockContainer();
|
||||
|
||||
const serviceCache = CacheFactory.createCacheForService(container, 'test-service');
|
||||
|
||||
expect(serviceCache).toBeDefined();
|
||||
expect(serviceCache).not.toBe(mockCache); // Should be a new namespaced instance
|
||||
});
|
||||
|
||||
it('should create cache with logger', () => {
|
||||
const mockLogger = {
|
||||
info: () => {},
|
||||
error: () => {},
|
||||
warn: () => {},
|
||||
debug: () => {},
|
||||
};
|
||||
it('should return null when no base cache available', () => {
|
||||
const container = createMockContainer(null);
|
||||
|
||||
const serviceCache = CacheFactory.createCacheForService(container, 'test-service');
|
||||
|
||||
expect(serviceCache).toBeNull();
|
||||
});
|
||||
|
||||
const cacheConfig = {
|
||||
logger: mockLogger,
|
||||
};
|
||||
it('should create cache for handler with prefix', () => {
|
||||
const container = createMockContainer();
|
||||
|
||||
const handlerCache = CacheFactory.createCacheForHandler(container, 'TestHandler');
|
||||
|
||||
expect(handlerCache).toBeDefined();
|
||||
// The namespace should include 'handler:' prefix
|
||||
});
|
||||
|
||||
const cache = CacheFactory.create(cacheConfig);
|
||||
expect(cache).toBeDefined();
|
||||
it('should create cache with custom prefix', () => {
|
||||
const container = createMockContainer();
|
||||
|
||||
const prefixedCache = CacheFactory.createCacheWithPrefix(container, 'custom-prefix');
|
||||
|
||||
expect(prefixedCache).toBeDefined();
|
||||
});
|
||||
|
||||
it('should clean duplicate cache: prefix', () => {
|
||||
const container = createMockContainer();
|
||||
|
||||
// Should handle prefix that already includes 'cache:'
|
||||
const prefixedCache = CacheFactory.createCacheWithPrefix(container, 'cache:custom-prefix');
|
||||
|
||||
expect(prefixedCache).toBeDefined();
|
||||
// Internally it should strip the duplicate 'cache:' prefix
|
||||
});
|
||||
|
||||
it('should handle null cache in all factory methods', () => {
|
||||
const container = createMockContainer(null);
|
||||
|
||||
expect(CacheFactory.createCacheForService(container, 'service')).toBeNull();
|
||||
expect(CacheFactory.createCacheForHandler(container, 'handler')).toBeNull();
|
||||
expect(CacheFactory.createCacheWithPrefix(container, 'prefix')).toBeNull();
|
||||
});
|
||||
});
|
||||
})
|
||||
});
|
||||
|
|
@ -3,26 +3,29 @@ import { createContainer, asClass, asFunction, asValue } from 'awilix';
|
|||
import {
|
||||
registerCacheServices,
|
||||
registerDatabaseServices,
|
||||
registerServiceDependencies,
|
||||
registerApplicationServices,
|
||||
} from '../src/registrations';
|
||||
|
||||
describe('DI Registrations', () => {
|
||||
describe('registerCacheServices', () => {
|
||||
it('should register null cache when no redis config', () => {
|
||||
it('should register null cache when redis disabled', () => {
|
||||
const container = createContainer();
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
},
|
||||
// No redis config
|
||||
};
|
||||
redis: {
|
||||
enabled: false,
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
},
|
||||
} as any;
|
||||
|
||||
registerCacheServices(container, config);
|
||||
|
||||
const cache = container.resolve('cache');
|
||||
expect(cache).toBeDefined();
|
||||
expect(cache.type).toBe('null'); // NullCache type
|
||||
expect(cache).toBeNull();
|
||||
});
|
||||
|
||||
it('should register redis cache when redis config exists', () => {
|
||||
|
|
@ -44,11 +47,12 @@ describe('DI Registrations', () => {
|
|||
type: 'WORKER' as const,
|
||||
},
|
||||
redis: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
db: 1,
|
||||
},
|
||||
};
|
||||
} as any;
|
||||
|
||||
registerCacheServices(container, config);
|
||||
|
||||
|
|
@ -56,30 +60,38 @@ describe('DI Registrations', () => {
|
|||
expect(cache).toBeDefined();
|
||||
});
|
||||
|
||||
it('should register service cache', () => {
|
||||
it('should register both cache and globalCache', () => {
|
||||
const container = createContainer();
|
||||
|
||||
// Register dependencies
|
||||
// Register logger dependency
|
||||
container.register({
|
||||
cache: asValue({ type: 'null' }),
|
||||
config: asValue({
|
||||
service: { name: 'test-service' },
|
||||
redis: { host: 'localhost', port: 6379 },
|
||||
logger: asValue({
|
||||
info: () => {},
|
||||
error: () => {},
|
||||
warn: () => {},
|
||||
debug: () => {},
|
||||
}),
|
||||
logger: asValue({ info: () => {} }),
|
||||
});
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
serviceName: 'test-service',
|
||||
},
|
||||
};
|
||||
redis: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
port: 6379,
|
||||
db: 1,
|
||||
},
|
||||
} as any;
|
||||
|
||||
registerCacheServices(container, config);
|
||||
|
||||
const serviceCache = container.resolve('serviceCache');
|
||||
expect(serviceCache).toBeDefined();
|
||||
const cache = container.resolve('cache');
|
||||
const globalCache = container.resolve('globalCache');
|
||||
expect(cache).toBeDefined();
|
||||
expect(globalCache).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -103,16 +115,19 @@ describe('DI Registrations', () => {
|
|||
type: 'WORKER' as const,
|
||||
},
|
||||
mongodb: {
|
||||
enabled: true,
|
||||
uri: 'mongodb://localhost:27017',
|
||||
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 mongodb is registered
|
||||
// Check that mongoClient is registered (not mongodb)
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.mongodb).toBeDefined();
|
||||
expect(registrations.mongoClient).toBeDefined();
|
||||
});
|
||||
|
||||
it('should register Postgres when config exists', () => {
|
||||
|
|
@ -129,18 +144,21 @@ describe('DI Registrations', () => {
|
|||
type: 'WORKER' as const,
|
||||
},
|
||||
postgres: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
port: 5432,
|
||||
database: 'test-db',
|
||||
username: 'user',
|
||||
user: 'user',
|
||||
password: 'pass',
|
||||
},
|
||||
};
|
||||
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.postgres).toBeDefined();
|
||||
expect(registrations.postgresClient).toBeDefined();
|
||||
});
|
||||
|
||||
it('should register QuestDB when config exists', () => {
|
||||
|
|
@ -157,38 +175,46 @@ describe('DI Registrations', () => {
|
|||
type: 'WORKER' as const,
|
||||
},
|
||||
questdb: {
|
||||
enabled: true,
|
||||
host: 'localhost',
|
||||
httpPort: 9000,
|
||||
pgPort: 8812,
|
||||
influxPort: 9009,
|
||||
database: 'test',
|
||||
},
|
||||
};
|
||||
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.questdb).toBeDefined();
|
||||
expect(registrations.questdbClient).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not register databases without config', () => {
|
||||
it('should register null for disabled databases', () => {
|
||||
const container = createContainer();
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
},
|
||||
// No database configs
|
||||
};
|
||||
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
|
||||
} as any;
|
||||
|
||||
registerDatabaseServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.mongodb).toBeUndefined();
|
||||
expect(registrations.postgres).toBeUndefined();
|
||||
expect(registrations.questdb).toBeUndefined();
|
||||
expect(container.resolve('mongoClient')).toBeNull();
|
||||
expect(container.resolve('postgresClient')).toBeNull();
|
||||
expect(container.resolve('questdbClient')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('registerServiceDependencies', () => {
|
||||
describe('registerApplicationServices', () => {
|
||||
it('should register browser service when config exists', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = { info: () => {}, error: () => {} };
|
||||
|
|
@ -209,9 +235,12 @@ describe('DI Registrations', () => {
|
|||
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;
|
||||
|
||||
registerServiceDependencies(container, config);
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.browser).toBeDefined();
|
||||
|
|
@ -232,62 +261,81 @@ describe('DI Registrations', () => {
|
|||
},
|
||||
proxy: {
|
||||
enabled: true,
|
||||
rotateOnError: 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' },
|
||||
} as any;
|
||||
|
||||
registerServiceDependencies(container, config);
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.proxyManager).toBeDefined();
|
||||
});
|
||||
|
||||
it('should register queue services for worker type', () => {
|
||||
it('should register queue services when queue enabled', () => {
|
||||
const container = createContainer();
|
||||
const mockLogger = { info: () => {}, error: () => {} };
|
||||
const mockHandlerRegistry = { getAllHandlers: () => [] };
|
||||
|
||||
container.register({
|
||||
logger: asValue(mockLogger),
|
||||
config: asValue({
|
||||
service: { name: 'test-service', type: 'WORKER' },
|
||||
redis: { host: 'localhost', port: 6379 },
|
||||
}),
|
||||
handlerRegistry: asValue(mockHandlerRegistry),
|
||||
});
|
||||
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-service',
|
||||
type: 'WORKER' as const,
|
||||
serviceName: 'test-service',
|
||||
},
|
||||
queue: {
|
||||
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;
|
||||
|
||||
registerServiceDependencies(container, config);
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.queueManager).toBeDefined();
|
||||
});
|
||||
|
||||
it('should not register queue for API type', () => {
|
||||
it('should not register queue when disabled', () => {
|
||||
const container = createContainer();
|
||||
const config = {
|
||||
service: {
|
||||
name: 'test-api',
|
||||
type: 'API' as const,
|
||||
},
|
||||
queue: {
|
||||
enabled: false,
|
||||
},
|
||||
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;
|
||||
|
||||
registerServiceDependencies(container, config);
|
||||
registerApplicationServices(container, config);
|
||||
|
||||
const registrations = container.registrations;
|
||||
expect(registrations.queueManager).toBeUndefined();
|
||||
expect(registrations.queueManager).toBeDefined();
|
||||
expect(container.resolve('queueManager')).toBeNull();
|
||||
});
|
||||
});
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue