// Integration tests for module interactions use movie_mapper::service::audit_logger::{AuditAction, AuditLogger}; use movie_mapper::service::file_mapper::FileMapper; use movie_mapper::model::file::MediaFile; use movie_mapper::service::file_metadata::MetadataExtractor; use movie_mapper::service::file_scanner::FileScanner; use movie_mapper::service::tag_manager::TagManager; use std::fs::{self, File}; use tempfile::tempdir; /// Test complete workflow: scan → extract metadata → tag → move #[tokio::test] async fn test_complete_workflow_integration() { let temp_dir = tempdir().unwrap(); // Setup: Create test files let file1 = temp_dir.path().join("video1.mp4"); let file2 = temp_dir.path().join("video2.mkv"); File::create(&file1).unwrap(); File::create(&file2).unwrap(); // Step 1: Scan directory let scanner = FileScanner::new(); let files = scanner.scan_directory(temp_dir.path(), None).await.unwrap(); assert_eq!(files.len(), 2); // Step 2: Extract metadata let extractor = MetadataExtractor::new(); let metadata1 = extractor.extract_metadata(&file1).unwrap(); let metadata2 = extractor.extract_metadata(&file2).unwrap(); assert_eq!(metadata1.name, "video1.mp4"); assert_eq!(metadata2.name, "video2.mkv"); // Step 3: Tag files let mut tag_manager = TagManager::new(); tag_manager.add_tag(&metadata1.path, "extra").unwrap(); tag_manager.add_tag(&metadata2.path, "commentary").unwrap(); // Step 4: Create target folders let extras_folder = temp_dir.path().join("extras"); let commentary_folder = temp_dir.path().join("commentary"); fs::create_dir_all(&extras_folder).unwrap(); fs::create_dir_all(&commentary_folder).unwrap(); // Step 5: Move tagged files tag_manager .move_tagged_files("extra", &extras_folder) .await .unwrap(); tag_manager .move_tagged_files("commentary", &commentary_folder) .await .unwrap(); } /// Test file scanner and metadata extractor integration #[tokio::test] async fn test_scanner_metadata_integration() { let temp_dir = tempdir().unwrap(); // Create test file let file_path = temp_dir.path().join("video.mp4"); File::create(&file_path).unwrap(); // Scan directory let scanner = FileScanner::new(); let files = scanner.scan_directory(temp_dir.path(), None).await.unwrap(); assert_eq!(files.len(), 1); // Extract metadata let extractor = MetadataExtractor::new(); let metadata = extractor.extract_metadata(&file_path).unwrap(); assert_eq!(metadata.name, "video.mp4"); } /// Test tag manager and audit logger integration #[tokio::test] async fn test_tag_audit_integration() { let temp_dir = tempdir().unwrap(); // Create test file let file_path = temp_dir.path().join("video.mp4"); File::create(&file_path).unwrap(); // Tag file let mut tag_manager = TagManager::new(); tag_manager.add_tag(&file_path, "extra").unwrap(); // Log audit event let logger = AuditLogger::new(temp_dir.path().to_str().unwrap()); logger .log_event(AuditAction::TagFile { file_path: file_path.to_string_lossy().to_string(), tag: "extra".to_string(), }) .unwrap(); // Verify audit file was created let audit_path = temp_dir.path().join(".audit"); assert!(audit_path.exists()); } /// Test file mapper integration #[tokio::test] async fn test_file_mapper_integration() { let temp_dir = tempdir().unwrap(); // Create test files let files_data = vec![ ("video1.mp4", "1080p"), ("video2.mkv", "720p"), ("video3.mp4", "480p"), ]; for (filename, _quality) in &files_data { let file_path = temp_dir.path().join(filename); File::create(&file_path).unwrap(); } // Create MediaFile objects with quality metadata let mut files = Vec::new(); for (filename, _quality) in &files_data { let file_path = temp_dir.path().join(filename); let mut file = MediaFile::from_path(file_path); file.quality = _quality.to_string(); files.push(file); } // Map files let mapper = FileMapper::new(); let result = mapper .map_files(&files, "Test Show", 1, None) .await .unwrap(); assert_eq!(result.success, 3); assert_eq!(result.errors, 0); } /// Test audit logger integration #[tokio::test] async fn test_audit_logger_integration() { let temp_dir = tempdir().unwrap(); let logger = AuditLogger::new(temp_dir.path().to_str().unwrap()); // Test multiple audit actions let actions = vec![ AuditAction::DirectorySelected { path: temp_dir.path().to_string_lossy().to_string(), }, AuditAction::RenameFile { old_path: "/path/to/original.mp4".to_string(), new_path: "/path/to/renamed.mp4".to_string(), old_name: "original.mp4".to_string(), new_name: "renamed.mp4".to_string(), }, AuditAction::MoveFile { original_path: "/path/to/original.mp4".to_string(), new_path: "/path/to/moved.mp4".to_string(), folder: "extras".to_string(), }, ]; for action in actions { logger.log_event(action).unwrap(); } // Verify audit file was created let audit_path = temp_dir.path().join(".audit"); assert!(audit_path.exists()); // Verify content let content = fs::read_to_string(&audit_path).unwrap(); assert!(content.contains("directory_selected")); assert!(content.contains("rename_file")); assert!(content.contains("move_file")); } /// Test end-to-end workflow with real files #[tokio::test] async fn test_end_to_end_workflow() { let temp_dir = tempdir().unwrap(); // Create directory structure let source_dir = temp_dir.path().join("source"); let extras_dir = source_dir.join("extras"); fs::create_dir_all(&extras_dir).unwrap(); // Create test files File::create(source_dir.join("movie1.mp4")).unwrap(); File::create(source_dir.join("movie2.mkv")).unwrap(); // Scan - should find 3 items: 2 media files + 1 folder (extras) let scanner = FileScanner::new(); let files = scanner.scan_directory(&source_dir, None).await.unwrap(); assert_eq!(files.len(), 3); // Tag let mut tag_manager = TagManager::new(); for file in &files { if !file.is_folder { tag_manager.add_tag(&file.path, "extra").unwrap(); } } // Move tagged files let count = tag_manager .move_tagged_files("extra", &extras_dir) .await .unwrap(); assert_eq!(count, 2); }