Skip to content

Commit 5239cae

Browse files
fix: serialize a boolean schema example value as a JsonNode (#5173)
1 parent 6550721 commit 5239cae

4 files changed

Lines changed: 175 additions & 6 deletions

File tree

modules/swagger-core/src/main/java/io/swagger/v3/core/util/AnnotationsUtils.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -938,13 +938,18 @@ private static boolean shouldUseNodeAsExample(JsonNode node, Schema schemaObject
938938
if (node.isObject() || node.isArray()) {
939939
return true;
940940
}
941-
if (schemaObject != null && SchemaTypeUtils.isNumberSchema(schemaObject)) {
942-
return true;
943-
}
944-
if (schemaObject != null && SchemaTypeUtils.isStringSchema(schemaObject)) {
945-
return false;
941+
if (schemaObject != null) {
942+
if (SchemaTypeUtils.isNumberSchema(schemaObject)) {
943+
return true;
944+
}
945+
if (SchemaTypeUtils.isBooleanSchema(schemaObject)) {
946+
return true;
947+
}
948+
if (SchemaTypeUtils.isStringSchema(schemaObject)) {
949+
return false;
950+
}
946951
}
947-
return node.isNumber();
952+
return node.isNumber() || node.isBoolean();
948953
}
949954

950955
private static void setDefaultSchema(io.swagger.v3.oas.annotations.media.Schema schema, boolean openapi31, Schema schemaObject) {

modules/swagger-core/src/main/java/io/swagger/v3/core/util/SchemaTypeUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public class SchemaTypeUtils {
99
private static final String STRING_TYPE = "string";
1010
private static final String NUMBER_TYPE = "number";
1111
private static final String INTEGER_TYPE = "integer";
12+
private static final String BOOLEAN_TYPE = "boolean";
1213

1314
public static boolean isObjectSchema(Schema schema) {
1415
return isSchemaType(schema, OBJECT_TYPE) || (schema.getType() == null && (hasProperties(schema) || hasPatternProperties(schema)));
@@ -26,6 +27,10 @@ public static boolean isNumberSchema(Schema schema) {
2627
return isSchemaType(schema, NUMBER_TYPE) || isSchemaType(schema, INTEGER_TYPE);
2728
}
2829

30+
public static boolean isBooleanSchema(Schema schema) {
31+
return isSchemaType(schema, BOOLEAN_TYPE);
32+
}
33+
2934
private static boolean isSchemaType(Schema schema, String type) {
3035
return type.equals(schema.getType()) || isSchemaType31(schema, type);
3136
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package io.swagger.v3.core.converting;
2+
3+
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.fasterxml.jackson.databind.ObjectMapper;
5+
import io.swagger.v3.core.converter.ModelConverters;
6+
import io.swagger.v3.core.converter.ResolvedSchema;
7+
import io.swagger.v3.core.util.Json31;
8+
import org.testng.annotations.Test;
9+
10+
import java.math.BigDecimal;
11+
12+
import static org.testng.Assert.assertNotNull;
13+
import static org.testng.Assert.assertTrue;
14+
15+
/**
16+
* test documenting how example values for booleans behave in their JSON-representation.
17+
*/
18+
public class Issue5168Test {
19+
20+
@Test
21+
public void testExampleValuesAreSerializedAsJsonDifferentlyBetweenStringAndBoolean() throws Exception {
22+
ResolvedSchema schema = ModelConverters.getInstance(true).readAllAsResolvedSchema(
23+
ModelWithDifferentCombinationOfBooleanFieldsWithExamples.class
24+
);
25+
26+
assertNotNull(schema, "Schema should resolve");
27+
String json = Json31.pretty(schema);
28+
assertNotNull(json);
29+
ObjectMapper mapper = new ObjectMapper();
30+
JsonNode root = mapper.readTree(json);
31+
32+
JsonNode stringFieldType = root.at("/schema/properties/stringFieldType");
33+
assertExampleIsString(stringFieldType);
34+
35+
JsonNode stringFieldTypeWithExplicitBooleanSchemaType = root.at("/schema/properties/stringFieldTypeWithExplicitBooleanSchemaType");
36+
assertExampleIsBoolean(stringFieldTypeWithExplicitBooleanSchemaType);
37+
38+
JsonNode booleanFieldTypeWithExplicitStringSchemaType = root.at("/schema/properties/booleanFieldTypeWithExplicitStringSchemaType");
39+
assertExampleIsString(booleanFieldTypeWithExplicitStringSchemaType);
40+
41+
JsonNode booleanFieldType = root.at("/schema/properties/booleanFieldType");
42+
assertExampleIsBoolean(booleanFieldType);
43+
}
44+
45+
private void assertExampleIsBoolean(JsonNode node) {
46+
assertTrue(node.get("example").isBoolean(), "should be a boolean");
47+
}
48+
49+
private void assertExampleIsString(JsonNode node) {
50+
assertTrue(node.get("example").isTextual(), "should be a string");
51+
}
52+
53+
public static class ModelWithDifferentCombinationOfBooleanFieldsWithExamples {
54+
55+
@io.swagger.v3.oas.annotations.media.Schema(example = "true")
56+
String stringFieldType;
57+
58+
@io.swagger.v3.oas.annotations.media.Schema(type = "boolean", example = "true")
59+
String stringFieldTypeWithExplicitBooleanSchemaType;
60+
61+
@io.swagger.v3.oas.annotations.media.Schema(type = "string", example = "true")
62+
boolean booleanFieldTypeWithExplicitStringSchemaType;
63+
64+
@io.swagger.v3.oas.annotations.media.Schema(example = "true")
65+
boolean booleanFieldType;
66+
67+
public String getStringFieldType() {
68+
return stringFieldType;
69+
}
70+
71+
public String getStringFieldTypeWithExplicitBooleanSchemaType() {
72+
return stringFieldTypeWithExplicitBooleanSchemaType;
73+
}
74+
75+
public boolean isBooleanFieldTypeWithExplicitStringSchemaType() {
76+
return booleanFieldTypeWithExplicitStringSchemaType;
77+
}
78+
79+
public boolean getBooleanFieldType() {
80+
return booleanFieldType;
81+
}
82+
}
83+
}

modules/swagger-core/src/test/java/io/swagger/v3/core/util/AnnotationsUtilsTest.java

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.swagger.v3.core.util;
22

33
import com.fasterxml.jackson.databind.JsonNode;
4+
import com.fasterxml.jackson.databind.node.BooleanNode;
45
import com.fasterxml.jackson.databind.node.IntNode;
56
import com.google.common.collect.ImmutableMap;
67
import io.swagger.v3.oas.annotations.ExternalDocumentation;
@@ -138,6 +139,15 @@ static class ExampleHolder {
138139

139140
@io.swagger.v3.oas.annotations.media.Schema(examples = {"42"}, type = "string")
140141
String stringExamplesWith42;
142+
143+
@io.swagger.v3.oas.annotations.media.Schema(example = "true")
144+
boolean aBoolean;
145+
146+
@io.swagger.v3.oas.annotations.media.Schema(example = "true", type = "boolean")
147+
String stringWithBooleanType;
148+
149+
@io.swagger.v3.oas.annotations.media.Schema(example = "true", type = "string")
150+
String stringWithBooleanExample;
141151
}
142152

143153
@Test
@@ -206,6 +216,72 @@ public void testExampleWithIntegerTypeShouldHaveExampleAsNumber() throws Excepti
206216
assertEquals(schema.get().getExample(), IntNode.valueOf(5));
207217
}
208218

219+
@Test
220+
public void testExampleBooleanShouldBeNode() throws Exception {
221+
io.swagger.v3.oas.annotations.media.Schema schemaAnnotation =
222+
ExampleHolder.class
223+
.getDeclaredField("aBoolean")
224+
.getAnnotation(io.swagger.v3.oas.annotations.media.Schema.class);
225+
226+
Optional<Schema> schema =
227+
AnnotationsUtils.getSchemaFromAnnotation(
228+
schemaAnnotation,
229+
null,
230+
null,
231+
false,
232+
null,
233+
Schema.SchemaResolution.DEFAULT,
234+
null
235+
);
236+
237+
assertTrue(schema.isPresent());
238+
assertEquals(schema.get().getExample(), BooleanNode.getTrue());
239+
}
240+
241+
@Test
242+
public void testExampleStringWithBooleanTypeShouldBeNode() throws Exception {
243+
io.swagger.v3.oas.annotations.media.Schema schemaAnnotation =
244+
ExampleHolder.class
245+
.getDeclaredField("stringWithBooleanType")
246+
.getAnnotation(io.swagger.v3.oas.annotations.media.Schema.class);
247+
248+
Optional<Schema> schema =
249+
AnnotationsUtils.getSchemaFromAnnotation(
250+
schemaAnnotation,
251+
null,
252+
null,
253+
false,
254+
null,
255+
Schema.SchemaResolution.DEFAULT,
256+
null
257+
);
258+
259+
assertTrue(schema.isPresent());
260+
assertEquals(schema.get().getExample(), BooleanNode.getTrue());
261+
}
262+
263+
@Test
264+
public void testExampleStringWithBooleanShouldBeString() throws Exception {
265+
io.swagger.v3.oas.annotations.media.Schema schemaAnnotation =
266+
ExampleHolder.class
267+
.getDeclaredField("stringWithBooleanExample")
268+
.getAnnotation(io.swagger.v3.oas.annotations.media.Schema.class);
269+
270+
Optional<Schema> schema =
271+
AnnotationsUtils.getSchemaFromAnnotation(
272+
schemaAnnotation,
273+
null,
274+
null,
275+
false,
276+
null,
277+
Schema.SchemaResolution.DEFAULT,
278+
null
279+
);
280+
281+
assertTrue(schema.isPresent());
282+
assertEquals(schema.get().getExample(), "true");
283+
}
284+
209285
static class DefaultHolder {
210286

211287
@io.swagger.v3.oas.annotations.media.Schema(type = "string")

0 commit comments

Comments
 (0)