From 846c1695f2e4fa20d68137108ec661b435060856 Mon Sep 17 00:00:00 2001 From: Steven Serrata <9343811+sserrata@users.noreply.github.com> Date: Wed, 21 Aug 2024 12:35:50 -0400 Subject: [PATCH] Add additional oneOf tests (#924) --- demo/examples/tests/oneOf.yaml | 264 +++++++++++++++++ .../__snapshots__/createSchema.test.ts.snap | 272 ++++++++++++++++++ .../src/markdown/createSchema.test.ts | 187 ++++++++++++ 3 files changed, 723 insertions(+) create mode 100644 demo/examples/tests/oneOf.yaml diff --git a/demo/examples/tests/oneOf.yaml b/demo/examples/tests/oneOf.yaml new file mode 100644 index 000000000..13fea2d85 --- /dev/null +++ b/demo/examples/tests/oneOf.yaml @@ -0,0 +1,264 @@ +openapi: 3.0.1 +info: + title: OneOf Variations API + description: Demonstrates various oneOf schema combinations. + version: 1.0.0 +tags: + - name: oneOf + description: oneOf tests +paths: + /oneof-primitive-types: + get: + tags: + - oneOf + summary: oneOf with Primitive Types + description: | + Schema: + ```yaml + type: object + properties: + oneOfProperty: + oneOf: + - type: string + - type: number + - type: boolean + ``` + responses: + "200": + description: Successful response + content: + application/json: + schema: + type: object + properties: + oneOfProperty: + oneOf: + - type: string + - type: number + - type: boolean + + /oneof-complex-types: + get: + tags: + - oneOf + summary: oneOf with Complex Types + description: | + Schema: + ```yaml + type: object + properties: + oneOfProperty: + oneOf: + - type: object + properties: + objectProp: + type: string + - type: array + items: + type: number + ``` + responses: + "200": + description: Successful response + content: + application/json: + schema: + type: object + properties: + oneOfProperty: + oneOf: + - type: object + properties: + objectProp: + type: string + - type: array + items: + type: number + + /oneof-nested: + get: + tags: + - oneOf + summary: oneOf with Nested oneOf + description: | + Schema: + ```yaml + type: object + properties: + oneOfProperty: + oneOf: + - type: object + properties: + nestedOneOfProp: + oneOf: + - type: string + - type: number + - type: boolean + ``` + responses: + "200": + description: Successful response + content: + application/json: + schema: + type: object + properties: + oneOfProperty: + oneOf: + - type: object + properties: + nestedOneOfProp: + oneOf: + - type: string + - type: number + - type: boolean + + # /oneof-discriminator: + # get: + # tags: + # - oneOf + # summary: oneOf with Discriminator + # description: | + # Schema: + # ```yaml + # type: object + # discriminator: + # propertyName: type + # properties: + # type: + # type: string + # oneOf: + # - type: object + # properties: + # type: + # type: string + # enum: ["typeA"] + # propA: + # type: string + # required: ["type"] + # - type: object + # properties: + # type: + # type: string + # enum: ["typeB"] + # propB: + # type: number + # required: ["type"] + # ``` + # responses: + # '200': + # description: Successful response + # content: + # application/json: + # schema: + # type: object + # discriminator: + # propertyName: type + # properties: + # type: + # type: string + # oneOf: + # - type: object + # properties: + # type: + # type: string + # enum: ["typeA"] + # propA: + # type: string + # required: ["type"] + # - type: object + # properties: + # type: + # type: string + # enum: ["typeB"] + # propB: + # type: number + # required: ["type"] + + /oneof-shared-properties: + get: + tags: + - oneOf + summary: oneOf with Shared Properties + description: | + Schema: + ```yaml + type: object + properties: + sharedProp: + type: string + oneOfProperty: + oneOf: + - type: object + properties: + specificPropA: + type: string + - type: object + properties: + specificPropB: + type: number + ``` + responses: + "200": + description: Successful response + content: + application/json: + schema: + type: object + properties: + sharedProp: + type: string + oneOfProperty: + oneOf: + - type: object + properties: + specificPropA: + type: string + - type: object + properties: + specificPropB: + type: number + + /oneof-required-properties: + get: + tags: + - oneOf + summary: oneOf with Required Properties + description: | + Schema: + ```yaml + type: object + properties: + oneOfProperty: + oneOf: + - type: object + properties: + requiredPropA: + type: string + required: ["requiredPropA"] + - type: object + properties: + requiredPropB: + type: number + required: ["requiredPropB"] + ``` + responses: + "200": + description: Successful response + content: + application/json: + schema: + type: object + properties: + oneOfProperty: + oneOf: + - type: object + properties: + requiredPropA: + type: string + required: ["requiredPropA"] + - type: object + properties: + requiredPropB: + type: number + required: ["requiredPropB"] diff --git a/packages/docusaurus-plugin-openapi-docs/src/markdown/__snapshots__/createSchema.test.ts.snap b/packages/docusaurus-plugin-openapi-docs/src/markdown/__snapshots__/createSchema.test.ts.snap index 82bff053d..5638c268f 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/markdown/__snapshots__/createSchema.test.ts.snap +++ b/packages/docusaurus-plugin-openapi-docs/src/markdown/__snapshots__/createSchema.test.ts.snap @@ -457,3 +457,275 @@ Array [ ", ] `; + +exports[`createNodes oneOf should handle nested oneOf clauses 1`] = ` +Array [ + " + + + + oneOfProperty + object + + + + + + oneOf + + + + + + + + + nestedOneOfProp + + object + + + + + + oneOf + + + + + string + + + + + number + + + + + + + + + + + boolean + + + + + + +; +", +] +`; + +exports[`createNodes oneOf should handle oneOf with complex types 1`] = ` +Array [ + " + + + + oneOfProperty + object + + + + + + oneOf + + + + + + + + + Array [ + + + + number + + + + ] + + + + + + + +; +", +] +`; + +exports[`createNodes oneOf should handle oneOf with different primitive types 1`] = ` +Array [ + " + + + + oneOfProperty + object + + + + + + oneOf + + + + + string + + + + + number + + + + + boolean + + + + + + +; +", +] +`; + +exports[`createNodes oneOf should handle oneOf with required properties 1`] = ` +Array [ + " + + + + oneOfProperty + object + + + + + + oneOf + + + + + + + + + + + + +; +", +] +`; + +exports[`createNodes oneOf should handle oneOf with shared properties 1`] = ` +Array [ + "; +", + " + + + + oneOfProperty + object + + + + + + oneOf + + + + + + + + + + + + +; +", +] +`; diff --git a/packages/docusaurus-plugin-openapi-docs/src/markdown/createSchema.test.ts b/packages/docusaurus-plugin-openapi-docs/src/markdown/createSchema.test.ts index a9a4f964a..35f0342cf 100644 --- a/packages/docusaurus-plugin-openapi-docs/src/markdown/createSchema.test.ts +++ b/packages/docusaurus-plugin-openapi-docs/src/markdown/createSchema.test.ts @@ -57,6 +57,193 @@ describe("createNodes", () => { ) ).toMatchSnapshot(); }); + + it("should handle oneOf with different primitive types", async () => { + const schema: SchemaObject = { + type: "object", + properties: { + oneOfProperty: { + oneOf: [ + { type: "string" }, + { type: "number" }, + { type: "boolean" }, + ], + }, + }, + }; + + expect( + await Promise.all( + createNodes(schema, "response").map( + async (md: any) => await prettier.format(md, { parser: "babel" }) + ) + ) + ).toMatchSnapshot(); + }); + + it("should handle oneOf with complex types", async () => { + const schema: SchemaObject = { + type: "object", + properties: { + oneOfProperty: { + oneOf: [ + { + type: "object", + properties: { + objectProp: { type: "string" }, + }, + }, + { + type: "array", + items: { type: "number" }, + }, + ], + }, + }, + }; + + expect( + await Promise.all( + createNodes(schema, "response").map( + async (md: any) => await prettier.format(md, { parser: "babel" }) + ) + ) + ).toMatchSnapshot(); + }); + + it("should handle nested oneOf clauses", async () => { + const schema: SchemaObject = { + type: "object", + properties: { + oneOfProperty: { + oneOf: [ + { + type: "object", + properties: { + nestedOneOfProp: { + oneOf: [{ type: "string" }, { type: "number" }], + }, + }, + }, + { type: "boolean" }, + ], + }, + }, + }; + + expect( + await Promise.all( + createNodes(schema, "response").map( + async (md: any) => await prettier.format(md, { parser: "babel" }) + ) + ) + ).toMatchSnapshot(); + }); + + // TypeError: Cannot read properties of undefined (reading 'length') + // eslint-disable-next-line jest/no-commented-out-tests + // it("should handle oneOf with discriminator", async () => { + // const schema: SchemaObject = { + // type: "object", + // discriminator: { propertyName: "type" }, + // properties: { + // type: { type: "string" }, + // }, + // oneOf: [ + // { + // type: "object", + // properties: { + // type: { type: "string", enum: ["typeA"] }, + // propA: { type: "string" }, + // }, + // required: ["type"], + // }, + // { + // type: "object", + // properties: { + // type: { type: "string", enum: ["typeB"] }, + // propB: { type: "number" }, + // }, + // required: ["type"], + // }, + // ], + // }; + + // expect( + // await Promise.all( + // createNodes(schema, "response").map( + // async (md: any) => await prettier.format(md, { parser: "babel" }) + // ) + // ) + // ).toMatchSnapshot(); + // }); + + it("should handle oneOf with shared properties", async () => { + const schema: SchemaObject = { + type: "object", + properties: { + sharedProp: { type: "string" }, + oneOfProperty: { + oneOf: [ + { + type: "object", + properties: { + specificPropA: { type: "string" }, + }, + }, + { + type: "object", + properties: { + specificPropB: { type: "number" }, + }, + }, + ], + }, + }, + }; + + expect( + await Promise.all( + createNodes(schema, "response").map( + async (md: any) => await prettier.format(md, { parser: "babel" }) + ) + ) + ).toMatchSnapshot(); + }); + + it("should handle oneOf with required properties", async () => { + const schema: SchemaObject = { + type: "object", + properties: { + oneOfProperty: { + oneOf: [ + { + type: "object", + properties: { + requiredPropA: { type: "string" }, + }, + required: ["requiredPropA"], + }, + { + type: "object", + properties: { + requiredPropB: { type: "number" }, + }, + required: ["requiredPropB"], + }, + ], + }, + }, + }; + + expect( + await Promise.all( + createNodes(schema, "response").map( + async (md: any) => await prettier.format(md, { parser: "babel" }) + ) + ) + ).toMatchSnapshot(); + }); }); describe("allOf", () => {