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