Repository: pmcelhaney/counterfact
Pull request #500 (2023-08-17 15:50:32)

fix a bug where the produces content type is defined at the root


Patch:
diff --git a/.changeset/fifty-flowers-approve.md b/.changeset/fifty-flowers-approve.md
new file mode 100644
index 0000000..ae5cc5c
--- /dev/null
+++ b/.changeset/fifty-flowers-approve.md
@@ -0,0 +1,5 @@
+---
+"counterfact": patch
+---
+
+fix error when the produces content type is defined at the root
diff --git a/src/typescript-generator/operation-type-coder.js b/src/typescript-generator/operation-type-coder.js
index c25a844..384f0f2 100644
--- a/src/typescript-generator/operation-type-coder.js
+++ b/src/typescript-generator/operation-type-coder.js
@@ -35,7 +35,7 @@ export class OperationTypeCoder extends Coder {
         if (response.has("schema")) {
           const produces =
             this.requirement?.get("produces")?.data ??
-            this.requirement.rootRequirement.get("produces").data;
+            this.requirement.specification.rootRequirement.get("produces").data;
 
           return produces
             .map(


Test patch:
diff --git a/test/typescript-generator/__snapshots__/operation-type-coder.test.js.snap b/test/typescript-generator/__snapshots__/operation-type-coder.test.js.snap
index 4088dd5..f6f0b26 100644
--- a/test/typescript-generator/__snapshots__/operation-type-coder.test.js.snap
+++ b/test/typescript-generator/__snapshots__/operation-type-coder.test.js.snap
@@ -36,6 +36,56 @@ exports[`an OperationTypeCoder falls back to root level produces (OpenAPI 2) 1`]
 "
 `;
 
+exports[`an OperationTypeCoder generates a complex post operation (OpenAPI 2 with produces at the root) 1`] = `
+"type TestType = ({
+  query,
+  path,
+  header,
+  body,
+  context,
+  proxy,
+}: {
+  query: { \\"name?\\": string };
+  path: { \\"id?\\": string };
+  header: { \\"name?\\": string };
+  body: Type;
+  context: typeof default;
+  response: ResponseBuilderFactory<{
+    200: {
+      headers: {};
+      content: {};
+    };
+    400: {
+      headers: {};
+      content: {};
+    };
+    [statusCode in Exclude<HttpStatusCode, 200 | 400>]: {
+      headers: {};
+      content: {};
+    };
+  }>;
+  proxy: (url: string) => { proxyUrl: string };
+}) =>
+  | {
+      status: 200;
+      contentType?: \\"application/json\\";
+      body?: Type;
+    }
+  | {
+      status: 400;
+      contentType?: \\"application/json\\";
+      body?: Type;
+    }
+  | {
+      status: number | undefined;
+      contentType?: \\"application/json\\";
+      body?: Type;
+    }
+  | { status: 415; contentType: \\"text/plain\\"; body: string }
+  | void;
+"
+`;
+
 exports[`an OperationTypeCoder generates a complex post operation (OpenAPI 2) 1`] = `
 "type TestType = ({
   query,
diff --git a/test/typescript-generator/operation-type-coder.test.js b/test/typescript-generator/operation-type-coder.test.js
index 121b024..056f23f 100644
--- a/test/typescript-generator/operation-type-coder.test.js
+++ b/test/typescript-generator/operation-type-coder.test.js
@@ -3,6 +3,7 @@ import prettier from "prettier";
 
 import { OperationTypeCoder } from "../../src/typescript-generator/operation-type-coder.js";
 import { Requirement } from "../../src/typescript-generator/requirement.js";
+import { Specification } from "../../src/typescript-generator/specification.js";
 
 function format(code) {
   return prettier.format(code, { parser: "typescript" });
@@ -163,6 +164,53 @@ describe("an OperationTypeCoder", () => {
     ).toMatchSnapshot();
   });
 
+  it("generates a complex post operation (OpenAPI 2 with produces at the root)", () => {
+    const specification = new Specification();
+
+    specification.rootRequirement = new Requirement({
+      produces: ["application/json"],
+    });
+
+    const requirement = new Requirement(
+      {
+        consumes: ["application/json"],
+
+        parameters: [
+          { name: "id", in: "path", type: "string" },
+          { name: "name", in: "query", type: "string" },
+          { name: "name", in: "header", type: "string" },
+          {
+            name: "body",
+            in: "body",
+            schema: { $ref: "#/components/schemas/Example" },
+          },
+        ],
+
+        responses: {
+          200: {
+            schema: { $ref: "#/components/schemas/Example" },
+          },
+
+          400: {
+            schema: { $ref: "#/components/schemas/Error" },
+          },
+
+          default: {
+            schema: { $ref: "#/components/schemas/Error" },
+          },
+        },
+      },
+      "#/paths/hello/post",
+      specification
+    );
+
+    const coder = new OperationTypeCoder(requirement);
+
+    expect(
+      format(`type TestType = ${coder.write(dummyScript)}`)
+    ).toMatchSnapshot();
+  });
+
   it("generates a simple get operation", () => {
     const requirement = new Requirement(
       {