From f371a91d15bb555590ecf4a2c704030322663feb Mon Sep 17 00:00:00 2001 From: WannabeSoftwareEngineer <118805272+WannabeSoftwareEngineer@users.noreply.github.com> Date: Thu, 12 Jun 2025 15:47:51 +0200 Subject: [PATCH] FIX #21407 - use referenced string enum schema in requestBody if available --- .../codegen/CodegenConstants.java | 3 ++ .../openapitools/codegen/DefaultCodegen.java | 11 +++-- .../codegen/DefaultCodegenTest.java | 46 ++++++++++++++++++ .../src/test/resources/3_0/issue_21407.yaml | 48 +++++++++++++++++++ 4 files changed, 105 insertions(+), 3 deletions(-) create mode 100644 modules/openapi-generator/src/test/resources/3_0/issue_21407.yaml diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java index ae52412b7d2d..fbfcc8e12559 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenConstants.java @@ -397,6 +397,9 @@ public static enum ENUM_PROPERTY_NAMING_TYPE {camelCase, PascalCase, snake_case, public static final String REMOVE_ENUM_VALUE_PREFIX = "removeEnumValuePrefix"; public static final String REMOVE_ENUM_VALUE_PREFIX_DESC = "Remove the common prefix of enum values"; + public static final String USE_STRING_ENUM_SCHEMA_REF_FOR_REQUEST_BODY = "useStringEnumSchemaRefForRequestBody"; + public static final String USE_STRING_ENUM_SCHEMA_REF_FOR_REQUEST_BODY_DESC = "A boolean flag that controls how the parameter type for a referenced string enum in a request body is generated. When set to true, the generator will use the referenced schema instead of a plain String type"; + public static final String SKIP_ONEOF_ANYOF_GETTER = "skipOneOfAnyOfGetter"; public static final String SKIP_ONEOF_ANYOF_GETTER_DESC = "Skip the generation of getter for sub-schemas in oneOf/anyOf models."; diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java index 33918bed8462..00f8d9efc405 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/DefaultCodegen.java @@ -7794,8 +7794,13 @@ protected void updateRequestBodyForArray(CodegenParameter codegenParameter, Sche } } - protected void updateRequestBodyForString(CodegenParameter codegenParameter, Schema schema, Set imports, String bodyParameterName) { - updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + protected void updateRequestBodyForString(CodegenParameter codegenParameter, Schema schema, String name, Set imports, String bodyParameterName) { + if (convertPropertyToBoolean(CodegenConstants.USE_STRING_ENUM_SCHEMA_REF_FOR_REQUEST_BODY) && !StringUtils.isEmpty(name)) { + addBodyModelSchema(codegenParameter, name, schema, imports, bodyParameterName, false); + } else { + updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); + } + if (ModelUtils.isByteArraySchema(schema)) { codegenParameter.setIsString(false); codegenParameter.isByteArray = true; @@ -7996,7 +8001,7 @@ public CodegenParameter fromRequestBody(RequestBody body, Set imports, S // swagger v2 only, type file codegenParameter.isFile = true; } else if (ModelUtils.isStringSchema(schema)) { - updateRequestBodyForString(codegenParameter, schema, imports, bodyParameterName); + updateRequestBodyForString(codegenParameter, schema, name, imports, bodyParameterName); } else if (ModelUtils.isNumberSchema(schema)) { updateRequestBodyForPrimitiveType(codegenParameter, schema, bodyParameterName, imports); codegenParameter.isNumeric = Boolean.TRUE; diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java index 40bf8d83a5df..32ff7f24401c 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/DefaultCodegenTest.java @@ -48,6 +48,7 @@ import org.openapitools.codegen.utils.SemVer; import org.slf4j.LoggerFactory; import org.testng.Assert; +import org.testng.annotations.DataProvider; import org.testng.annotations.Ignore; import org.testng.annotations.Test; @@ -5015,4 +5016,49 @@ public void testSingleRequestParameter_hasSingleParamTrue() { // When & Then assertThat(codegenOperation.getHasSingleParam()).isTrue(); } + + @DataProvider(name = "testRequestBodyWithStringEnumSchemaData") + private Object[][] testRequestBodyWithStringEnumSchemaData() { + return new Object[][]{ + {false, "String"}, + {true, "Letter"} + }; + } + + @Test(dataProvider = "testRequestBodyWithStringEnumSchemaData") + public void testRequestBodyWithStringEnumSchema(boolean useStringEnumSchemaRefForRequestBody, String expectedDataType) { + // Given + OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_21407.yaml"); + DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + codegen.additionalProperties().put(CodegenConstants.USE_STRING_ENUM_SCHEMA_REF_FOR_REQUEST_BODY, useStringEnumSchemaRefForRequestBody); + String path = "/v1/resource-class/send-using-schema"; + + // When + CodegenOperation codegenOperation = codegen.fromOperation(path, "POST", openAPI.getPaths().get(path).getPost(), null); + + // Then + assertThat(codegenOperation.bodyParam).satisfies(bodyParam -> { + assertThat(bodyParam).isNotNull(); + assertThat(bodyParam.getDataType()).isEqualTo(expectedDataType); + }); + } + + @Test + public void testRequestBodyWithStringSchema() { + // Given + OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_21407.yaml"); + DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + String path = "/v1/resource-class/send-using-string"; + + // When + CodegenOperation codegenOperation = codegen.fromOperation(path, "POST", openAPI.getPaths().get(path).getPost(), null); + + // Then + assertThat(codegenOperation.bodyParam).satisfies(bodyParam -> { + assertThat(bodyParam).isNotNull(); + assertThat(bodyParam.getDataType()).isEqualTo("String"); + }); + } } diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_21407.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_21407.yaml new file mode 100644 index 000000000000..75eb086a6a0d --- /dev/null +++ b/modules/openapi-generator/src/test/resources/3_0/issue_21407.yaml @@ -0,0 +1,48 @@ +openapi: 3.0.1 +info: + title: sample spec + description: "Sample spec" + version: 0.0.1 +tags: +- name: ResourceClass +paths: + /v1/resource-class/send-using-schema: + post: + tags: + - ResourceClass + description: Add @Operation annotation to provide a description + operationId: send-using-schema + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/Letter" + responses: + "200": + description: OK - the request has succeeded. + content: + application/json: + schema: + $ref: "#/components/schemas/Letter" + /v1/resource-class/send-using-string: + post: + tags: + - ResourceClass + description: Add @Operation annotation to provide a description + operationId: send-using-string + requestBody: + content: + application/json: + schema: + type: string + responses: + "204": + description: "No Content - the request has been successfully processed,\ + \ but there is no additional content." +components: + schemas: + Letter: + type: string + enum: + - A + - B \ No newline at end of file