use std::path::PathBuf; use std::fs; use std::env; use tempfile::TempDir; use video_processing::{VideoProcessingConfig, VideoConverter}; #[tokio::test] async fn test_video_converter_creation() { let config = VideoProcessingConfig::from_env(); let converter = VideoConverter::new(config); // Basic smoke test that converter was created assert!(true); } #[tokio::test] async fn test_video_converter_with_custom_config() { // Set custom environment variables env::set_var("FFMPEG_BINARY", "custom_ffmpeg"); env::set_var("VIDEO_CODEC", "h264"); env::set_var("AUDIO_CODEC", "aac"); env::set_var("VIDEO_BITRATE", "8M"); let config = VideoProcessingConfig::from_env(); let converter = VideoConverter::new(config); // Test that converter was created with custom config assert!(true); // Clean up env::remove_var("FFMPEG_BINARY"); env::remove_var("VIDEO_CODEC"); env::remove_var("AUDIO_CODEC"); env::remove_var("VIDEO_BITRATE"); } #[tokio::test] async fn test_conversion_with_missing_input_file() { let config = VideoProcessingConfig::from_env(); let converter = VideoConverter::new(config); let temp_dir = TempDir::new().unwrap(); let input_file = temp_dir.path().join("nonexistent.mp4"); let output_file = temp_dir.path().join("output.mp4"); // Should fail when input file doesn't exist let result = converter.convert_video(&input_file, &output_file).await; assert!(result.is_err()); } #[tokio::test] async fn test_conversion_output_verification() { let config = VideoProcessingConfig::from_env(); let converter = VideoConverter::new(config); let temp_dir = TempDir::new().unwrap(); let input_file = temp_dir.path().join("input.mp4"); let output_file = temp_dir.path().join("output.mp4"); // Create a fake input video file fs::write(&input_file, create_minimal_mp4_content()).unwrap(); // The conversion will likely fail due to invalid video content or missing ffmpeg, // but we can test that the converter handles the failure gracefully let result = converter.convert_video(&input_file, &output_file).await; // We expect this to fail since we don't have real video content or ffmpeg might not be available // The important thing is that it doesn't panic and returns a proper error assert!(result.is_err()); } #[tokio::test] async fn test_conversion_safety_no_overwrite() { let mut config = VideoProcessingConfig::from_env(); // Use a fake ffmpeg binary to test the command construction without actually running ffmpeg config.ffmpeg_binary = "echo".to_string(); // Use echo as a safe substitute let converter = VideoConverter::new(config); let temp_dir = TempDir::new().unwrap(); let input_file = temp_dir.path().join("input.mp4"); let output_file = temp_dir.path().join("output.mp4"); // Create both input and output files fs::write(&input_file, "fake video content").unwrap(); fs::write(&output_file, "existing output").unwrap(); // The converter should use -n flag to never overwrite, so this should fail let result = converter.convert_video(&input_file, &output_file).await; // When using echo, it will succeed, but with real ffmpeg and -n flag, // it would fail if output exists. We test the command construction here. // The actual behavior depends on whether we're using echo or real ffmpeg match result { Ok(_) => { // If using echo as substitute, it might succeed println!("Command executed (likely using echo substitute)"); }, Err(e) => { // If using real ffmpeg with -n, it should fail when output exists println!("Conversion failed as expected: {}", e); } } // The important thing is no panic occurred assert!(true); } #[tokio::test] async fn test_hardware_acceleration_config() { // Test with QSV hardware acceleration env::set_var("HW_ACCEL", "qsv"); env::set_var("HW_DEVICE", "qsv=hw"); env::set_var("VIDEO_CODEC", "av1_qsv"); let config = VideoProcessingConfig::from_env(); let converter = VideoConverter::new(config); let temp_dir = TempDir::new().unwrap(); let input_file = temp_dir.path().join("input.mp4"); let output_file = temp_dir.path().join("output.mp4"); // Create a fake input file fs::write(&input_file, "fake video").unwrap(); // Test that hardware acceleration settings are used // This will likely fail due to missing hardware or ffmpeg, but shouldn't panic let result = converter.convert_video(&input_file, &output_file).await; // We expect failure but no panic assert!(result.is_err() || result.is_ok()); // Clean up env::remove_var("HW_ACCEL"); env::remove_var("HW_DEVICE"); env::remove_var("VIDEO_CODEC"); } #[tokio::test] async fn test_no_hardware_acceleration() { // Test without hardware acceleration env::set_var("HW_ACCEL", "none"); env::set_var("HW_DEVICE", ""); env::set_var("VIDEO_CODEC", "libx264"); let config = VideoProcessingConfig::from_env(); let converter = VideoConverter::new(config); let temp_dir = TempDir::new().unwrap(); let input_file = temp_dir.path().join("input.mp4"); let output_file = temp_dir.path().join("output.mp4"); // Create a fake input file fs::write(&input_file, "fake video").unwrap(); // Test conversion without hardware acceleration let result = converter.convert_video(&input_file, &output_file).await; // We expect failure but no panic assert!(result.is_err() || result.is_ok()); // Clean up env::remove_var("HW_ACCEL"); env::remove_var("HW_DEVICE"); env::remove_var("VIDEO_CODEC"); } #[tokio::test] async fn test_audio_codec_settings() { // Test different audio codec settings let test_cases = vec![ ("copy", ""), ("aac", "128k"), ("libopus", "192k"), ("mp3", "256k"), ]; for (audio_codec, audio_bitrate) in test_cases { env::set_var("AUDIO_CODEC", audio_codec); env::set_var("AUDIO_BITRATE", audio_bitrate); let config = VideoProcessingConfig::from_env(); let converter = VideoConverter::new(config); let temp_dir = TempDir::new().unwrap(); let input_file = temp_dir.path().join("input.mp4"); let output_file = temp_dir.path().join("output.mp4"); fs::write(&input_file, "fake video").unwrap(); // Test that different audio settings don't cause panics let result = converter.convert_video(&input_file, &output_file).await; assert!(result.is_err() || result.is_ok()); env::remove_var("AUDIO_CODEC"); env::remove_var("AUDIO_BITRATE"); } } // Helper function to create minimal MP4-like content for testing fn create_minimal_mp4_content() -> Vec { // This is just fake binary content that looks like it could be a video file // Real MP4 files have complex structure, but for testing we just need some binary data let mut content = Vec::new(); // Add some MP4-like header bytes (these are not valid but sufficient for testing) content.extend_from_slice(b"\x00\x00\x00\x20ftypmp41"); // Fake ftyp box content.extend_from_slice(&[0u8; 1000]); // Add some padding content }