mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
0a4c6fbace
db/database.ts opened the connection as a side effect of being imported, so the moment anything reached it the database was open. index.ts had to defer loading the app until a first-boot restore was done, and nothing in the container decided when the connection opened or closed. The module now opens the connection on first use and opens nothing at import. A connection closed on purpose (a restore, the shutdown) stays closed until it is reopened, as before. The new DatabaseLifecycle provider owns the decisions: buildApp() opens through it, which also binds the ORM to later swaps (the hook attachOrm used to register) and runs the schema bootstrap in the same order as before, and the shutdown closes through it. Its file property is the one resolved database path. The module keeps every export, so the test suites that replace it with vi.mock keep working; buildDbMock gains the new openDb.
56 lines
2.0 KiB
TypeScript
56 lines
2.0 KiB
TypeScript
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
|
|
import request from 'supertest';
|
|
import type { INestApplication } from '@nestjs/common';
|
|
import { buildApp } from '../../src/bootstrap';
|
|
import { DatabaseLifecycle } from '../../src/nest/database/database-lifecycle.service';
|
|
|
|
/**
|
|
* The core database's lifecycle, owned by the DatabaseLifecycle provider, on a
|
|
* real boot.
|
|
*
|
|
* The connection used to open as a side effect of importing db/database.ts and
|
|
* was closed and reopened through module functions the restore and the demo
|
|
* reset called directly. buildApp() now opens it through the provider, which
|
|
* also binds the ORM to later swaps, and closes and reopens it through the
|
|
* same provider. Unmocked on purpose: under NODE_ENV=test the
|
|
* module opens a copy of the migrated schema snapshot, and every reopen opens a
|
|
* pristine copy again, which is all these cases need.
|
|
*/
|
|
describe('the database connection lifecycle under buildApp()', () => {
|
|
let app: INestApplication;
|
|
|
|
beforeAll(async () => {
|
|
app = await buildApp();
|
|
await app.init();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
await app?.close();
|
|
});
|
|
|
|
it('LIFECYCLE-001: the boot opened the connection through the provider and the database answers', async () => {
|
|
expect(app.get(DatabaseLifecycle).file).toBe(':memory:');
|
|
|
|
const res = await request(app.getHttpServer()).get('/api/health/ready');
|
|
|
|
expect(res.status).toBe(200);
|
|
expect(res.body).toEqual({ status: 'ready' });
|
|
});
|
|
|
|
it('LIFECYCLE-002: closed, the readiness probe answers 503; reopened, the ORM is bound to the new handle and it answers again', async () => {
|
|
const lifecycle = app.get(DatabaseLifecycle);
|
|
|
|
lifecycle.close();
|
|
try {
|
|
const down = await request(app.getHttpServer()).get('/api/health/ready');
|
|
expect(down.status).toBe(503);
|
|
expect(down.body).toEqual({ status: 'unavailable' });
|
|
} finally {
|
|
await lifecycle.reopen();
|
|
}
|
|
|
|
const up = await request(app.getHttpServer()).get('/api/health/ready');
|
|
expect(up.status).toBe(200);
|
|
});
|
|
});
|