mixvideo-v2/apps/desktop/src-tauri/src/tests/material_matching_service_t...

338 lines
12 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#[cfg(test)]
mod tests {
// use crate::business::services::material_matching_service::MaterialMatchingService;
use crate::data::models::{
material::{Material, MaterialSegment, MaterialType, ProcessingStatus, MaterialMetadata},
template::{SegmentMatchingRule, TrackSegment},
};
use crate::infrastructure::filename_utils::FilenameUtils;
use std::collections::HashSet;
use chrono::Utc;
/// 创建测试用的素材片段
fn create_test_material_segment(
id: &str,
material_id: &str,
file_path: &str,
duration: f64,
) -> MaterialSegment {
MaterialSegment {
id: id.to_string(),
material_id: material_id.to_string(),
segment_index: 0,
start_time: 0.0,
end_time: duration,
duration,
file_path: file_path.to_string(),
file_size: 1024 * 1024, // 1MB
thumbnail_path: None,
usage_count: 0,
is_used: false,
last_used_at: None,
created_at: Utc::now(),
}
}
/// 创建测试用的素材
fn create_test_material(id: &str, name: &str, model_id: Option<String>) -> Material {
Material {
id: id.to_string(),
project_id: "test_project".to_string(),
model_id,
name: name.to_string(),
original_path: format!("/test/path/{}.mp4", name),
file_size: 1024 * 1024,
md5_hash: "test_hash".to_string(),
material_type: MaterialType::Video,
processing_status: ProcessingStatus::Completed,
metadata: MaterialMetadata::None,
scene_detection: None,
segments: Vec::new(),
thumbnail_path: None,
created_at: Utc::now(),
updated_at: Utc::now(),
processed_at: Some(Utc::now()),
error_message: None,
}
}
/// 创建测试用的轨道片段
fn create_test_track_segment(
id: &str,
name: &str,
duration_seconds: f64,
matching_rule: SegmentMatchingRule,
) -> TrackSegment {
let duration_microseconds = (duration_seconds * 1_000_000.0) as u64;
let mut segment = TrackSegment::new(
id.to_string(),
"test_track".to_string(),
name.to_string(),
0,
duration_microseconds,
0,
);
segment.set_matching_rule(matching_rule);
segment
}
#[test]
fn test_filename_sequence_matching_basic() {
// 测试基本的文件名序号匹配
let segments = vec![
(
create_test_material_segment("seg1", "mat1", "video_001.mp4", 10.0),
"category1".to_string(),
),
(
create_test_material_segment("seg2", "mat2", "video_002.mp4", 15.0),
"category2".to_string(),
),
(
create_test_material_segment("seg3", "mat3", "image_001.jpg", 5.0),
"category3".to_string(),
),
];
let materials = vec![
create_test_material("mat1", "video_001", Some("model1".to_string())),
create_test_material("mat2", "video_002", Some("model2".to_string())),
create_test_material("mat3", "image_001", None),
];
let _track_segment = create_test_track_segment(
"track_seg1",
"Test Segment",
8.0,
SegmentMatchingRule::FilenameSequence {
target_sequence: "001".to_string(),
},
);
// 模拟匹配逻辑
let mut matching_segments = Vec::new();
for (segment, category) in &segments {
if FilenameUtils::has_sequence_number(&segment.file_path, "001") {
if FilenameUtils::is_video_file(&segment.file_path) {
if let Some(material) = materials.iter().find(|m| m.id == segment.material_id) {
matching_segments.push((segment, category, material));
}
}
}
}
// 应该找到一个匹配的视频文件
assert_eq!(matching_segments.len(), 1);
assert_eq!(matching_segments[0].0.file_path, "video_001.mp4");
}
#[test]
fn test_filename_sequence_matching_no_videos() {
// 测试没有视频文件的情况
let segments = vec![
(
create_test_material_segment("seg1", "mat1", "image_001.jpg", 10.0),
"category1".to_string(),
),
(
create_test_material_segment("seg2", "mat2", "audio_001.mp3", 15.0),
"category2".to_string(),
),
];
let materials = vec![
create_test_material("mat1", "image_001", None),
create_test_material("mat2", "audio_001", None),
];
// 模拟匹配逻辑
let mut matching_segments = Vec::new();
for (segment, category) in &segments {
if FilenameUtils::has_sequence_number(&segment.file_path, "001") {
if FilenameUtils::is_video_file(&segment.file_path) {
if let Some(material) = materials.iter().find(|m| m.id == segment.material_id) {
matching_segments.push((segment, category, material));
}
}
}
}
// 应该没有找到匹配的视频文件
assert_eq!(matching_segments.len(), 0);
}
#[test]
fn test_filename_sequence_matching_wrong_sequence() {
// 测试序号不匹配的情况
let segments = vec![
(
create_test_material_segment("seg1", "mat1", "video_002.mp4", 10.0),
"category1".to_string(),
),
(
create_test_material_segment("seg2", "mat2", "video_003.mp4", 15.0),
"category2".to_string(),
),
];
let materials = vec![
create_test_material("mat1", "video_002", Some("model1".to_string())),
create_test_material("mat2", "video_003", Some("model2".to_string())),
];
// 模拟匹配逻辑 - 寻找序号001
let mut matching_segments = Vec::new();
for (segment, category) in &segments {
if FilenameUtils::has_sequence_number(&segment.file_path, "001") {
if FilenameUtils::is_video_file(&segment.file_path) {
if let Some(material) = materials.iter().find(|m| m.id == segment.material_id) {
matching_segments.push((segment, category, material));
}
}
}
}
// 应该没有找到匹配的文件因为没有序号001的文件
assert_eq!(matching_segments.len(), 0);
}
#[test]
fn test_sequence_001_usage_validation() {
// 测试序号001使用限制逻辑
let segments = vec![
(
create_test_material_segment("seg1", "mat1", "video_001.mp4", 10.0),
"category1".to_string(),
),
(
create_test_material_segment("seg2", "mat2", "another_001.mp4", 15.0),
"category2".to_string(),
),
];
let mut used_segment_ids = HashSet::new();
// 模拟第一次使用序号001的视频
used_segment_ids.insert("seg1".to_string());
// 检查是否已经使用了序号001的视频
let mut has_used_sequence_001 = false;
for used_id in &used_segment_ids {
if let Some((used_segment, _)) = segments.iter().find(|(seg, _)| seg.id == *used_id) {
if FilenameUtils::has_sequence_001(&used_segment.file_path) &&
FilenameUtils::is_video_file(&used_segment.file_path) {
has_used_sequence_001 = true;
break;
}
}
}
// 应该检测到已经使用了序号001的视频
assert!(has_used_sequence_001);
}
#[test]
fn test_multiple_sequence_001_files() {
// 测试多个序号001文件的情况
let files = vec![
"video_001.mp4".to_string(),
"scene_001.avi".to_string(),
"take_001.mkv".to_string(),
"video_002.mp4".to_string(),
];
let sequence_001_videos = FilenameUtils::filter_videos_with_sequence_001(&files);
// 应该找到3个序号001的视频文件
assert_eq!(sequence_001_videos.len(), 3);
assert!(sequence_001_videos.contains(&"video_001.mp4".to_string()));
assert!(sequence_001_videos.contains(&"scene_001.avi".to_string()));
assert!(sequence_001_videos.contains(&"take_001.mkv".to_string()));
}
#[test]
fn test_segment_matching_rule_display() {
// 测试匹配规则的显示名称
let rule = SegmentMatchingRule::FilenameSequence {
target_sequence: "001".to_string(),
};
assert_eq!(rule.display_name(), "文件名序号: 001");
assert!(rule.is_filename_sequence());
assert!(!rule.is_fixed_material());
assert!(!rule.is_ai_classification());
assert!(!rule.is_random_match());
assert_eq!(rule.get_target_sequence(), Some(&"001".to_string()));
}
#[test]
fn test_segment_matching_rule_serialization() {
// 测试匹配规则的序列化和反序列化
let rule = SegmentMatchingRule::FilenameSequence {
target_sequence: "042".to_string(),
};
let serialized = serde_json::to_string(&rule).unwrap();
let deserialized: SegmentMatchingRule = serde_json::from_str(&serialized).unwrap();
match deserialized {
SegmentMatchingRule::FilenameSequence { target_sequence } => {
assert_eq!(target_sequence, "042");
}
_ => panic!("Deserialization failed"),
}
}
#[test]
fn test_integration_filename_sequence_workflow() {
// 集成测试:完整的文件名序号匹配工作流程
// 1. 创建测试数据 - 模拟项目中的视频文件
let video_files = vec![
"scene_001.mp4",
"scene_002.mp4",
"take_001.avi",
"final_001.mkv",
"backup_002.mp4",
"test_video.mp4", // 无序号
];
// 2. 测试文件名序号提取
for file in &video_files {
let sequence = FilenameUtils::extract_sequence_number(file);
match *file {
f if f.contains("_001") => assert_eq!(sequence, Some("001".to_string())),
f if f.contains("_002") => assert_eq!(sequence, Some("002".to_string())),
"test_video.mp4" => assert_eq!(sequence, None),
_ => {} // 其他情况
}
}
// 3. 测试序号001的筛选
let sequence_001_files = FilenameUtils::filter_videos_with_sequence_001(
&video_files.iter().map(|s| s.to_string()).collect::<Vec<_>>()
);
assert_eq!(sequence_001_files.len(), 3); // scene_001.mp4, take_001.avi, final_001.mkv
assert!(sequence_001_files.contains(&"scene_001.mp4".to_string()));
assert!(sequence_001_files.contains(&"take_001.avi".to_string()));
assert!(sequence_001_files.contains(&"final_001.mkv".to_string()));
// 4. 测试模板匹配规则创建
let rule = SegmentMatchingRule::FilenameSequence {
target_sequence: "001".to_string(),
};
assert!(rule.is_filename_sequence());
assert_eq!(rule.get_target_sequence(), Some(&"001".to_string()));
assert_eq!(rule.display_name(), "文件名序号: 001");
// 5. 测试序列化兼容性(确保可以存储到数据库)
let json = serde_json::to_string(&rule).unwrap();
let restored: SegmentMatchingRule = serde_json::from_str(&json).unwrap();
assert_eq!(rule, restored);
println!("✅ 文件名序号匹配功能集成测试通过");
}
}