/** * OpenAPI Contract Validation Tests * Ensures API implementation conforms to OpenAPI specification */ import { describe, it, expect } from '@jest/globals'; import { readFileSync } from 'fs'; import { join } from 'path'; import * as yaml from 'js-yaml'; import Ajv from 'ajv'; import addFormats from 'ajv-formats'; const OPENAPI_SPEC = join(__dirname, '../../../api/packages/openapi/v1/openapi.yaml'); describe('OpenAPI Contract Validation', () => { let openapiSpec: any; beforeAll(() => { const specContent = readFileSync(OPENAPI_SPEC, 'utf-8'); openapiSpec = yaml.load(specContent); }); it('should have valid OpenAPI structure', () => { expect(openapiSpec).toHaveProperty('openapi'); expect(openapiSpec.openapi).toMatch(/^3\.\d+\.\d+$/); expect(openapiSpec).toHaveProperty('info'); expect(openapiSpec).toHaveProperty('paths'); }); it('should have all required paths', () => { const requiredPaths = [ '/tokens', '/tokens/{code}', '/liens', '/liens/{lienId}', '/compliance/accounts/{accountRefId}', '/triggers', '/triggers/{triggerId}', '/iso/inbound', '/iso/outbound', '/packets', '/bridge/lock', '/bridge/unlock', ]; requiredPaths.forEach((path) => { expect(openapiSpec.paths).toHaveProperty(path); }); }); it('should have security schemes defined', () => { expect(openapiSpec.components).toHaveProperty('securitySchemes'); expect(openapiSpec.components.securitySchemes).toHaveProperty('oauth2'); expect(openapiSpec.components.securitySchemes).toHaveProperty('mtls'); }); it('should have idempotency markers', () => { expect(openapiSpec).toHaveProperty('x-idempotency'); expect(Array.isArray(openapiSpec['x-idempotency'])).toBe(true); }); });