use std::fs::File; use std::io::Write; use std::path::PathBuf; use std::time::{Duration, SystemTime}; use tempfile::TempDir; use tokio::time::sleep; use video_processing::{VideoProcessingConfig, StabilityTracker}; async fn create_test_file(path: &PathBuf, content: &str) -> std::io::Result<()> { let mut file = File::create(path)?; file.write_all(content.as_bytes())?; file.flush()?; Ok(()) } #[tokio::test] async fn test_new_file_tracking() { let temp_dir = TempDir::new().unwrap(); let test_file = temp_dir.path().join("test.mp4"); // Create initial file create_test_file(&test_file, "initial content").await.unwrap(); let mut config = VideoProcessingConfig::from_env(); config.stability_check_interval_secs = 1; config.stability_required_checks = 3; let tracker = StabilityTracker::new(config); // First event should start tracking but not be stable let result = tracker.on_file_event(&test_file).unwrap(); assert!(!result, "New file should not be immediately stable"); // File should now be tracked let tracked_files = tracker.get_tracked_files(); assert_eq!(tracked_files.len(), 1); assert_eq!(tracked_files[0], test_file); } #[tokio::test] async fn test_file_stability_detection() { let temp_dir = TempDir::new().unwrap(); let test_file = temp_dir.path().join("stable_test.mp4"); // Create initial file create_test_file(&test_file, "stable content").await.unwrap(); let mut config = VideoProcessingConfig::from_env(); config.stability_check_interval_secs = 1; config.stability_required_checks = 3; let tracker = StabilityTracker::new(config); // Start tracking let result1 = tracker.on_file_event(&test_file).unwrap(); assert!(!result1, "First check should not be stable"); // Wait for interval and check again without changes sleep(Duration::from_secs(1)).await; let result2 = tracker.on_file_event(&test_file).unwrap(); assert!(!result2, "Second check should not be stable yet"); sleep(Duration::from_secs(1)).await; let result3 = tracker.on_file_event(&test_file).unwrap(); assert!(!result3, "Third check should not be stable yet"); sleep(Duration::from_secs(1)).await; let result4 = tracker.on_file_event(&test_file).unwrap(); assert!(result4, "Fourth check should be stable after 3 consecutive unchanged checks"); } #[tokio::test] async fn test_file_instability_resets_counter() { let temp_dir = TempDir::new().unwrap(); let test_file = temp_dir.path().join("unstable_test.mp4"); // Create initial file create_test_file(&test_file, "initial").await.unwrap(); let mut config = VideoProcessingConfig::from_env(); config.stability_check_interval_secs = 1; config.stability_required_checks = 3; let tracker = StabilityTracker::new(config); // Start tracking tracker.on_file_event(&test_file).unwrap(); // Wait and check (should increment stability counter) sleep(Duration::from_secs(1)).await; let result1 = tracker.on_file_event(&test_file).unwrap(); assert!(!result1); // Change file content (should reset counter) create_test_file(&test_file, "changed content").await.unwrap(); sleep(Duration::from_secs(1)).await; let result2 = tracker.on_file_event(&test_file).unwrap(); assert!(!result2, "File change should reset stability counter"); // Now check stability again sleep(Duration::from_secs(1)).await; tracker.on_file_event(&test_file).unwrap(); sleep(Duration::from_secs(1)).await; tracker.on_file_event(&test_file).unwrap(); sleep(Duration::from_secs(1)).await; let final_result = tracker.on_file_event(&test_file).unwrap(); assert!(final_result, "Should be stable after 3 consecutive unchanged checks"); } #[tokio::test] async fn test_remove_file_tracker() { let temp_dir = TempDir::new().unwrap(); let test_file = temp_dir.path().join("remove_test.mp4"); create_test_file(&test_file, "content").await.unwrap(); let config = VideoProcessingConfig::from_env(); let tracker = StabilityTracker::new(config); // Start tracking tracker.on_file_event(&test_file).unwrap(); assert_eq!(tracker.get_tracked_files().len(), 1); // Remove tracker tracker.remove_file_tracker(&test_file); assert_eq!(tracker.get_tracked_files().len(), 0); } #[tokio::test] async fn test_multiple_files_tracking() { let temp_dir = TempDir::new().unwrap(); let file1 = temp_dir.path().join("file1.mp4"); let file2 = temp_dir.path().join("file2.mp4"); create_test_file(&file1, "content1").await.unwrap(); create_test_file(&file2, "content2").await.unwrap(); let config = VideoProcessingConfig::from_env(); let tracker = StabilityTracker::new(config); // Track both files tracker.on_file_event(&file1).unwrap(); tracker.on_file_event(&file2).unwrap(); let tracked_files = tracker.get_tracked_files(); assert_eq!(tracked_files.len(), 2); assert!(tracked_files.contains(&file1)); assert!(tracked_files.contains(&file2)); // Remove one tracker.remove_file_tracker(&file1); let tracked_files = tracker.get_tracked_files(); assert_eq!(tracked_files.len(), 1); assert!(tracked_files.contains(&file2)); } #[tokio::test] async fn test_rate_limiting() { let temp_dir = TempDir::new().unwrap(); let test_file = temp_dir.path().join("rate_limit_test.mp4"); create_test_file(&test_file, "content").await.unwrap(); let mut config = VideoProcessingConfig::from_env(); config.stability_check_interval_secs = 2; // 2 second interval config.stability_required_checks = 2; let tracker = StabilityTracker::new(config); // Start tracking tracker.on_file_event(&test_file).unwrap(); // Immediately check again (should be rate limited) let result = tracker.on_file_event(&test_file).unwrap(); assert!(!result, "Should be rate limited and not advance stability counter"); // Wait for interval to pass sleep(Duration::from_secs(2)).await; let result = tracker.on_file_event(&test_file).unwrap(); assert!(!result, "After interval, should advance counter but not be stable yet"); sleep(Duration::from_secs(2)).await; let result = tracker.on_file_event(&test_file).unwrap(); assert!(result, "Should be stable after required checks with proper intervals"); }