53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
import { INestApplication } from '@nestjs/common';
|
|
import { Test } from '@nestjs/testing';
|
|
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
|
|
import { readFile } from 'node:fs/promises';
|
|
import { resolve } from 'node:path';
|
|
import { AppModule } from './../src/app.module';
|
|
import { configureApp } from './../src/main';
|
|
|
|
function canonicalize(value: unknown): unknown {
|
|
if (Array.isArray(value)) return value.map(canonicalize);
|
|
if (value && typeof value === 'object') {
|
|
return Object.fromEntries(
|
|
Object.entries(value)
|
|
.sort(([left], [right]) => left.localeCompare(right))
|
|
.map(([key, nestedValue]) => [key, canonicalize(nestedValue)]),
|
|
);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
describe('OpenAPI contract (integration)', () => {
|
|
let app: INestApplication;
|
|
|
|
beforeAll(async () => {
|
|
const module = await Test.createTestingModule({
|
|
imports: [AppModule],
|
|
}).compile();
|
|
app = module.createNestApplication();
|
|
configureApp(app);
|
|
await app.init();
|
|
});
|
|
|
|
afterAll(() => app.close());
|
|
|
|
it('matches the committed frontend OpenAPI snapshot', async () => {
|
|
const runtimeDocument = SwaggerModule.createDocument(
|
|
app,
|
|
new DocumentBuilder()
|
|
.setTitle('WealthLedger API')
|
|
.setVersion('v1')
|
|
.build(),
|
|
);
|
|
const snapshot = JSON.parse(
|
|
await readFile(
|
|
resolve(__dirname, '../../frontend/src/shared/api/spec/openapi.json'),
|
|
'utf8',
|
|
),
|
|
) as unknown;
|
|
|
|
expect(canonicalize(runtimeDocument)).toEqual(canonicalize(snapshot));
|
|
});
|
|
});
|