fix(接口测试): swagger导入,解析嵌套的json请求体不准确

--bug=1048546 --user=陈建星 【接口测试】接口定义-导入swagger 接口文档接口的object下array内容信息没导入 https://www.tapd.cn/55049933/s/1625025
This commit is contained in:
AgAngle 2024-12-04 18:35:31 +08:00 committed by Craftsman
parent e2ccf0e630
commit 65f2b93057
1 changed files with 56 additions and 128 deletions

View File

@ -323,7 +323,7 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
} }
private void setResponseBodyData(String k, io.swagger.v3.oas.models.media.MediaType value, ResponseBody body) { private void setResponseBodyData(String k, io.swagger.v3.oas.models.media.MediaType value, ResponseBody body) {
JsonSchemaItem jsonSchemaItem = parseSchema(value.getSchema()); JsonSchemaItem jsonSchemaItem = parseSchema(value.getSchema(), new HashSet<>());
switch (k) { switch (k) {
case MediaType.APPLICATION_JSON_VALUE, MediaType.ALL_VALUE -> { case MediaType.APPLICATION_JSON_VALUE, MediaType.ALL_VALUE -> {
body.setBodyType(Body.BodyType.JSON.name()); body.setBodyType(Body.BodyType.JSON.name());
@ -373,7 +373,7 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
} }
private void setRequestBodyData(String k, io.swagger.v3.oas.models.media.MediaType value, Body body) { private void setRequestBodyData(String k, io.swagger.v3.oas.models.media.MediaType value, Body body) {
JsonSchemaItem jsonSchemaItem = parseSchema(value.getSchema()); JsonSchemaItem jsonSchemaItem = parseSchema(value.getSchema(), new HashSet<>());
switch (k) { switch (k) {
case MediaType.APPLICATION_JSON_VALUE, MediaType.ALL_VALUE -> { case MediaType.APPLICATION_JSON_VALUE, MediaType.ALL_VALUE -> {
body.setBodyType(Body.BodyType.JSON.name()); body.setBodyType(Body.BodyType.JSON.name());
@ -582,45 +582,42 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
return null; return null;
} }
private JsonSchemaItem parseSchema(Schema<?> schema) { private JsonSchemaItem parseSchema(Schema<?> schema, Set refModelSet) {
if (schema != null) { if (schema != null) {
String refName = schema.get$ref(); return switch (schema) {
Schema<?> modelByRef; case ArraySchema arraySchema -> parseArraySchema(arraySchema, refModelSet);
if (StringUtils.isNotBlank(refName)) { case ObjectSchema objectSchema -> parseObject(objectSchema, refModelSet);
modelByRef = getModelByRef(refName); case MapSchema mapSchema -> parseMapObject(mapSchema, refModelSet);
} else { default -> {
modelByRef = schema; if (StringUtils.isNotBlank(schema.get$ref())) {
} yield parseObject(schema, refModelSet);
if (modelByRef != null) {
return switch (modelByRef) {
case ArraySchema arraySchema -> parseArraySchema(arraySchema, false);
case ObjectSchema objectSchema -> parseObject(objectSchema, false);
default -> {
JsonSchemaItem jsonSchemaItem = new JsonSchemaItem();
Map<String, JsonSchemaItem> jsonSchemaProperties = new LinkedHashMap<>();
if (MapUtils.isNotEmpty(modelByRef.getProperties())) {
modelByRef.getProperties().forEach((key, value) -> {
JsonSchemaItem item = parseProperty(value, false);
jsonSchemaProperties.put(key, item);
});
}
if (StringUtils.isNotBlank(modelByRef.getType())) {
jsonSchemaItem.setType(modelByRef.getType());
}
if (StringUtils.isNotBlank(refName)) {
jsonSchemaItem.setType(PropertyConstant.OBJECT);
}
jsonSchemaItem.setProperties(jsonSchemaProperties);
yield jsonSchemaItem;
} }
}; yield parseSchemaBySimpleType(schema);
} }
};
} }
return null; return null;
} }
private JsonSchemaItem parseMapObject(MapSchema mapSchema) { private JsonSchemaItem parseSchemaBySimpleType(Schema<?> schema) {
String type = schema.getType();
return switch (type) {
case PropertyConstant.STRING -> parseString(schema);
case PropertyConstant.INTEGER -> parseInteger(schema);
case PropertyConstant.NUMBER -> parseNumber(schema);
case PropertyConstant.BOOLEAN -> parseBoolean(schema);
default -> {
JsonSchemaItem jsonSchemaItem = new JsonSchemaItem();
jsonSchemaItem.setId(IDGenerator.nextStr());
if (StringUtils.isNotBlank(schema.getType())) {
jsonSchemaItem.setType(schema.getType());
}
yield jsonSchemaItem;
}
};
}
private JsonSchemaItem parseMapObject(MapSchema mapSchema, Set refModelSet) {
JsonSchemaItem jsonSchemaItem = new JsonSchemaItem(); JsonSchemaItem jsonSchemaItem = new JsonSchemaItem();
jsonSchemaItem.setType(PropertyConstant.OBJECT); jsonSchemaItem.setType(PropertyConstant.OBJECT);
jsonSchemaItem.setRequired(mapSchema.getRequired()); jsonSchemaItem.setRequired(mapSchema.getRequired());
@ -636,8 +633,9 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
case StringSchema stringSchema -> item = parseString(stringSchema); case StringSchema stringSchema -> item = parseString(stringSchema);
case NumberSchema numberSchema -> item = parseNumber(numberSchema); case NumberSchema numberSchema -> item = parseNumber(numberSchema);
case BooleanSchema booleanSchema -> item = parseBoolean(booleanSchema); case BooleanSchema booleanSchema -> item = parseBoolean(booleanSchema);
case ArraySchema arraySchema -> item = parseArraySchema(arraySchema, false); case ArraySchema arraySchema -> item = parseArraySchema(arraySchema, refModelSet);
case ObjectSchema objectSchemaItem -> item = parseObject(objectSchemaItem, false); case ObjectSchema objectSchemaItem -> item = parseObject(objectSchemaItem, refModelSet);
case Schema schema -> item = parseSchema(schema, refModelSet);
default -> { default -> {
} }
} }
@ -646,7 +644,7 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
return jsonSchemaItem; return jsonSchemaItem;
} }
private JsonSchemaItem parseObject(ObjectSchema objectSchema, boolean onlyOnce) { private JsonSchemaItem parseObject(Schema objectSchema, Set refModelSet) {
JsonSchemaItem jsonSchemaItem = new JsonSchemaItem(); JsonSchemaItem jsonSchemaItem = new JsonSchemaItem();
jsonSchemaItem.setType(PropertyConstant.OBJECT); jsonSchemaItem.setType(PropertyConstant.OBJECT);
jsonSchemaItem.setRequired(objectSchema.getRequired()); jsonSchemaItem.setRequired(objectSchema.getRequired());
@ -656,11 +654,17 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
Map<String, Schema> properties = objectSchema.getProperties(); Map<String, Schema> properties = objectSchema.getProperties();
Schema<?> refSchema = getRefSchema(objectSchema); Schema<?> refSchema = getRefSchema(objectSchema);
if (refSchema != null) { if (refSchema != null) {
if (refModelSet.contains(objectSchema.get$ref())) {
// 如果存在循环引用则直接返回
return jsonSchemaItem;
}
properties = refSchema.getProperties(); properties = refSchema.getProperties();
// 记录引用的对象
refModelSet.add(objectSchema.get$ref());
} }
if (MapUtils.isNotEmpty(properties)) { if (MapUtils.isNotEmpty(properties)) {
properties.forEach((key, value) -> { properties.forEach((key, value) -> {
JsonSchemaItem item = parseProperty(value, onlyOnce); JsonSchemaItem item = parseProperty(value, refModelSet);
jsonSchemaProperties.put(key, item); jsonSchemaProperties.put(key, item);
}); });
} }
@ -668,7 +672,7 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
return jsonSchemaItem; return jsonSchemaItem;
} }
private JsonSchemaItem parseProperty(Schema<?> value, boolean onlyOnce) { private JsonSchemaItem parseProperty(Schema<?> value, Set refModelSet) {
if (StringUtils.equals(value.getType(), PropertyConstant.NULL)) { if (StringUtils.equals(value.getType(), PropertyConstant.NULL)) {
return parseNull(); return parseNull();
} }
@ -678,80 +682,14 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
case StringSchema stringSchema -> parseString(stringSchema); case StringSchema stringSchema -> parseString(stringSchema);
case NumberSchema numberSchema -> parseNumber(numberSchema); case NumberSchema numberSchema -> parseNumber(numberSchema);
case BooleanSchema booleanSchema -> parseBoolean(booleanSchema); case BooleanSchema booleanSchema -> parseBoolean(booleanSchema);
case ArraySchema arraySchema -> { case ArraySchema arraySchema -> parseArraySchema(arraySchema, refModelSet);
if (onlyOnce) { case ObjectSchema objectSchema -> parseObject(objectSchema, refModelSet);
JsonSchemaItem arrayItem = new JsonSchemaItem(); case MapSchema mapSchema -> parseMapObject(mapSchema, refModelSet);
arrayItem.setId(IDGenerator.nextStr()); case Schema<?> schema -> parseSchema(schema, refModelSet);
arrayItem.setType(PropertyConstant.ARRAY);
arrayItem.setItems(List.of());
yield arrayItem;
}
yield isRef(arraySchema.getItems(), 0) ? parseArraySchema(arraySchema, true) :
parseArraySchema(arraySchema, false);
}
case ObjectSchema objectSchema -> {
if (onlyOnce) {
JsonSchemaItem objectItem = new JsonSchemaItem();
objectItem.setId(IDGenerator.nextStr());
objectItem.setType(PropertyConstant.OBJECT);
objectItem.setProperties(new LinkedHashMap<>());
yield objectItem;
}
yield isRef(objectSchema, 0) ? parseObject(objectSchema, true) :
parseObject(objectSchema, false);
}
case MapSchema mapSchema -> parseMapObject(mapSchema);
case Schema<?> items -> {
if (isRef(items, 0)) {
JsonSchemaItem arrayItem = new JsonSchemaItem();
arrayItem.setId(IDGenerator.nextStr());
arrayItem.setType(PropertyConstant.OBJECT);
yield arrayItem;
}
yield parseSchema(items);
}
};
}
//判断对象是否存在一直引用
private boolean isRef(Schema<?> schema, int level) {
if (level > 20 || schema == null) {
return true;
}
if (StringUtils.isNotBlank(schema.get$ref())) {
schema = getModelByRef(schema.get$ref());
}
assert schema != null;
return switch (schema) {
case ArraySchema arraySchema -> isRef(arraySchema.getItems(), level + 1);
case ObjectSchema objectSchema -> hasRefInObjectSchema(objectSchema, level + 1);
default -> false;
}; };
} }
private JsonSchemaItem parseString(Schema stringSchema) {
private boolean hasRefInObjectSchema(ObjectSchema objectSchema, int level) {
if (level > 20) {
return true;
}
if (MapUtils.isNotEmpty(objectSchema.getProperties())) {
for (Schema<?> value : objectSchema.getProperties().values()) {
if (isRef(value, level + 1)) {
return true;
}
}
}
return false;
}
private JsonSchemaItem parseString(StringSchema stringSchema) {
JsonSchemaItem jsonSchemaItem = parseSchemaItem(stringSchema); JsonSchemaItem jsonSchemaItem = parseSchemaItem(stringSchema);
jsonSchemaItem.setType(PropertyConstant.STRING); jsonSchemaItem.setType(PropertyConstant.STRING);
jsonSchemaItem.setFormat(getDefaultStringValue(stringSchema.getFormat())); jsonSchemaItem.setFormat(getDefaultStringValue(stringSchema.getFormat()));
@ -763,7 +701,7 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
return jsonSchemaItem; return jsonSchemaItem;
} }
private JsonSchemaItem parseInteger(IntegerSchema integerSchema) { private JsonSchemaItem parseInteger(Schema integerSchema) {
JsonSchemaItem jsonSchemaItem = parseSchemaItem(integerSchema); JsonSchemaItem jsonSchemaItem = parseSchemaItem(integerSchema);
jsonSchemaItem.setType(PropertyConstant.INTEGER); jsonSchemaItem.setType(PropertyConstant.INTEGER);
jsonSchemaItem.setFormat(StringUtils.isNotBlank(integerSchema.getFormat()) ? integerSchema.getFormat() : StringUtils.EMPTY); jsonSchemaItem.setFormat(StringUtils.isNotBlank(integerSchema.getFormat()) ? integerSchema.getFormat() : StringUtils.EMPTY);
@ -776,13 +714,13 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
return jsonSchemaItem; return jsonSchemaItem;
} }
private JsonSchemaItem parseNumber(NumberSchema numberSchema) { private JsonSchemaItem parseNumber(Schema numberSchema) {
JsonSchemaItem jsonSchemaItem = parseSchemaItem(numberSchema); JsonSchemaItem jsonSchemaItem = parseSchemaItem(numberSchema);
jsonSchemaItem.setType(PropertyConstant.NUMBER); jsonSchemaItem.setType(PropertyConstant.NUMBER);
return jsonSchemaItem; return jsonSchemaItem;
} }
private JsonSchemaItem parseBoolean(BooleanSchema booleanSchema) { private JsonSchemaItem parseBoolean(Schema booleanSchema) {
JsonSchemaItem jsonSchemaItem = parseSchemaItem(booleanSchema); JsonSchemaItem jsonSchemaItem = parseSchemaItem(booleanSchema);
jsonSchemaItem.setType(PropertyConstant.BOOLEAN); jsonSchemaItem.setType(PropertyConstant.BOOLEAN);
return jsonSchemaItem; return jsonSchemaItem;
@ -805,25 +743,15 @@ public class Swagger3ParserApiDefinition extends HttpApiDefinitionImportAbstract
return jsonSchemaNull; return jsonSchemaNull;
} }
private JsonSchemaItem parseArraySchema(ArraySchema arraySchema, boolean onlyOnce) { private JsonSchemaItem parseArraySchema(Schema arraySchema, Set refModelSet) {
Schema<?> items = arraySchema.getItems();
JsonSchemaItem jsonSchemaArray = new JsonSchemaItem(); JsonSchemaItem jsonSchemaArray = new JsonSchemaItem();
jsonSchemaArray.setType(PropertyConstant.ARRAY); jsonSchemaArray.setType(PropertyConstant.ARRAY);
jsonSchemaArray.setId(IDGenerator.nextStr()); jsonSchemaArray.setId(IDGenerator.nextStr());
Schema<?> itemsSchema;
if (StringUtils.isNotBlank(items.get$ref())) {
itemsSchema = getModelByRef(items.get$ref());
} else {
itemsSchema = items;
}
if (itemsSchema == null) {
return jsonSchemaArray;
}
JsonSchemaItem itemsJsonSchema = parseProperty(itemsSchema, onlyOnce);
jsonSchemaArray.setItems(List.of(itemsJsonSchema));
jsonSchemaArray.setMaxItems(arraySchema.getMaxItems()); jsonSchemaArray.setMaxItems(arraySchema.getMaxItems());
jsonSchemaArray.setMinItems(arraySchema.getMinItems()); jsonSchemaArray.setMinItems(arraySchema.getMinItems());
JsonSchemaItem itemsJsonSchema = parseProperty(arraySchema.getItems(), refModelSet);
jsonSchemaArray.setItems(List.of(itemsJsonSchema));
return jsonSchemaArray; return jsonSchemaArray;
} }