created lots of tests
This commit is contained in:
parent
42baadae38
commit
54f37f9521
21 changed files with 4577 additions and 215 deletions
260
libs/core/di/test/lifecycle.test.ts
Normal file
260
libs/core/di/test/lifecycle.test.ts
Normal file
|
|
@ -0,0 +1,260 @@
|
|||
import { describe, expect, it, mock, beforeEach } from 'bun:test';
|
||||
import { ServiceLifecycleManager } from '../src/utils/lifecycle';
|
||||
import type { AwilixContainer } from 'awilix';
|
||||
|
||||
describe('ServiceLifecycleManager', () => {
|
||||
let manager: ServiceLifecycleManager;
|
||||
|
||||
beforeEach(() => {
|
||||
manager = new ServiceLifecycleManager();
|
||||
});
|
||||
|
||||
describe('initializeServices', () => {
|
||||
it('should initialize services with connect method', async () => {
|
||||
const mockCache = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockMongoClient = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockCache,
|
||||
mongoClient: mockMongoClient,
|
||||
postgresClient: null, // Not configured
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await manager.initializeServices(mockContainer);
|
||||
|
||||
expect(mockCache.connect).toHaveBeenCalled();
|
||||
expect(mockMongoClient.connect).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should initialize services with initialize method', async () => {
|
||||
const mockService = {
|
||||
initialize: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockService,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await manager.initializeServices(mockContainer);
|
||||
|
||||
expect(mockService.initialize).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle initialization errors', async () => {
|
||||
const mockService = {
|
||||
connect: mock(() => Promise.reject(new Error('Connection failed'))),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockService,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await expect(manager.initializeServices(mockContainer)).rejects.toThrow('Connection failed');
|
||||
});
|
||||
|
||||
it('should handle initialization timeout', async () => {
|
||||
const mockService = {
|
||||
connect: mock(() => new Promise(() => {})), // Never resolves
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockService,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await expect(manager.initializeServices(mockContainer, 100)).rejects.toThrow('cache initialization timed out after 100ms');
|
||||
});
|
||||
});
|
||||
|
||||
describe('shutdownServices', () => {
|
||||
it('should shutdown services with disconnect method', async () => {
|
||||
const mockCache = {
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockMongoClient = {
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockCache,
|
||||
mongoClient: mockMongoClient,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await manager.shutdownServices(mockContainer);
|
||||
|
||||
expect(mockCache.disconnect).toHaveBeenCalled();
|
||||
expect(mockMongoClient.disconnect).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should shutdown services with close method', async () => {
|
||||
const mockService = {
|
||||
close: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
queueManager: mockService,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await manager.shutdownServices(mockContainer);
|
||||
|
||||
expect(mockService.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should shutdown services with shutdown method', async () => {
|
||||
const mockService = {
|
||||
shutdown: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockService,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await manager.shutdownServices(mockContainer);
|
||||
|
||||
expect(mockService.shutdown).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should handle shutdown errors gracefully', async () => {
|
||||
const mockService = {
|
||||
disconnect: mock(() => Promise.reject(new Error('Disconnect failed'))),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockService,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
// Should not throw
|
||||
await manager.shutdownServices(mockContainer);
|
||||
});
|
||||
|
||||
it('should shutdown services in reverse order', async () => {
|
||||
const callOrder: string[] = [];
|
||||
|
||||
const mockCache = {
|
||||
disconnect: mock(() => {
|
||||
callOrder.push('cache');
|
||||
return Promise.resolve();
|
||||
}),
|
||||
};
|
||||
|
||||
const mockQueueManager = {
|
||||
close: mock(() => {
|
||||
callOrder.push('queue');
|
||||
return Promise.resolve();
|
||||
}),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockCache,
|
||||
queueManager: mockQueueManager,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
await manager.shutdownServices(mockContainer);
|
||||
|
||||
// Queue manager should be shutdown before cache (reverse order)
|
||||
expect(callOrder[0]).toBe('queue');
|
||||
expect(callOrder[1]).toBe('cache');
|
||||
});
|
||||
});
|
||||
|
||||
describe('mixed lifecycle methods', () => {
|
||||
it('should handle services with multiple lifecycle methods', async () => {
|
||||
const mockService = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
initialize: mock(() => Promise.resolve()),
|
||||
shutdown: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockService,
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
// Initialize should prefer connect over initialize
|
||||
await manager.initializeServices(mockContainer);
|
||||
expect(mockService.connect).toHaveBeenCalled();
|
||||
expect(mockService.initialize).not.toHaveBeenCalled();
|
||||
|
||||
// Shutdown should prefer disconnect over others
|
||||
await manager.shutdownServices(mockContainer);
|
||||
expect(mockService.disconnect).toHaveBeenCalled();
|
||||
expect(mockService.shutdown).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('complete lifecycle flow', () => {
|
||||
it('should handle full initialization and shutdown cycle', async () => {
|
||||
const mockCache = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockMongoClient = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
disconnect: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockPostgresClient = {
|
||||
connect: mock(() => Promise.resolve()),
|
||||
close: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockQuestdbClient = {
|
||||
initialize: mock(() => Promise.resolve()),
|
||||
shutdown: mock(() => Promise.resolve()),
|
||||
};
|
||||
|
||||
const mockContainer = {
|
||||
cradle: {
|
||||
cache: mockCache,
|
||||
mongoClient: mockMongoClient,
|
||||
postgresClient: mockPostgresClient,
|
||||
questdbClient: mockQuestdbClient,
|
||||
proxyManager: null, // Not configured
|
||||
queueManager: null, // Not configured
|
||||
},
|
||||
} as unknown as AwilixContainer;
|
||||
|
||||
// Initialize all services
|
||||
await manager.initializeServices(mockContainer);
|
||||
|
||||
expect(mockCache.connect).toHaveBeenCalled();
|
||||
expect(mockMongoClient.connect).toHaveBeenCalled();
|
||||
expect(mockPostgresClient.connect).toHaveBeenCalled();
|
||||
expect(mockQuestdbClient.initialize).toHaveBeenCalled();
|
||||
|
||||
// Shutdown all services
|
||||
await manager.shutdownServices(mockContainer);
|
||||
|
||||
expect(mockCache.disconnect).toHaveBeenCalled();
|
||||
expect(mockMongoClient.disconnect).toHaveBeenCalled();
|
||||
expect(mockPostgresClient.close).toHaveBeenCalled();
|
||||
expect(mockQuestdbClient.shutdown).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
})
|
||||
Loading…
Add table
Add a link
Reference in a new issue