Skip to content

Commit

Permalink
Solve the issue of type=object being removed for MapSchema properties. (
Browse files Browse the repository at this point in the history
#1176)

Fixes #1175
  • Loading branch information
andriy-dmytruk authored Aug 24, 2023
1 parent 12ea4bb commit 7cac13e
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ protected Schema<?> bindSchemaForElement(VisitorContext context, TypedElement el
boolean addSchemaToBind = !SchemaUtils.isEmptySchema(schemaToBind);

if (addSchemaToBind) {
if (TYPE_OBJECT.equals(originalSchema.getType())) {
if (TYPE_OBJECT.equals(originalSchema.getType()) && !(originalSchema instanceof MapSchema)) {
if (composedSchema.getType() == null) {
composedSchema.setType(TYPE_OBJECT);
}
Expand All @@ -1259,7 +1259,7 @@ protected Schema<?> bindSchemaForElement(VisitorContext context, TypedElement el
composedSchema.addAllOfItem(originalSchema);
}
if (addSchemaToBind && !schemaToBind.equals(originalSchema)) {
if (TYPE_OBJECT.equals(schemaToBind.getType())) {
if (TYPE_OBJECT.equals(schemaToBind.getType()) && !(originalSchema instanceof MapSchema)) {
if (composedSchema.getType() == null) {
composedSchema.setType(TYPE_OBJECT);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package io.micronaut.openapi.visitor

import io.micronaut.openapi.AbstractOpenApiTypeElementSpec
import io.swagger.v3.oas.models.OpenAPI
import io.swagger.v3.oas.models.Operation
import io.swagger.v3.oas.models.media.ComposedSchema
import io.swagger.v3.oas.models.media.MapSchema
import io.swagger.v3.oas.models.media.Schema
import io.swagger.v3.oas.models.media.StringSchema

class OpenApiMapSchemaSpec extends AbstractOpenApiTypeElementSpec {

void "test build OpenAPI doc for map properties"() {

when:
buildBeanDefinition('test.MyBean', '''
package test;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.micronaut.core.annotation.Introspected;
import io.micronaut.http.HttpResponse;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Body;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Post;
import io.reactivex.Single;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.parameters.RequestBody;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.micronaut.core.annotation.Nullable;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Min;
import java.util.HashMap;
import java.util.Map;
/**
* Represents a pet.
*/
@Introspected
abstract class Pet {
private Map<String, String> map;
private Map<String, Pet> complexMap;
public Pet(Map<String, String> map, Map<String, Pet> complexMap) {
this.map = map;
this.complexMap = complexMap;
}
public Pet() {
}
public Map<String, String> getMap() {
return map;
}
public Map<String, Pet> getComplexMap() {
return complexMap;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void setComplexMap(Map<String, Pet> complexMap) {
this.complexMap = complexMap;
}
}
@Controller("/pets")
class PetController {
@Operation(summary = "Save a pet", description = "The saved pet information is returned")
@Tag(name = "save-pet")
@Post
HttpResponse<Pet> save(@Valid @NotNull @Body Pet pet) {
return HttpResponse.ok(pet);
}
}
''')
then: "the state is correct"
Utils.testReference != null

when: "The OpenAPI is retrieved"
OpenAPI openAPI = Utils.testReference
Schema petSchema = openAPI.components.schemas['Pet']

then: "the components are valid"
petSchema != null

petSchema instanceof Schema

petSchema.type == 'object'
petSchema.properties.size() == 2
petSchema.properties['map'] instanceof MapSchema
petSchema.properties['complexMap'] instanceof MapSchema

when:
MapSchema map = (MapSchema) petSchema.properties['map']
MapSchema complexMap = (MapSchema) petSchema.properties['complexMap']

then:
map.type == 'object'
map.additionalProperties instanceof StringSchema
complexMap.type == 'object'
complexMap.additionalProperties instanceof Schema
complexMap.additionalProperties['$ref'].contains("Pet")
}
}

0 comments on commit 7cac13e

Please sign in to comment.