1
This commit is contained in:
@@ -3862,12 +3862,6 @@ fn is_match3d_generated_asset_image_ready(asset: &Match3DGeneratedItemAsset) ->
|
||||
})
|
||||
.count();
|
||||
view_count >= MATCH3D_ITEM_VIEW_COUNT
|
||||
|| asset
|
||||
.image_object_key
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty())
|
||||
.is_some()
|
||||
}
|
||||
|
||||
fn has_match3d_required_item_images(
|
||||
@@ -4952,7 +4946,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match3d_required_item_images_require_object_keys() {
|
||||
fn match3d_required_item_images_require_five_views() {
|
||||
let assets = vec![
|
||||
Match3DGeneratedItemAsset {
|
||||
item_id: "match3d-item-1".to_string(),
|
||||
@@ -5024,6 +5018,47 @@ mod tests {
|
||||
];
|
||||
|
||||
assert!(!has_match3d_required_item_images(&assets, 3));
|
||||
|
||||
let five_view_assets = (1..=3)
|
||||
.map(|index| Match3DGeneratedItemAsset {
|
||||
item_id: format!("match3d-item-{index}"),
|
||||
item_name: format!("物品{index}"),
|
||||
image_src: Some(format!(
|
||||
"/generated-match3d-assets/s/p/items/i{index}/views/view-01.png"
|
||||
)),
|
||||
image_object_key: Some(format!(
|
||||
"generated-match3d-assets/s/p/items/i{index}/views/view-01.png"
|
||||
)),
|
||||
image_views: (1..=MATCH3D_ITEM_VIEW_COUNT)
|
||||
.map(|view_index| Match3DGeneratedItemImageView {
|
||||
view_id: format!("view-{view_index:02}"),
|
||||
view_index: view_index as u32,
|
||||
image_src: Some(format!(
|
||||
"/generated-match3d-assets/s/p/items/i{index}/views/view-{view_index:02}.png"
|
||||
)),
|
||||
image_object_key: Some(format!(
|
||||
"generated-match3d-assets/s/p/items/i{index}/views/view-{view_index:02}.png"
|
||||
)),
|
||||
})
|
||||
.collect(),
|
||||
model_src: None,
|
||||
model_object_key: None,
|
||||
model_file_name: None,
|
||||
task_uuid: None,
|
||||
subscription_key: None,
|
||||
sound_prompt: None,
|
||||
background_music_title: None,
|
||||
background_music_style: None,
|
||||
background_music_prompt: None,
|
||||
background_music: None,
|
||||
click_sound: None,
|
||||
background_asset: None,
|
||||
status: "image_ready".to_string(),
|
||||
error: None,
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
assert!(has_match3d_required_item_images(&five_view_assets, 3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -1338,7 +1338,7 @@ fn count_ready_generated_item_types(value: Option<&str>) -> Result<usize, String
|
||||
let status_ready = asset
|
||||
.get("status")
|
||||
.and_then(Value::as_str)
|
||||
.map(|status| matches!(status, "image_ready" | "model_ready"))
|
||||
.map(|status| status == "image_ready")
|
||||
.unwrap_or(false);
|
||||
let view_count = asset
|
||||
.get("imageViews")
|
||||
@@ -1363,19 +1363,7 @@ fn count_ready_generated_item_types(value: Option<&str>) -> Result<usize, String
|
||||
.count()
|
||||
})
|
||||
.unwrap_or(0);
|
||||
let has_primary_image = asset
|
||||
.get("imageSrc")
|
||||
.or_else(|| asset.get("image_src"))
|
||||
.and_then(Value::as_str)
|
||||
.map(|value| !value.trim().is_empty())
|
||||
.unwrap_or(false)
|
||||
|| asset
|
||||
.get("imageObjectKey")
|
||||
.or_else(|| asset.get("image_object_key"))
|
||||
.and_then(Value::as_str)
|
||||
.map(|value| !value.trim().is_empty())
|
||||
.unwrap_or(false);
|
||||
status_ready && (view_count >= 5 || has_primary_image)
|
||||
status_ready && view_count >= 5
|
||||
})
|
||||
.count())
|
||||
}
|
||||
@@ -1893,6 +1881,68 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match3d_publish_ready_requires_five_image_views_per_item() {
|
||||
let base_work = Match3DWorkProfileRow {
|
||||
profile_id: "profile-1".to_string(),
|
||||
owner_user_id: "user-1".to_string(),
|
||||
source_session_id: "session-1".to_string(),
|
||||
author_display_name: "作者".to_string(),
|
||||
game_name: "水果抓大鹅".to_string(),
|
||||
theme_text: "水果".to_string(),
|
||||
summary_text: "水果主题".to_string(),
|
||||
tags_json: "[\"水果\"]".to_string(),
|
||||
cover_image_src: "/cover.png".to_string(),
|
||||
cover_asset_id: String::new(),
|
||||
clear_count: 8,
|
||||
difficulty: 2,
|
||||
config_json: to_json_string(&Match3DCreatorConfigSnapshot {
|
||||
theme_text: "水果".to_string(),
|
||||
reference_image_src: None,
|
||||
clear_count: 8,
|
||||
difficulty: 2,
|
||||
asset_style_id: None,
|
||||
asset_style_label: None,
|
||||
asset_style_prompt: None,
|
||||
generate_click_sound: false,
|
||||
}),
|
||||
publication_status: MATCH3D_PUBLICATION_DRAFT.to_string(),
|
||||
play_count: 0,
|
||||
updated_at: Timestamp::from_micros_since_unix_epoch(1),
|
||||
published_at: None,
|
||||
generated_item_assets_json: Some(
|
||||
r#"[{"itemId":"match3d-item-1","itemName":"草莓","imageSrc":"/generated-match3d-assets/session/profile/items/item/image.png","status":"image_ready"},{"itemId":"match3d-item-2","itemName":"苹果","imageViews":[{"imageSrc":"/v1.png"},{"imageSrc":"/v2.png"},{"imageSrc":"/v3.png"},{"imageSrc":"/v4.png"},{"imageSrc":"/v5.png"}],"status":"model_ready"},{"itemId":"match3d-item-3","itemName":"香蕉","imageViews":[{"imageSrc":"/v1.png"},{"imageSrc":"/v2.png"},{"imageSrc":"/v3.png"},{"imageSrc":"/v4.png"}],"status":"image_ready"}]"#
|
||||
.to_string(),
|
||||
),
|
||||
};
|
||||
|
||||
let error = validate_publishable_work(&base_work).unwrap_err();
|
||||
assert!(error.contains("当前已有 0 种"));
|
||||
|
||||
let ready_assets = (1..=3)
|
||||
.map(|index| {
|
||||
let views = (1..=5)
|
||||
.map(|view_index| {
|
||||
format!(
|
||||
r#"{{"imageSrc":"/generated-match3d-assets/session/profile/items/i{index}/views/view-{view_index:02}.png"}}"#
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
format!(
|
||||
r#"{{"itemId":"match3d-item-{index}","itemName":"物品{index}","imageViews":[{views}],"status":"image_ready"}}"#
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
let ready_work = Match3DWorkProfileRow {
|
||||
generated_item_assets_json: Some(format!("[{ready_assets}]")),
|
||||
..base_work
|
||||
};
|
||||
|
||||
assert!(validate_publishable_work(&ready_work).is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn match3d_compile_without_metadata_payload_preserves_existing_metadata() {
|
||||
let existing = Match3DWorkProfileRow {
|
||||
|
||||
Reference in New Issue
Block a user