#[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) -> 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::>() ); 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!("✅ 文件名序号匹配功能集成测试通过"); } }