修正外部媒体序列契约

角色动作素材与项目资源创建请求强制提交完整序列字段
非角色动作类型禁止携带图片序列字段
增加两类请求的正反向 OpenAPI 契约测试
This commit is contained in:
2026-08-05 19:41:06 +08:00
parent 731bc02b5c
commit eac2c19a72
2 changed files with 106 additions and 10 deletions
@@ -2064,11 +2064,31 @@
]
},
"then": {
"required": [
"imageSequenceFrames",
"imageSequenceDurationMs"
],
"properties": {
"generationInputs": {
"$ref": "#/components/schemas/ExternalCharacterAnimationGenerationInputs"
}
}
},
"else": {
"not": {
"anyOf": [
{
"required": [
"imageSequenceFrames"
]
},
{
"required": [
"imageSequenceDurationMs"
]
}
]
}
}
}
],
@@ -2158,6 +2178,7 @@
},
"imageSequenceFrames": {
"type": "array",
"minItems": 2,
"items": {
"$ref": "#/components/schemas/EditorImageSequenceFrame"
}
@@ -2189,11 +2210,31 @@
]
},
"then": {
"required": [
"imageSequenceFrames",
"imageSequenceDurationMs"
],
"properties": {
"generationInputs": {
"$ref": "#/components/schemas/ExternalCharacterAnimationGenerationInputs"
}
}
},
"else": {
"not": {
"anyOf": [
{
"required": [
"imageSequenceFrames"
]
},
{
"required": [
"imageSequenceDurationMs"
]
}
]
}
}
}
],
@@ -2275,6 +2316,7 @@
},
"imageSequenceFrames": {
"type": "array",
"minItems": 2,
"items": {
"$ref": "#/components/schemas/EditorImageSequenceFrame"
}
@@ -1021,6 +1021,11 @@ fn serialize_external_editor_generation_inputs(
mod tests {
use super::*;
const EXTERNAL_MEDIA_CREATE_REQUEST_SCHEMAS: [&str; 2] = [
"ExternalEditorAssetCreateRequest",
"ExternalEditorProjectResourceCreateRequest",
];
fn external_generation_job_fixture(status: &str) -> ExternalGenerationJobRecord {
ExternalGenerationJobRecord {
job_id: "task-external-test".to_string(),
@@ -1246,6 +1251,62 @@ mod tests {
assert!(!unavailable.body_text().contains("ConnectDropped"));
}
#[test]
fn external_openapi_character_animation_create_requires_complete_sequence_metadata() {
let parsed: Value = serde_json::from_str(OPENAPI_JSON).expect("openapi json should parse");
for request_schema_name in EXTERNAL_MEDIA_CREATE_REQUEST_SCHEMAS {
let request_schema = &parsed["components"]["schemas"][request_schema_name];
let conditional = &request_schema["allOf"][0];
assert_eq!(
conditional["then"]["required"],
json!(["imageSequenceFrames", "imageSequenceDurationMs"]),
"{request_schema_name}"
);
assert_eq!(
request_schema["properties"]["imageSequenceFrames"]["minItems"],
json!(2),
"{request_schema_name}"
);
assert_eq!(
request_schema["properties"]["imageSequenceDurationMs"]["minimum"],
json!(1),
"{request_schema_name}"
);
assert_eq!(
conditional["then"]["properties"]["generationInputs"]["$ref"],
"#/components/schemas/ExternalCharacterAnimationGenerationInputs",
"{request_schema_name}"
);
}
}
#[test]
fn external_openapi_non_animation_create_forbids_sequence_metadata() {
let parsed: Value = serde_json::from_str(OPENAPI_JSON).expect("openapi json should parse");
for request_schema_name in EXTERNAL_MEDIA_CREATE_REQUEST_SCHEMAS {
let request_schema = &parsed["components"]["schemas"][request_schema_name];
let conditional = &request_schema["allOf"][0];
assert_eq!(
conditional["if"]["required"],
json!(["assetKind"]),
"{request_schema_name}"
);
let forbidden_fields = conditional["else"]["not"]["anyOf"]
.as_array()
.expect("非角色动作分支必须逐项禁止序列字段")
.iter()
.filter_map(|schema| schema["required"][0].as_str())
.collect::<Vec<_>>();
assert_eq!(
forbidden_fields,
["imageSequenceFrames", "imageSequenceDurationMs"],
"{request_schema_name}"
);
}
}
#[test]
fn exported_openapi_json_contains_external_editor_routes_and_security() {
let parsed: Value = serde_json::from_str(OPENAPI_JSON).expect("openapi json should parse");
@@ -1270,19 +1331,12 @@ mod tests {
.collect::<Vec<_>>(),
legacy_runtime_fields
);
for request_schema in [
"ExternalEditorAssetCreateRequest",
"ExternalEditorProjectResourceCreateRequest",
] {
let conditional = &parsed["components"]["schemas"][request_schema]["allOf"][0];
for request_schema in EXTERNAL_MEDIA_CREATE_REQUEST_SCHEMAS {
assert_eq!(
conditional["if"]["properties"]["assetKind"]["const"],
parsed["components"]["schemas"][request_schema]["allOf"][0]["if"]["properties"]["assetKind"]
["const"],
"character-animation"
);
assert_eq!(
conditional["then"]["properties"]["generationInputs"]["$ref"],
"#/components/schemas/ExternalCharacterAnimationGenerationInputs"
);
}
assert!(
parsed["paths"]