import assert from "node:assert/strict"; import { describe, it } from "node:test"; import { findMissingOperations, normalizePath, } from "../openapi-contract.mjs"; describe("OpenAPI contract comparison", () => { it("accepts matching paths and methods", () => { const missing = findMissingOperations( { chatHistory: { method: "get", path: "/api/chat/history" }, unlockAlbum: { method: "post", path: "/api/private-zone/albums/{albumId}/unlock", }, }, { paths: { "/api/chat/history": { get: {} }, "/api/private-zone/albums/{album_id}/unlock/": { post: {} }, }, }, ); assert.deepEqual(missing, []); }); it("reports missing paths and methods with operation ids", () => { const missing = findMissingOperations( { chatHistory: { method: "get", path: "/api/chat/history" }, chatSend: { method: "post", path: "/api/chat/send" }, }, { paths: { "/api/chat/history": { post: {} } } }, ); assert.deepEqual(missing, [ { operationId: "chatHistory", method: "get", path: "/api/chat/history", reason: "method is missing", }, { operationId: "chatSend", method: "post", path: "/api/chat/send", reason: "path is missing", }, ]); }); it("normalizes trailing slashes and path parameter names", () => { assert.equal( normalizePath("/api/albums/{album_id}/unlock/"), "/api/albums/{}/unlock", ); }); it("rejects documents without OpenAPI paths", () => { assert.throws( () => findMissingOperations({}, {}), /does not contain a paths object/u, ); }); });