[bug][kotlin-spring] fix allowableValues quotes in documentation anno… (#21700)

* [bug][kotlin-spring] fix allowableValues quotes in documentation annotations for path parameters

* Remove unused imports in KotlinSpringServerCodegenTest

* Fix Swagger1 annotation

* Streamline Swagger1 annotation

* Remove extra line break

---------

Co-authored-by: Chris Gual <cgual@omnidian.com>
This commit is contained in:
Christopher Gual 2025-08-06 00:17:36 -07:00 committed by GitHub
parent bb6acc132a
commit 7e974272be
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 90 additions and 3 deletions

View File

@ -1 +1 @@
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#enumVars}}"{{#lambdaEscapeInNormalString}}{{{value}}}{{/lambdaEscapeInNormalString}}"{{^-last}}, {{/-last}}{{/enumVars}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#enumVars}}"{{#lambdaEscapeInNormalString}}{{{value}}}{{/lambdaEscapeInNormalString}}"{{^-last}}, {{/-last}}{{/enumVars}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#enumVars}}{{#lambda.escapeDoubleQuote}}{{{value}}}{{/lambda.escapeDoubleQuote}}{{^-last}}, {{/-last}}{{/enumVars}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} @PathVariable("{{baseName}}") {{{paramName}}}: {{>optionalDataType}}{{/isPathParam}}
{{#isPathParam}}{{#useBeanValidation}}{{>beanValidationPathParams}}{{/useBeanValidation}}{{#swagger2AnnotationLibrary}}@Parameter(description = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}{{#defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]{{^isContainer}}, defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{/isContainer}}){{/defaultValue}}{{/allowableValues}}{{#allowableValues}}{{^defaultValue}}, schema = Schema(allowableValues = [{{#values}}"{{{.}}}"{{^-last}}, {{/-last}}{{/values}}]){{/defaultValue}}{{/allowableValues}}{{^allowableValues}}{{#defaultValue}}{{^isContainer}}, schema = Schema(defaultValue = {{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}{{{defaultValue}}}{{^isString}}"{{/isString}}{{#isString}}{{#isEnum}}"{{/isEnum}}{{/isString}}){{/isContainer}}{{/defaultValue}}{{/allowableValues}}){{/swagger2AnnotationLibrary}}{{#swagger1AnnotationLibrary}}@ApiParam(value = "{{{description}}}"{{#required}}, required = true{{/required}}{{#allowableValues}}, allowableValues = "{{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}"{{/allowableValues}}{{#defaultValue}}, defaultValue = "{{{.}}}"{{/defaultValue}}){{/swagger1AnnotationLibrary}} @PathVariable("{{baseName}}") {{{paramName}}}: {{>optionalDataType}}{{/isPathParam}}

View File

@ -7,6 +7,7 @@ import io.swagger.v3.oas.models.servers.Server;
import io.swagger.v3.parser.core.models.ParseOptions;
import java.util.HashMap;
import java.util.function.Consumer;
import java.util.stream.Stream;
import org.apache.commons.io.FileUtils;
import org.assertj.core.api.Assertions;
import org.jetbrains.annotations.NotNull;
@ -15,13 +16,14 @@ import org.openapitools.codegen.CodegenConstants;
import org.openapitools.codegen.DefaultGenerator;
import org.openapitools.codegen.TestUtils;
import org.openapitools.codegen.config.CodegenConfigurator;
import org.openapitools.codegen.java.assertions.JavaFileAssert;
import org.openapitools.codegen.kotlin.KotlinTestUtils;
import org.openapitools.codegen.languages.KotlinSpringServerCodegen;
import org.openapitools.codegen.languages.features.CXFServerFeatures;
import org.openapitools.codegen.languages.features.DocumentationProviderFeatures;
import org.openapitools.codegen.languages.features.DocumentationProviderFeatures.AnnotationLibrary;
import org.openapitools.codegen.languages.features.DocumentationProviderFeatures.DocumentationProvider;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import java.io.File;
@ -1232,6 +1234,79 @@ public class KotlinSpringServerCodegenTest {
"@NotNull", "@Valid", "@Pattern(regexp=\"^[a-zA-Z0-9]+[a-zA-Z0-9\\\\.\\\\-_]*[a-zA-Z0-9]+$\")");
}
@DataProvider
public Object[][] issue17997DocumentationProviders() {
return new Object[][]{
{DocumentationProviderFeatures.DocumentationProvider.SPRINGDOC.name(),
(Consumer<Path>) outputPath ->
assertFileContains(
outputPath,
"allowableValues = [\"0\", \"1\"], defaultValue = \"0\"",
"@PathVariable"
),
(Consumer<Path>) outputPath ->
assertFileContains(
outputPath,
"allowableValues = [\"sleeping\", \"awake\"]", "@PathVariable",
"@PathVariable"
)
},
{DocumentationProviderFeatures.DocumentationProvider.SPRINGFOX.name(),
(Consumer<Path>) outputPath ->
assertFileContains(
outputPath,
"allowableValues = \"0, 1\", defaultValue = \"0\"",
"@PathVariable"
),
(Consumer<Path>) outputPath ->
assertFileContains(
outputPath,
"allowableValues = \"sleeping, awake\"", "@PathVariable",
"@PathVariable"
)
}
};
}
@Test(dataProvider = "issue17997DocumentationProviders")
public void testDocumentationAnnotationInPathParams_Issue17997(
String documentProvider,
Consumer<Path> intEnumAssertFunction,
Consumer<Path> stringEnumAssertFunction
) throws IOException {
Map<String, Object> additionalProperties = new HashMap<>();
additionalProperties.put(DOCUMENTATION_PROVIDER, documentProvider);
Map<String, String> generatorPropertyDefaults = new HashMap<>();
generatorPropertyDefaults.put(CodegenConstants.MODEL_TESTS, "false");
generatorPropertyDefaults.put(CodegenConstants.MODEL_DOCS, "false");
generatorPropertyDefaults.put(CodegenConstants.APIS, "true");
Map<String, File> files = generateFromContract(
"src/test/resources/3_0/issue_6762.yaml",
additionalProperties,
generatorPropertyDefaults
);
Stream.of(
"ZebrasApiController.kt",
"GiraffesApiController.kt"
).forEach(filename -> {
File file = files.get(filename);
assertThat(file).isNotNull();
intEnumAssertFunction.accept(file.toPath());
});
Stream.of(
"BearsApiController.kt",
"CamelsApiController.kt"
).forEach(filename -> {
File file = files.get(filename);
assertThat(file).isNotNull();
stringEnumAssertFunction.accept(file.toPath());
});
}
private Map<String, File> generateFromContract(String url) throws IOException {
return generateFromContract(url, new HashMap<>(), new HashMap<>());
}

View File

@ -13,6 +13,9 @@ paths:
operationId: getGiraffes
parameters:
- $ref: '#/components/parameters/refStatus'
responses:
"204":
description: Successful response
/zebras/{status}:
get:
operationId: getZebras
@ -24,11 +27,17 @@ paths:
type: integer
enum: [0,1]
default: 0
responses:
"204":
description: Successful response
/bears/{refCondition}:
get:
operationId: getBears
parameters:
- $ref: '#/components/parameters/refCondition'
responses:
"204":
description: Successful response
/camels/{condition}:
get:
operationId: getCamels
@ -41,6 +50,9 @@ paths:
enum:
- sleeping
- awake
responses:
"204":
description: Successful response
components:
parameters:
refStatus:
@ -58,4 +70,4 @@ components:
type: string
enum:
- sleeping
- awake
- awake