Files
backend/test/openapi-contract.e2e-spec.ts
T

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));
});
});