From d18ee5459cee9487924ccf407d6a18c01152879c Mon Sep 17 00:00:00 2001 From: Stefan Burnicki Date: Thu, 29 Jul 2021 04:37:31 +0200 Subject: [PATCH] [kotlin-spring] Support model objects and date-time query params (#8257) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [kotlin-spring] Support query params with model objects (#8080) Must fix #8080 * [kotlin-spring] Support parsing date and date-time parameters adopted #3860 for kotlin-spring Co-authored-by: Мышкин Максим --- .../kotlin-spring/queryParams.mustache | 2 +- .../spring/KotlinSpringServerCodegenTest.java | 107 ++++++++++++++++++ 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/modules/openapi-generator/src/main/resources/kotlin-spring/queryParams.mustache b/modules/openapi-generator/src/main/resources/kotlin-spring/queryParams.mustache index 53686e7b82f..7fb691c0ddc 100644 --- a/modules/openapi-generator/src/main/resources/kotlin-spring/queryParams.mustache +++ b/modules/openapi-generator/src/main/resources/kotlin-spring/queryParams.mustache @@ -1 +1 @@ -{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}{{/isContainer}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}}{{/swaggerAnnotations}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{^isContainer}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}{{/isContainer}}) {{paramName}}: {{>optionalDataType}}{{/isQueryParam}} \ No newline at end of file +{{#isQueryParam}}{{#useBeanValidation}}{{>beanValidationQueryParams}}{{/useBeanValidation}}{{#swaggerAnnotations}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{#-last}}{{/-last}}{{/values}}"{{/allowableValues}}{{^isContainer}}{{#defaultValue}}, defaultValue = "{{{defaultValue}}}"{{/defaultValue}}{{/isContainer}}) {{#useBeanValidation}}@Valid{{/useBeanValidation}}{{/swaggerAnnotations}}{{^isModel}} @RequestParam(value = "{{baseName}}"{{#required}}, required = true{{/required}}{{^required}}, required = false{{/required}}{{^isContainer}}{{#defaultValue}}, defaultValue="{{{defaultValue}}}"{{/defaultValue}}{{/isContainer}}){{/isModel}}{{#isDate}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE){{/isDate}}{{#isDateTime}} @org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME){{/isDateTime}} {{paramName}}: {{>optionalDataType}}{{/isQueryParam}} \ No newline at end of file diff --git a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java index dc3bceaa435..6a506a7221f 100644 --- a/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java +++ b/modules/openapi-generator/src/test/java/org/openapitools/codegen/kotlin/spring/KotlinSpringServerCodegenTest.java @@ -1,9 +1,11 @@ package org.openapitools.codegen.kotlin.spring; import com.google.common.collect.testing.Helpers; +import io.swagger.parser.OpenAPIParser; import io.swagger.v3.oas.models.OpenAPI; import io.swagger.v3.oas.models.info.Info; import io.swagger.v3.oas.models.servers.Server; +import io.swagger.v3.parser.core.models.ParseOptions; import org.apache.commons.io.FileUtils; import org.openapitools.codegen.ClientOptInput; import org.openapitools.codegen.CodegenConstants; @@ -11,10 +13,12 @@ import org.openapitools.codegen.DefaultGenerator; import org.openapitools.codegen.TestUtils; import org.openapitools.codegen.kotlin.KotlinTestUtils; import org.openapitools.codegen.languages.KotlinSpringServerCodegen; +import org.openapitools.codegen.languages.features.CXFServerFeatures; import org.testng.Assert; import org.testng.annotations.Test; import java.io.File; +import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Collections; @@ -253,4 +257,107 @@ public class KotlinSpringServerCodegenTest { assertFileNotContains(Paths.get(output + "/src/main/kotlin/org/openapitools/api/TestV2ApiDelegate.kt"), "suspend fun", "ApiUtil"); } + + @Test + public void doNotGenerateRequestParamForObjectQueryParam() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + OpenAPI openAPI = new OpenAPIParser() + .readLocation("src/test/resources/3_0/objectQueryParam.yaml", null, new ParseOptions()).getOpenAPI(); + + KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true"); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + generator.opts(input).generate(); + + assertFileNotContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/PonyApi.kt"), "@RequestParam"); + } + + @Test + public void doGenerateRequestParamForSimpleParam() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + OpenAPI openAPI = new OpenAPIParser() + .readLocation("src/test/resources/3_0/issue_3248.yaml", null, new ParseOptions()).getOpenAPI(); + + KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true"); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + + generator.opts(input).generate(); + + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/MonkeysApi.kt"), "@RequestParam"); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/ElephantsApi.kt"), "@RequestParam"); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/ZebrasApi.kt"), "@RequestParam"); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/BearsApi.kt"), "@RequestParam"); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/CamelsApi.kt"), "@RequestParam"); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/PandasApi.kt"), "@RequestParam"); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/CrocodilesApi.kt"), "@RequestParam"); + assertFileContains(Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/PolarBearsApi.kt"), "@RequestParam"); + } + + @Test + public void generateFormatForDateAndDateTimeQueryParam() throws IOException { + File output = Files.createTempDirectory("test").toFile().getCanonicalFile(); + output.deleteOnExit(); + String outputPath = output.getAbsolutePath().replace('\\', '/'); + + OpenAPI openAPI = new OpenAPIParser() + .readLocation("src/test/resources/3_0/issue_2053.yaml", null, new ParseOptions()).getOpenAPI(); + + KotlinSpringServerCodegen codegen = new KotlinSpringServerCodegen(); + codegen.setOutputDir(output.getAbsolutePath()); + codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true"); + + ClientOptInput input = new ClientOptInput(); + input.openAPI(openAPI); + input.config(codegen); + + DefaultGenerator generator = new DefaultGenerator(); + + generator.setGeneratorPropertyDefault(CodegenConstants.MODELS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_TESTS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.MODEL_DOCS, "false"); + generator.setGeneratorPropertyDefault(CodegenConstants.APIS, "true"); + generator.setGeneratorPropertyDefault(CodegenConstants.SUPPORTING_FILES, "false"); + generator.opts(input).generate(); + + assertFileContains( + Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/ElephantsApi.kt"), + "@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)" + ); + assertFileContains( + Paths.get(outputPath + "/src/main/kotlin/org/openapitools/api/ZebrasApi.kt"), + "@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)" + ); + } }