Skip to content

Commit

Permalink
[JAVA] Generate client files with multiple enum oneOf types (#12687)
Browse files Browse the repository at this point in the history
* handle multiple enum types for oneof

* add updates from generate-samples.sh

* add test coverage for oneof enum generation

* update doc and var names for clarity
  • Loading branch information
l3ender authored May 31, 2023
1 parent ff414dd commit 1561c33
Show file tree
Hide file tree
Showing 3 changed files with 128 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -2736,7 +2736,9 @@ protected void updateModelForComposedSchema(CodegenModel m, Schema schema, Map<S
addProperties(allProperties, allRequired, refSchema, new HashSet<>());
} else {
// composition
addProperties(properties, required, refSchema, new HashSet<>());
Map<String, Schema> newProperties = new LinkedHashMap<>();
addProperties(newProperties, required, refSchema, new HashSet<>());
mergeProperties(properties, newProperties);
addProperties(allProperties, allRequired, refSchema, new HashSet<>());
}
}
Expand Down Expand Up @@ -2812,6 +2814,28 @@ protected void updateModelForComposedSchema(CodegenModel m, Schema schema, Map<S
// end of code block for composed schema
}

/**
* Combines all previously-detected type entries for a schema with newly-discovered ones, to ensure
* that schema for items like enum include all possible values.
*/
private void mergeProperties(Map<String, Schema> existingProperties, Map<String, Schema> newProperties) {
// https://github.com/OpenAPITools/openapi-generator/issues/12545
if (null != existingProperties && null != newProperties) {
Schema existingType = existingProperties.get("type");
Schema newType = newProperties.get("type");
existingProperties.putAll(newProperties);
if (null != existingType && null != newType && !newType.getEnum().isEmpty()) {
for (Object e : newType.getEnum()) {
// ensure all interface enum types are added to schema
if (null != existingType.getEnum() && !existingType.getEnum().contains(e)) {
existingType.addEnumItemObject(e);
}
}
existingProperties.put("type", existingType);
}
}
}

protected void updateModelForObject(CodegenModel m, Schema schema) {
if (schema.getProperties() != null || schema.getRequired() != null && !(schema instanceof ComposedSchema)) {
// passing null to allProperties and allRequired as there's no parent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,36 @@ public void testGetSchemaTypeWithComposedSchemaWithOneOf() {
Assert.assertEquals(type, "oneOf<ObjA,ObjB>");
}

@Test
public void testOneOfEnum() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue12545.json");
final DefaultCodegen codegen = new DefaultCodegen();
String modelName = "petItems";

final Schema schema = openAPI.getComponents().getSchemas().get(modelName);
codegen.setOpenAPI(openAPI);
CodegenModel petItems = codegen.fromModel(modelName, schema);

Set<String> oneOf = new TreeSet<String>();
oneOf.add("Dog");
oneOf.add("Cat");
Assert.assertEquals(petItems.oneOf, oneOf);
// make sure that animal has the property type
boolean typeSeen = false;
boolean typeContainsEnums = false;
for (CodegenProperty cp : petItems.vars) {
if ("type".equals(cp.name)) {
typeSeen = true;
if (null != cp.get_enum() && cp.get_enum().contains("dog") && cp.get_enum().contains("cat")) {
typeContainsEnums = true;
}
break;
}
}
Assert.assertTrue(typeSeen);
Assert.assertTrue(typeContainsEnums);
}

@Test
public void testComposedSchemaOneOfWithProperties() {
final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/oneOf.yaml");
Expand Down
73 changes: 73 additions & 0 deletions modules/openapi-generator/src/test/resources/3_0/issue12545.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
{
"openapi": "3.0.1",
"info": {
"version": "1.0.0",
"title": "OpenAPI Petstore"
},
"paths": {
"/": {
"get": {
"description": "get all pets in a household",
"responses": {
"200": {
"description": "successful operation",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Household"
}
}
}
}
}
}
}
},
"components": {
"schemas": {
"Household": {
"title": "Household",
"type" : "object",
"required": [
"pets"
],
"properties": {
"pets": {
"type": "array",
"title": "pets",
"items" : {
"title": "petItems",
"oneOf" : [ {
"$ref" : "#/components/schemas/Dog"
}, {
"$ref" : "#/components/schemas/Cat"
} ]
}
}
}
},
"Dog": {
"type" : "object",
"title": "Dog",
"properties" : {
"type" : {
"type" : "string",
"enum" : [ "dog" ]
}
},
"required" : [ "type" ]
},
"Cat": {
"type" : "object",
"title": "Cat",
"properties" : {
"type" : {
"type" : "string",
"enum" : [ "cat" ]
}
},
"required" : [ "type" ]
}
}
}
}

0 comments on commit 1561c33

Please sign in to comment.