diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java index dfd9f1a470e..624bdf6f76b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenModel.java @@ -150,6 +150,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { private String pattern; private Number multipleOf; private CodegenProperty items; + private CodegenProperty additionalProperties; private boolean isModel; public String getAdditionalPropertiesType() { @@ -602,6 +603,14 @@ public class CodegenModel implements IJsonSchemaValidationProperties { this.isArray = isArray; } + @Override + public CodegenProperty getAdditionalProperties() { return additionalProperties; } + + @Override + public void setAdditionalProperties(CodegenProperty additionalProperties) { + this.additionalProperties = additionalProperties; + } + // indicates if the model component has validation on the root level schema // this will be true when minItems or minProperties is set public boolean hasValidation() { @@ -769,6 +778,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { Objects.equals(getMaximum(), that.getMaximum()) && Objects.equals(getPattern(), that.getPattern()) && Objects.equals(getItems(), that.getItems()) && + Objects.equals(getAdditionalProperties(), that.getAdditionalProperties()) && Objects.equals(getIsModel(), that.getIsModel()) && Objects.equals(getMultipleOf(), that.getMultipleOf()); } @@ -787,7 +797,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { hasChildren, isMap, isDeprecated, hasOnlyReadOnly, getExternalDocumentation(), getVendorExtensions(), getAdditionalPropertiesType(), getMaxProperties(), getMinProperties(), getUniqueItems(), getMaxItems(), getMinItems(), getMaxLength(), getMinLength(), getExclusiveMinimum(), getExclusiveMaximum(), getMinimum(), - getMaximum(), getPattern(), getMultipleOf(), getItems(), getIsModel()); + getMaximum(), getPattern(), getMultipleOf(), getItems(), getAdditionalProperties(), getIsModel()); } @Override @@ -869,6 +879,7 @@ public class CodegenModel implements IJsonSchemaValidationProperties { sb.append(", pattern='").append(pattern).append('\''); sb.append(", multipleOf='").append(multipleOf).append('\''); sb.append(", items='").append(items).append('\''); + sb.append(", additionalProperties='").append(additionalProperties).append('\''); sb.append(", isModel='").append(isModel).append('\''); sb.append('}'); return sb.toString(); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java index f7a7c92c364..61fa928c20e 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenParameter.java @@ -42,6 +42,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { public List _enum; public Map allowableValues; public CodegenProperty items; + public CodegenProperty additionalProperties; public CodegenProperty mostInnerItems; public Map vendorExtensions = new HashMap(); public boolean hasValidation; @@ -145,6 +146,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { output.maximum = this.maximum; output.minimum = this.minimum; output.pattern = this.pattern; + output.additionalProperties = this.additionalProperties; if (this._enum != null) { output._enum = new ArrayList(this._enum); @@ -191,7 +193,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { @Override public int hashCode() { - return Objects.hash(isFormParam, isQueryParam, isPathParam, isHeaderParam, isCookieParam, isBodyParam, hasMore, isContainer, secondaryParam, isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, baseName, paramName, dataType, datatypeWithEnum, dataFormat, collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName, style, example, jsonSchema, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isFreeFormObject, isAnyType, isArray, isMap, isFile, isEnum, _enum, allowableValues, items, mostInnerItems, vendorExtensions, hasValidation, getMaxProperties(), getMinProperties(), isNullable, required, getMaximum(), getExclusiveMaximum(), getMinimum(), getExclusiveMinimum(), getMaxLength(), getMinLength(), getPattern(), getMaxItems(), getMinItems(), getUniqueItems(), contentType, multipleOf); + return Objects.hash(isFormParam, isQueryParam, isPathParam, isHeaderParam, isCookieParam, isBodyParam, hasMore, isContainer, secondaryParam, isCollectionFormatMulti, isPrimitiveType, isModel, isExplode, baseName, paramName, dataType, datatypeWithEnum, dataFormat, collectionFormat, description, unescapedDescription, baseType, defaultValue, enumName, style, example, jsonSchema, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isFreeFormObject, isAnyType, isArray, isMap, isFile, isEnum, _enum, allowableValues, items, mostInnerItems, additionalProperties, vendorExtensions, hasValidation, getMaxProperties(), getMinProperties(), isNullable, required, getMaximum(), getExclusiveMaximum(), getMinimum(), getExclusiveMinimum(), getMaxLength(), getMinLength(), getPattern(), getMaxItems(), getMinItems(), getUniqueItems(), contentType, multipleOf); } @Override @@ -256,6 +258,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { Objects.equals(_enum, that._enum) && Objects.equals(allowableValues, that.allowableValues) && Objects.equals(items, that.items) && + Objects.equals(additionalProperties, that.additionalProperties) && Objects.equals(mostInnerItems, that.mostInnerItems) && Objects.equals(vendorExtensions, that.vendorExtensions) && Objects.equals(getMaxProperties(), that.getMaxProperties()) && @@ -326,6 +329,7 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { sb.append(", allowableValues=").append(allowableValues); sb.append(", items=").append(items); sb.append(", mostInnerItems=").append(mostInnerItems); + sb.append(", additionalProperties=").append(additionalProperties); sb.append(", vendorExtensions=").append(vendorExtensions); sb.append(", hasValidation=").append(hasValidation); sb.append(", maxProperties=").append(maxProperties); @@ -527,5 +531,13 @@ public class CodegenParameter implements IJsonSchemaValidationProperties { public void setIsArray(boolean isArray) { this.isArray = isArray; } + + @Override + public CodegenProperty getAdditionalProperties() { return additionalProperties; } + + @Override + public void setAdditionalProperties(CodegenProperty additionalProperties) { + this.additionalProperties = additionalProperties; + } } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java index e37e1147229..efabd68731b 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenProperty.java @@ -159,6 +159,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti // If 'additionalProperties' is set to a type or refers to a type, 'items' provides the type information for // the undeclared properties. public CodegenProperty items; + public CodegenProperty additionalProperties; public CodegenProperty mostInnerItems; public Map vendorExtensions = new HashMap(); public boolean hasValidation; // true if pattern, maximum, etc are set (only used in the mustache template) @@ -461,6 +462,14 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti this.items = items; } + @Override + public CodegenProperty getAdditionalProperties() { return additionalProperties; } + + @Override + public void setAdditionalProperties(CodegenProperty additionalProperties) { + this.additionalProperties = additionalProperties; + } + @Override public boolean getIsModel() { return isModel; } @@ -594,6 +603,9 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti if (this.items != null) { cp.items = this.items; } + if (this.additionalProperties != null) { + cp.additionalProperties = this.additionalProperties; + } if (this.mostInnerItems != null) { cp.mostInnerItems = this.mostInnerItems; } @@ -712,6 +724,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti sb.append(", _enum=").append(_enum); sb.append(", allowableValues=").append(allowableValues); sb.append(", items=").append(items); + sb.append(", additionalProperties=").append(additionalProperties); sb.append(", mostInnerItems=").append(mostInnerItems); sb.append(", vendorExtensions=").append(vendorExtensions); sb.append(", hasValidation=").append(hasValidation); @@ -808,6 +821,7 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti Objects.equals(_enum, that._enum) && Objects.equals(allowableValues, that.allowableValues) && Objects.equals(items, that.items) && + Objects.equals(additionalProperties, that.additionalProperties) && Objects.equals(mostInnerItems, that.mostInnerItems) && Objects.equals(vendorExtensions, that.vendorExtensions) && Objects.equals(discriminatorValue, that.discriminatorValue) && @@ -834,7 +848,8 @@ public class CodegenProperty implements Cloneable, IJsonSchemaValidationProperti isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBinary, isFile, isBoolean, isDate, isDateTime, isUuid, isUri, isEmail, isFreeFormObject, isArray, isMap, isEnum, isReadOnly, isWriteOnly, isNullable, - isSelfReference, isCircularReference, isDiscriminator, _enum, allowableValues, items, mostInnerItems, + isSelfReference, isCircularReference, isDiscriminator, _enum, allowableValues, + items, mostInnerItems, additionalProperties, vendorExtensions, hasValidation, isInherited, discriminatorValue, nameInCamelCase, nameInSnakeCase, enumName, maxItems, minItems, isXmlAttribute, xmlPrefix, xmlName, xmlNamespace, isXmlWrapped); diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java index cc8397e95a8..b0e79592c00 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/CodegenResponse.java @@ -74,13 +74,14 @@ public class CodegenResponse implements IJsonSchemaValidationProperties { public String pattern; public Number multipleOf; public CodegenProperty items; + public CodegenProperty additionalProperties; @Override public int hashCode() { return Objects.hash(headers, code, message, hasMore, examples, dataType, baseType, containerType, hasHeaders, isString, isNumeric, isInteger, isLong, isNumber, isFloat, isDouble, isByteArray, isBoolean, isDate, isDateTime, isUuid, isEmail, isModel, isFreeFormObject, isAnyType, isDefault, simpleType, primitiveType, - isMap, isArray, isBinary, isFile, schema, jsonSchema, vendorExtensions, items, + isMap, isArray, isBinary, isFile, schema, jsonSchema, vendorExtensions, items, additionalProperties, getMaxProperties(), getMinProperties(), uniqueItems, getMaxItems(), getMinItems(), getMaxLength(), getMinLength(), exclusiveMinimum, exclusiveMaximum, getMinimum(), getMaximum(), getPattern()); } @@ -116,6 +117,7 @@ public class CodegenResponse implements IJsonSchemaValidationProperties { isBinary == that.isBinary && isFile == that.isFile && items == that.items && + additionalProperties == that.additionalProperties && Objects.equals(headers, that.headers) && Objects.equals(code, that.code) && Objects.equals(message, that.message) && @@ -322,6 +324,14 @@ public class CodegenResponse implements IJsonSchemaValidationProperties { this.isMap = isMap; } + @Override + public CodegenProperty getAdditionalProperties() { return additionalProperties; } + + @Override + public void setAdditionalProperties(CodegenProperty additionalProperties) { + this.additionalProperties = additionalProperties; + } + @Override public String toString() { final StringBuilder sb = new StringBuilder("CodegenResponse{"); @@ -374,6 +384,7 @@ public class CodegenResponse implements IJsonSchemaValidationProperties { sb.append(", pattern='").append(pattern).append('\''); sb.append(", multipleOf='").append(multipleOf).append('\''); sb.append(", items='").append(items).append('\''); + sb.append(", additionalProperties='").append(additionalProperties).append('\''); sb.append('}'); return sb.toString(); } 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 ebec1118c14..97feb4238ad 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 @@ -2598,15 +2598,21 @@ public class DefaultCodegen implements CodegenConfig { m.isAdditionalPropertiesTrue = false; } else { m.isAdditionalPropertiesTrue = true; + CodegenProperty cp = fromProperty("", new Schema()); + m.setAdditionalProperties(cp); } } else if (schema.getAdditionalProperties() instanceof Boolean) { if (Boolean.TRUE.equals(schema.getAdditionalProperties())) { m.isAdditionalPropertiesTrue = true; + CodegenProperty cp = fromProperty("", new Schema()); + m.setAdditionalProperties(cp); } else { m.isAdditionalPropertiesTrue = false; } } else { m.isAdditionalPropertiesTrue = false; + CodegenProperty cp = fromProperty("", (Schema) schema.getAdditionalProperties()); + m.setAdditionalProperties(cp); } // post process model properties @@ -3366,6 +3372,24 @@ public class DefaultCodegen implements CodegenConfig { property.isModel = (ModelUtils.isComposedSchema(refOrCurrent) || ModelUtils.isObjectSchema(refOrCurrent)) && ModelUtils.isModel(refOrCurrent); } + // process 'additionalProperties' + if ("object".equals(p.getType())) { + if (p.getAdditionalProperties() == null) { + if (!disallowAdditionalPropertiesIfNotPresent) { + CodegenProperty cp = fromProperty("", new Schema()); + property.setAdditionalProperties(cp); + } + } else if (p.getAdditionalProperties() instanceof Boolean) { + if (Boolean.TRUE.equals(p.getAdditionalProperties())) { + CodegenProperty cp = fromProperty("", new Schema()); + property.setAdditionalProperties(cp); + } + } else { + CodegenProperty cp = fromProperty("", (Schema) p.getAdditionalProperties()); + property.setAdditionalProperties(cp); + } + } + LOGGER.debug("debugging from property return: " + property); schemaCodegenPropertyCache.put(ns, property); return property; @@ -4090,6 +4114,24 @@ public class DefaultCodegen implements CodegenConfig { } r.primitiveType = (r.baseType == null || languageSpecificPrimitives().contains(r.baseType)); + + // process 'additionalProperties' + if ("object".equals(responseSchema.getType())) { + if (responseSchema.getAdditionalProperties() == null) { + if (!disallowAdditionalPropertiesIfNotPresent) { + CodegenProperty addPropProp = fromProperty("", new Schema()); + r.setAdditionalProperties(addPropProp); + } + } else if (responseSchema.getAdditionalProperties() instanceof Boolean) { + if (Boolean.TRUE.equals(responseSchema.getAdditionalProperties())) { + CodegenProperty addPropProp = fromProperty("", new Schema()); + r.setAdditionalProperties(addPropProp); + } + } else { + CodegenProperty addPropProp = fromProperty("", (Schema) responseSchema.getAdditionalProperties()); + r.setAdditionalProperties(addPropProp); + } + } } if (r.baseType == null) { @@ -4379,6 +4421,24 @@ public class DefaultCodegen implements CodegenConfig { codegenParameter.hasValidation = true; } + // process 'additionalProperties' + if ("object".equals(parameterSchema.getType())) { + if (parameterSchema.getAdditionalProperties() == null) { + if (!disallowAdditionalPropertiesIfNotPresent) { + CodegenProperty cp = fromProperty("", new Schema()); + codegenParameter.setAdditionalProperties(cp); + } + } else if (parameterSchema.getAdditionalProperties() instanceof Boolean) { + if (Boolean.TRUE.equals(parameterSchema.getAdditionalProperties())) { + CodegenProperty cp = fromProperty("", new Schema()); + codegenParameter.setAdditionalProperties(cp); + } + } else { + CodegenProperty cp = fromProperty("", (Schema) parameterSchema.getAdditionalProperties()); + codegenParameter.setAdditionalProperties(cp); + } + } + } else { LOGGER.error("ERROR! Not handling " + parameter + " as Body Parameter at the moment"); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java index fe451e62471..e0ee277fd0f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/IJsonSchemaValidationProperties.java @@ -76,4 +76,8 @@ public interface IJsonSchemaValidationProperties { boolean getIsArray(); void setIsArray(boolean isArray); + + CodegenProperty getAdditionalProperties(); + + void setAdditionalProperties(CodegenProperty additionalProperties); } diff --git a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppTizenClientCodegen.java b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppTizenClientCodegen.java index c0db6bec907..16bd058996f 100644 --- a/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppTizenClientCodegen.java +++ b/modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/CppTizenClientCodegen.java @@ -288,7 +288,10 @@ public class CppTizenClientCodegen extends AbstractCppCodegen implements Codegen @Override public String toVarName(String name) { String paramName = name.replaceAll("[^a-zA-Z0-9_]", ""); - paramName = Character.toLowerCase(paramName.charAt(0)) + paramName.substring(1); + if (name.length() > 0 ) { + // additionalProperties name is "" so name.length() == 0 + paramName = Character.toLowerCase(paramName.charAt(0)) + paramName.substring(1); + } if (isReservedWord(paramName)) { return escapeReservedWord(paramName); } 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 1899afb9fc3..c100f5ce91e 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 @@ -2341,6 +2341,168 @@ public class DefaultCodegenTest { assertEquals(co.responses.get(0).getItems().getMaximum(), "7"); } + @Test + public void testAdditionalPropertiesPresentInModels() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7613.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setDisallowAdditionalPropertiesIfNotPresent(false); + + String modelName; + Schema sc; + CodegenModel cm; + CodegenProperty anyTypeSchema = codegen.fromProperty("", new Schema()); + + modelName = "AdditionalPropertiesUnset"; + sc = openAPI.getComponents().getSchemas().get(modelName); + cm = codegen.fromModel(modelName, sc); + assertEquals(cm.getAdditionalProperties(), anyTypeSchema); + + modelName = "AdditionalPropertiesTrue"; + sc = openAPI.getComponents().getSchemas().get(modelName); + cm = codegen.fromModel(modelName, sc); + assertEquals(cm.getAdditionalProperties(), anyTypeSchema); + + modelName = "AdditionalPropertiesFalse"; + sc = openAPI.getComponents().getSchemas().get(modelName); + cm = codegen.fromModel(modelName, sc); + assertEquals(cm.getAdditionalProperties(), null); + + modelName = "AdditionalPropertiesSchema"; + sc = openAPI.getComponents().getSchemas().get(modelName); + cm = codegen.fromModel(modelName, sc); + CodegenProperty stringCp = codegen.fromProperty("", new Schema().type("string")); + assertEquals(cm.getAdditionalProperties(), stringCp); + } + + @Test + public void testAdditionalPropertiesPresentInModelProperties() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7613.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setDisallowAdditionalPropertiesIfNotPresent(false); + + String modelName; + Schema sc; + CodegenModel cm; + CodegenProperty anyTypeSchema = codegen.fromProperty("", new Schema()); + CodegenProperty stringCp = codegen.fromProperty("", new Schema().type("string")); + CodegenProperty mapWithAddPropsUnset; + CodegenProperty mapWithAddPropsTrue; + CodegenProperty mapWithAddPropsFalse; + CodegenProperty mapWithAddPropsSchema; + + modelName = "ObjectModelWithRefAddPropsInProps"; + sc = openAPI.getComponents().getSchemas().get(modelName); + cm = codegen.fromModel(modelName, sc); + mapWithAddPropsUnset = cm.getVars().get(0); + assertEquals(mapWithAddPropsUnset.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsTrue = cm.getVars().get(1); + assertEquals(mapWithAddPropsTrue.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsFalse = cm.getVars().get(2); + assertEquals(mapWithAddPropsFalse.getAdditionalProperties(), null); + mapWithAddPropsSchema = cm.getVars().get(3); + assertEquals(mapWithAddPropsSchema.getAdditionalProperties(), stringCp); + + modelName = "ObjectModelWithAddPropsInProps"; + sc = openAPI.getComponents().getSchemas().get(modelName); + cm = codegen.fromModel(modelName, sc); + mapWithAddPropsUnset = cm.getVars().get(0); + assertEquals(mapWithAddPropsUnset.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsTrue = cm.getVars().get(1); + assertEquals(mapWithAddPropsTrue.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsFalse = cm.getVars().get(2); + assertEquals(mapWithAddPropsFalse.getAdditionalProperties(), null); + mapWithAddPropsSchema = cm.getVars().get(3); + assertEquals(mapWithAddPropsSchema.getAdditionalProperties(), stringCp); + } + + @Test + public void testAdditionalPropertiesPresentInParameters() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7613.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setDisallowAdditionalPropertiesIfNotPresent(false); + + String path; + Operation operation; + CodegenOperation co; + + CodegenProperty anyTypeSchema = codegen.fromProperty("", new Schema()); + CodegenProperty stringCp = codegen.fromProperty("", new Schema().type("string")); + CodegenParameter mapWithAddPropsUnset; + CodegenParameter mapWithAddPropsTrue; + CodegenParameter mapWithAddPropsFalse; + CodegenParameter mapWithAddPropsSchema; + + path = "/ref_additional_properties/"; + operation = openAPI.getPaths().get(path).getPost(); + co = codegen.fromOperation(path, "POST", operation, null); + mapWithAddPropsUnset = co.queryParams.get(0); + assertEquals(mapWithAddPropsUnset.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsTrue = co.queryParams.get(1); + assertEquals(mapWithAddPropsTrue.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsFalse = co.queryParams.get(2); + assertEquals(mapWithAddPropsFalse.getAdditionalProperties(), null); + mapWithAddPropsSchema = co.queryParams.get(3); + assertEquals(mapWithAddPropsSchema.getAdditionalProperties(), stringCp); + + path = "/additional_properties/"; + operation = openAPI.getPaths().get(path).getPost(); + co = codegen.fromOperation(path, "POST", operation, null); + mapWithAddPropsUnset = co.queryParams.get(0); + assertEquals(mapWithAddPropsUnset.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsTrue = co.queryParams.get(1); + assertEquals(mapWithAddPropsTrue.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsFalse = co.queryParams.get(2); + assertEquals(mapWithAddPropsFalse.getAdditionalProperties(), null); + mapWithAddPropsSchema = co.queryParams.get(3); + assertEquals(mapWithAddPropsSchema.getAdditionalProperties(), stringCp); + } + + @Test + public void testAdditionalPropertiesPresentInResponses() { + final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7613.yaml"); + final DefaultCodegen codegen = new DefaultCodegen(); + codegen.setOpenAPI(openAPI); + codegen.setDisallowAdditionalPropertiesIfNotPresent(false); + + String path; + Operation operation; + CodegenOperation co; + + CodegenProperty anyTypeSchema = codegen.fromProperty("", new Schema()); + CodegenProperty stringCp = codegen.fromProperty("", new Schema().type("string")); + CodegenResponse mapWithAddPropsUnset; + CodegenResponse mapWithAddPropsTrue; + CodegenResponse mapWithAddPropsFalse; + CodegenResponse mapWithAddPropsSchema; + + path = "/ref_additional_properties/"; + operation = openAPI.getPaths().get(path).getPost(); + co = codegen.fromOperation(path, "POST", operation, null); + mapWithAddPropsUnset = co.responses.get(0); + assertEquals(mapWithAddPropsUnset.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsTrue = co.responses.get(1); + assertEquals(mapWithAddPropsTrue.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsFalse = co.responses.get(2); + assertEquals(mapWithAddPropsFalse.getAdditionalProperties(), null); + mapWithAddPropsSchema = co.responses.get(3); + assertEquals(mapWithAddPropsSchema.getAdditionalProperties(), stringCp); + + path = "/additional_properties/"; + operation = openAPI.getPaths().get(path).getPost(); + co = codegen.fromOperation(path, "POST", operation, null); + mapWithAddPropsUnset = co.responses.get(0); + assertEquals(mapWithAddPropsUnset.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsTrue = co.responses.get(1); + assertEquals(mapWithAddPropsTrue.getAdditionalProperties(), anyTypeSchema); + mapWithAddPropsFalse = co.responses.get(2); + assertEquals(mapWithAddPropsFalse.getAdditionalProperties(), null); + mapWithAddPropsSchema = co.responses.get(3); + assertEquals(mapWithAddPropsSchema.getAdditionalProperties(), stringCp); + } + @Test public void testIsXPresence() { final OpenAPI openAPI = TestUtils.parseFlattenSpec("src/test/resources/3_0/issue_7651.yaml"); diff --git a/modules/openapi-generator/src/test/resources/3_0/issue_7613.yaml b/modules/openapi-generator/src/test/resources/3_0/issue_7613.yaml index 29f45be7444..48645fc0400 100644 --- a/modules/openapi-generator/src/test/resources/3_0/issue_7613.yaml +++ b/modules/openapi-generator/src/test/resources/3_0/issue_7613.yaml @@ -72,6 +72,116 @@ paths: type: integer format: int64 maximum: 7 + /ref_additional_properties/: + post: + tags: + - additional_properties + operationId: arrayWithValidationsInItems + parameters: + - name: additionalPropertiesUnset + in: query + required: true + schema: + $ref: '#/components/schemas/AdditionalPropertiesUnset' + - name: additionalPropertiesTrue + in: query + required: true + schema: + $ref: '#/components/schemas/AdditionalPropertiesTrue' + - name: additionalPropertiesFalse + in: query + required: true + schema: + $ref: '#/components/schemas/AdditionalPropertiesFalse' + - name: additionalPropertiesSchema + in: query + required: true + schema: + $ref: '#/components/schemas/AdditionalPropertiesSchema' + responses: + "200": + description: "200" + content: + application/json: + schema: + $ref: '#/components/schemas/AdditionalPropertiesUnset' + "201": + description: "201" + content: + application/xml: + schema: + $ref: '#/components/schemas/AdditionalPropertiesTrue' + "202": + description: "202" + content: + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/AdditionalPropertiesFalse' + "203": + description: "203" + content: + application/*: + schema: + $ref: '#/components/schemas/AdditionalPropertiesSchema' + /additional_properties/: + post: + tags: + - additional_properties + operationId: arrayWithValidationsInItems + parameters: + - name: additionalPropertiesUnset + in: query + required: true + schema: + type: object + - name: additionalPropertiesTrue + in: query + required: true + schema: + type: object + additionalProperties: true + - name: additionalPropertiesFalse + in: query + required: true + schema: + type: object + additionalProperties: false + - name: additionalPropertiesSchema + in: query + required: true + schema: + type: object + additionalProperties: + type: string + responses: + "200": + description: "200" + content: + application/json: + schema: + type: object + "201": + description: "201" + content: + application/json: + schema: + type: object + additionalProperties: true + "202": + description: "202" + content: + application/json: + schema: + type: object + additionalProperties: false + "203": + description: "203" + content: + application/json: + schema: + type: object + additionalProperties: + type: string components: schemas: ArrayWithValidationsInItems: @@ -110,4 +220,42 @@ components: - type: integer format: int64 maximum: 7 + AdditionalPropertiesUnset: + type: object + AdditionalPropertiesTrue: + type: object + additionalProperties: true + AdditionalPropertiesFalse: + type: object + additionalProperties: false + AdditionalPropertiesSchema: + type: object + additionalProperties: + type: string + ObjectModelWithRefAddPropsInProps: + type: object + properties: + map_with_additional_properties_unset: + $ref: '#/components/schemas/AdditionalPropertiesUnset' + map_with_additional_properties_true: + $ref: '#/components/schemas/AdditionalPropertiesTrue' + map_with_additional_properties_false: + $ref: '#/components/schemas/AdditionalPropertiesFalse' + map_with_additional_properties_schema: + $ref: '#/components/schemas/AdditionalPropertiesSchema' + ObjectModelWithAddPropsInProps: + type: object + properties: + map_with_additional_properties_unset: + type: object + map_with_additional_properties_true: + type: object + additionalProperties: true + map_with_additional_properties_false: + type: object + additionalProperties: false + map_with_additional_properties_schema: + type: object + additionalProperties: + type: string securitySchemes: {} \ No newline at end of file