Skip to content

Commit 85ac288

Browse files
authored
Fix process JsonUnwrapped schemas (#1603)
Fixed #1602
1 parent 21d03b4 commit 85ac288

File tree

2 files changed

+57
-5
lines changed

2 files changed

+57
-5
lines changed

openapi/src/main/java/io/micronaut/openapi/visitor/AbstractOpenApiVisitor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@
214214
import static io.micronaut.openapi.visitor.StringUtil.SLASH;
215215
import static io.micronaut.openapi.visitor.StringUtil.UNDERSCORE;
216216
import static io.micronaut.openapi.visitor.Utils.isOpenapi31;
217+
import static io.micronaut.openapi.visitor.Utils.resolveOpenApi;
217218
import static java.util.stream.Collectors.toMap;
218219

219220
/**
@@ -1172,9 +1173,14 @@ private Schema<?> processGenericAnnotations(Schema<?> schema, ClassElement compo
11721173
private void handleUnwrapped(VisitorContext context, Element element, ClassElement elementType, Schema<?> parentSchema, AnnotationValue<JsonUnwrapped> uw) {
11731174
Map<String, Schema> schemas = SchemaUtils.resolveSchemas(Utils.resolveOpenApi(context));
11741175
ClassElement customElementType = getCustomSchema(elementType.getName(), elementType.getTypeArguments(), context);
1176+
var elType = customElementType != null ? customElementType : elementType;
11751177
String schemaName = stringValue(element, io.swagger.v3.oas.annotations.media.Schema.class, PROP_NAME)
1176-
.orElse(computeDefaultSchemaName(null, customElementType != null ? customElementType : elementType, elementType.getTypeArguments(), context, null));
1178+
.orElse(computeDefaultSchemaName(null, elType, elementType.getTypeArguments(), context, null));
11771179
Schema<?> wrappedPropertySchema = schemas.get(schemaName);
1180+
if (wrappedPropertySchema == null) {
1181+
getSchemaDefinition(resolveOpenApi(context), context, elType, elType.getTypeArguments(), element, Collections.emptyList(), null);
1182+
wrappedPropertySchema = schemas.get(schemaName);
1183+
}
11781184
Map<String, Schema> properties = wrappedPropertySchema.getProperties();
11791185
if (CollectionUtils.isEmpty(properties)) {
11801186
return;

openapi/src/test/groovy/io/micronaut/openapi/visitor/OpenApiJsonUnwrappedsSpec.groovy

Lines changed: 50 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class OpenApiJsonUnwrappedsSpec extends AbstractOpenApiTypeElementSpec {
88

99
void "test JsonUnwrapped annotation"() {
1010

11-
given:"An API definition"
11+
given: "An API definition"
1212
when:
1313
buildBeanDefinition('test.MyBean', '''
1414
package test;
@@ -91,16 +91,16 @@ class Test {
9191
@jakarta.inject.Singleton
9292
class MyBean {}
9393
''')
94-
then:"the state is correct"
94+
then: "the state is correct"
9595
Utils.testReference != null
9696

97-
when:"The OpenAPI is retrieved"
97+
when: "The OpenAPI is retrieved"
9898
OpenAPI openAPI = Utils.testReference
9999
Schema schema = openAPI.components.schemas['Test']
100100
Schema dummySchema = openAPI.components.schemas['Dummy']
101101
Schema petSchema = openAPI.components.schemas['Pet']
102102

103-
then:"the components are valid"
103+
then: "the components are valid"
104104
schema.type == 'object'
105105
schema.properties.size() == 13
106106
schema.properties['plain'].$ref == '#/components/schemas/Dummy'
@@ -176,4 +176,50 @@ class MyBean {}
176176
exampleSchema.properties.nameInJson.type == 'string'
177177
exampleSchema.properties.nameInJson.description == 'example field'
178178
}
179+
180+
void "test issue with JsonUnwrapped and wildcard response type"() {
181+
182+
given: "An API definition"
183+
when:
184+
buildBeanDefinition('test.MyBean', '''
185+
package test;
186+
187+
import com.fasterxml.jackson.annotation.JsonUnwrapped;
188+
import io.micronaut.http.annotation.Controller;
189+
import io.micronaut.http.annotation.Post;
190+
import io.reactivex.Single;
191+
192+
@Controller("/test")
193+
interface TestOperations {
194+
195+
@Post
196+
Single<Test<?>> save(String name, int age);
197+
}
198+
199+
class Base {
200+
201+
public String name;
202+
}
203+
204+
class Test<T extends Base> {
205+
@JsonUnwrapped
206+
public T wrapped;
207+
}
208+
209+
@jakarta.inject.Singleton
210+
class MyBean {}
211+
''')
212+
then: "the state is correct"
213+
Utils.testReference != null
214+
215+
when: "The OpenAPI is retrieved"
216+
def openApi = Utils.testReference
217+
Schema schema = openApi.components.schemas.Test_Base_
218+
219+
then: "the components are valid"
220+
schema.type == 'object'
221+
schema.properties
222+
schema.properties.size() == 1
223+
schema.properties.name
224+
}
179225
}

0 commit comments

Comments
 (0)