[spring] Resolve regression on RequestParam for non-objects (#3855)

* [spring] Resolve regression on RequestParam for non-objects

* Regenerate Go client samples

* Include testcase for issue 3248

* Set isModel appropriately for referenced schemas
This commit is contained in:
Jim Schubert
2019-09-16 10:46:47 -04:00
committed by William Cheng
parent 4538db92a2
commit 667a6097b5
10 changed files with 417 additions and 20 deletions

View File

@@ -2303,8 +2303,9 @@ public class DefaultCodegen implements CodegenConfig {
// property.baseType = getSimpleRef(p.get$ref());
//}
// --END of revision
property.isModel = ModelUtils.isModel(p);
setNonArrayMapProperty(property, type);
Schema refOrCurrent = ModelUtils.getReferencedSchema(this.openAPI, p);
property.isModel = (ModelUtils.isComposedSchema(refOrCurrent) || ModelUtils.isObjectSchema(refOrCurrent)) && ModelUtils.isModel(refOrCurrent);
}
LOGGER.debug("debugging from property return: " + property);

View File

@@ -27,6 +27,7 @@ import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.media.*;
import io.swagger.v3.oas.models.parameters.Parameter;
import io.swagger.v3.oas.models.parameters.QueryParameter;
import io.swagger.v3.oas.models.parameters.RequestBody;
import io.swagger.v3.oas.models.responses.ApiResponse;
@@ -911,6 +912,41 @@ public class DefaultCodegenTest {
Assert.assertEquals(codegenModel.vars.size(), 1);
}
@Test
public void arrayInnerReferencedSchemaMarkedAsModel_20() {
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/2_0/arrayRefBody.yaml");
final DefaultCodegen codegen = new DefaultCodegen();
codegen.setOpenAPI(openAPI);
Set<String> imports = new HashSet<>();
RequestBody body = openAPI.getPaths().get("/examples").getPost().getRequestBody();
CodegenParameter codegenParameter = codegen.fromRequestBody(body, imports, "");
Assert.assertTrue(codegenParameter.isContainer);
Assert.assertTrue(codegenParameter.items.isModel);
Assert.assertFalse(codegenParameter.items.isContainer);
}
@Test
public void arrayInnerReferencedSchemaMarkedAsModel_30() {
final OpenAPI openAPI = TestUtils.parseSpec("src/test/resources/3_0/arrayRefBody.yaml");
new InlineModelResolver().flatten(openAPI);
final DefaultCodegen codegen = new DefaultCodegen();
codegen.setOpenAPI(openAPI);
Set<String> imports = new HashSet<>();
RequestBody body = openAPI.getPaths().get("/examples").getPost().getRequestBody();
CodegenParameter codegenParameter = codegen.fromRequestBody(body, imports, "");
Assert.assertTrue(codegenParameter.isContainer);
Assert.assertTrue(codegenParameter.items.isModel);
Assert.assertFalse(codegenParameter.items.isContainer);
}
@Test
@SuppressWarnings("unchecked")
public void commonLambdasRegistrationTest() {

View File

@@ -174,7 +174,7 @@ public class SpringCodegenTest {
String outputPath = output.getAbsolutePath().replace('\\', '/');
OpenAPI openAPI = new OpenAPIParser()
.readLocation("src/test/resources/3_0/issue_2053.yaml", null, new ParseOptions()).getOpenAPI();
.readLocation("src/test/resources/3_0/issue_2053.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
@@ -188,17 +188,97 @@ public class SpringCodegenTest {
generator.opts(input).generate();
checkFileContains(
generator,
outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)"
generator,
outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE)"
);
checkFileContains(
generator,
outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)"
generator,
outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java",
"@org.springframework.format.annotation.DateTimeFormat(iso = org.springframework.format.annotation.DateTimeFormat.ISO.DATE_TIME)"
);
}
@Test
public void shouldGenerateRequestParamForRefParams_3248_Regression() 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/3248-regression.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java",
"@RequestParam(value = \"format\"",
"@RequestParam(value = \"query\"");
}
@Test
public void shouldGenerateRequestParamForRefParams_3248_RegressionDates() 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/3248-regression-dates.yaml", null, new ParseOptions()).getOpenAPI();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.setOpenAPI(openAPI);
input.setConfig(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ExampleApi.java",
"@RequestParam(value = \"start\"");
}
@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();
SpringCodegen codegen = new SpringCodegen();
codegen.setOutputDir(output.getAbsolutePath());
codegen.additionalProperties().put(CXFServerFeatures.LOAD_TEST_DATA_FROM_FILE, "true");
ClientOptInput input = new ClientOptInput();
input.openAPI(openAPI);
input.config(codegen);
MockDefaultGenerator generator = new MockDefaultGenerator();
generator.opts(input).generate();
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/MonkeysApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ElephantsApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/ZebrasApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/BearsApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/CamelsApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/PandasApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/CrocodilesApi.java", "@RequestParam");
checkFileContains(generator, outputPath + "/src/main/java/org/openapitools/api/PolarBearsApi.java", "@RequestParam");
}
private void checkFileNotContains(MockDefaultGenerator generator, String path, String... lines) {
String file = generator.getFiles().get(path);
assertNotNull(file);
@@ -209,8 +289,14 @@ public class SpringCodegenTest {
private void checkFileContains(MockDefaultGenerator generator, String path, String... lines) {
String file = generator.getFiles().get(path);
assertNotNull(file);
for (String line : lines)
assertTrue(file.contains(line));
int expectedCount = lines.length;
int actualCount = 0;
for (String line : lines) {
if (file.contains(line)) {
actualCount++;
}
}
assertEquals(actualCount, expectedCount, "File is missing " + (expectedCount - actualCount) + " expected lines.");
}
@Test

View File

@@ -0,0 +1,52 @@
swagger: '2.0'
info:
version: ''
title: arrayRefBody
contact: {}
host: www.example.com
basePath: /
schemes:
- https
consumes:
- application/json
produces:
- application/json
paths:
/examples:
post:
description: Create an array of inputs
summary: ''
tags:
- Examples
operationId: createExamples
produces:
- application/json
parameters:
- name: body
in: body
required: true
description: inputs description
schema:
type: array
items:
$ref: '#/definitions/Input'
responses:
200:
description: successful operation
headers: {}
definitions:
Input:
title: Input
type: object
properties:
id:
type: string
age:
type: integer
format: int32
dt:
type: string
format: date-time
tags:
- name: Examples
description: 'Example inputs'

View File

@@ -0,0 +1,27 @@
openapi: 3.0.2
info:
title: info
description: info
version: 0.1.0
paths:
/example/api:
get:
summary: summary
description: description
parameters:
- name: start
in: query
schema:
type: string
format: date-time
required: true
description: The start time.
responses:
200:
description: response
content:
application/json:
schema:
type: string

View File

@@ -0,0 +1,47 @@
openapi: 3.0.2
info:
title: info
description: info
version: 0.1.0
paths:
/example/api:
get:
summary: summary
description: description
parameters:
- $ref: '#/components/parameters/requiredQueryParam'
- $ref: '#/components/parameters/formatParam'
responses:
200:
description: response
content:
application/json:
schema:
type: string
components:
parameters:
requiredQueryParam:
description: set query
in: query
name: query
required: true
schema:
type: string
formatParam:
description: set format
in: query
name: format
required: false
schema:
$ref: '#/components/schemas/format'
schemas:
format:
default: json
description: response format
enum:
- json
- csv
type: string

View File

@@ -0,0 +1,35 @@
openapi: 3.0.0
info:
title: ''
version: ''
paths:
/examples:
post:
tags:
- Examples
summary: Get a list of transactions
operationId: getFilteredTransactions
responses:
default:
description: successful operation
requestBody:
description: subscription payload
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Input'
components:
schemas:
Input:
type: object
properties:
id:
type: string
age:
type: integer
format: int32
dt:
type: string
format: date-time

View File

@@ -0,0 +1,121 @@
openapi: 3.0.0
servers:
- url: 'localhost:8080'
info:
version: 1.0.0
title: OpenAPI Zoo
license:
name: Apache-2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
paths:
/monkeys:
get:
operationId: getMonkeys
parameters:
- $ref: '#/components/parameters/refDate'
/elephants:
get:
operationId: getElephants
parameters:
- in: query
name: someDate
required: true
schema:
type: string
format: date
/girafes:
get:
operationId: getGirafes
parameters:
- $ref: '#/components/parameters/refStatus'
/zebras:
get:
operationId: getZebras
parameters:
- in: query
name: status
required: true
schema:
type: integer
enum: [0,1]
default: 0
/bears:
get:
operationId: getBears
parameters:
- $ref: '#/components/parameters/refCondition'
/camels:
get:
operationId: getCamels
parameters:
- in: query
name: condition
required: true
schema:
type: string
enum:
- sleeping
- awake
/pandas:
get:
operationId: getPandas
parameters:
- $ref: '#/components/parameters/refName'
/crocodiles:
get:
operationId: getCrocodiles
parameters:
- in: query
name: name
required: true
schema:
type: string
/polarBears:
get:
operationId: getPolarBears
parameters:
- $ref: '#/components/parameters/refAge'
/birds:
get:
operationId: getBirds
parameters:
- in: query
name: age
required: true
schema:
type: integer
components:
parameters:
refDate:
in: query
name: refDate
required: true
schema:
type: string
format: date
refStatus:
in: query
name: refStatus
required: true
schema:
type: integer
enum: [0,1]
default: 0
refCondition:
in: query
name: refCondition
schema:
type: string
enum:
- sleeping
- awake
refName:
in: query
name: refName
schema:
type: string
refAge:
in: query
name: refAge
schema:
type: integer

View File

@@ -835,11 +835,7 @@ func (a *FakeApiService) TestEndpointParameters(ctx _context.Context, number flo
localVarFormParams.Add("date", parameterToString(localVarOptionals.Date.Value(), ""))
}
if localVarOptionals != nil && localVarOptionals.DateTime.IsSet() {
paramJson, err := parameterToJson(localVarOptionals.DateTime.Value())
if err != nil {
return nil, err
}
localVarFormParams.Add("dateTime", paramJson)
localVarFormParams.Add("dateTime", parameterToString(localVarOptionals.DateTime.Value(), ""))
}
if localVarOptionals != nil && localVarOptionals.Password.IsSet() {
localVarFormParams.Add("password", parameterToString(localVarOptionals.Password.Value(), ""))

View File

@@ -834,11 +834,7 @@ func (a *FakeApiService) TestEndpointParameters(ctx _context.Context, number flo
localVarFormParams.Add("date", parameterToString(localVarOptionals.Date.Value(), ""))
}
if localVarOptionals != nil && localVarOptionals.DateTime.IsSet() {
paramJson, err := parameterToJson(localVarOptionals.DateTime.Value())
if err != nil {
return nil, err
}
localVarFormParams.Add("dateTime", paramJson)
localVarFormParams.Add("dateTime", parameterToString(localVarOptionals.DateTime.Value(), ""))
}
if localVarOptionals != nil && localVarOptionals.Password.IsSet() {
localVarFormParams.Add("password", parameterToString(localVarOptionals.Password.Value(), ""))