
- Event-driven file stability tracking - FFmpeg video conversion with hardware acceleration - NFO file generation for Kodi compatibility - Environment-based configuration - Disk space monitoring and shutdown handling - Comprehensive logging with tracing
154 lines
6.2 KiB
Rust
154 lines
6.2 KiB
Rust
use std::path::PathBuf;
|
|
use tempfile::TempDir;
|
|
use chrono::NaiveDate;
|
|
|
|
use video_processing::{VideoProcessingConfig, NfoGenerator};
|
|
|
|
#[tokio::test]
|
|
async fn test_nfo_file_creation() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let video_file = temp_dir.path().join("test_video.mp4");
|
|
let expected_nfo = temp_dir.path().join("test_video.nfo");
|
|
|
|
// Create empty video file
|
|
std::fs::write(&video_file, "fake video content").unwrap();
|
|
|
|
let mut config = VideoProcessingConfig::from_env();
|
|
config.show_title = "Test Show".to_string();
|
|
config.create_nfo_files = true;
|
|
|
|
let generator = NfoGenerator::new(config);
|
|
|
|
let date = NaiveDate::from_ymd_opt(2024, 12, 25).unwrap();
|
|
let title = "Christmas Special Episode";
|
|
let tag = Some("Holiday");
|
|
|
|
generator.create_nfo_file(&video_file, title, &date, tag).await.unwrap();
|
|
|
|
// Check that NFO file was created
|
|
assert!(expected_nfo.exists(), "NFO file should have been created");
|
|
|
|
// Read and verify NFO content
|
|
let nfo_content = std::fs::read_to_string(&expected_nfo).unwrap();
|
|
|
|
assert!(nfo_content.contains("<title>Christmas Special Episode</title>"));
|
|
assert!(nfo_content.contains("<showtitle>Test Show</showtitle>"));
|
|
assert!(nfo_content.contains("<season>2024</season>"));
|
|
assert!(nfo_content.contains("<episode>1225</episode>"));
|
|
assert!(nfo_content.contains("<aired>2024-12-25</aired>"));
|
|
assert!(nfo_content.contains("<displayseason>2024</displayseason>"));
|
|
assert!(nfo_content.contains("<displayepisode>1225</displayepisode>"));
|
|
assert!(nfo_content.contains("<tag>Holiday</tag>"));
|
|
assert!(nfo_content.contains("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>"));
|
|
assert!(nfo_content.contains("<episodedetails>"));
|
|
assert!(nfo_content.contains("</episodedetails>"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_nfo_file_with_no_tag() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let video_file = temp_dir.path().join("no_tag_video.mp4");
|
|
let expected_nfo = temp_dir.path().join("no_tag_video.nfo");
|
|
|
|
std::fs::write(&video_file, "fake video content").unwrap();
|
|
|
|
let config = VideoProcessingConfig::from_env();
|
|
let generator = NfoGenerator::new(config);
|
|
|
|
let date = NaiveDate::from_ymd_opt(2024, 1, 1).unwrap();
|
|
let title = "New Year Episode";
|
|
|
|
generator.create_nfo_file(&video_file, title, &date, None).await.unwrap();
|
|
|
|
let nfo_content = std::fs::read_to_string(&expected_nfo).unwrap();
|
|
|
|
assert!(nfo_content.contains("<title>New Year Episode</title>"));
|
|
assert!(nfo_content.contains("<tag>Video</tag>")); // Default tag when None provided
|
|
assert!(nfo_content.contains("<season>2024</season>"));
|
|
assert!(nfo_content.contains("<episode>0101</episode>"));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_nfo_disabled() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let video_file = temp_dir.path().join("disabled_nfo.mp4");
|
|
let expected_nfo = temp_dir.path().join("disabled_nfo.nfo");
|
|
|
|
std::fs::write(&video_file, "fake video content").unwrap();
|
|
|
|
let mut config = VideoProcessingConfig::from_env();
|
|
config.create_nfo_files = false;
|
|
|
|
let generator = NfoGenerator::new(config);
|
|
|
|
let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();
|
|
let title = "Summer Episode";
|
|
|
|
generator.create_nfo_file(&video_file, title, &date, Some("Summer")).await.unwrap();
|
|
|
|
// NFO file should not have been created
|
|
assert!(!expected_nfo.exists(), "NFO file should not be created when disabled");
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_nfo_date_formatting() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let video_file = temp_dir.path().join("date_test.mp4");
|
|
let expected_nfo = temp_dir.path().join("date_test.nfo");
|
|
|
|
std::fs::write(&video_file, "fake video content").unwrap();
|
|
|
|
let config = VideoProcessingConfig::from_env();
|
|
let generator = NfoGenerator::new(config);
|
|
|
|
// Test various dates
|
|
let test_cases = vec![
|
|
(NaiveDate::from_ymd_opt(2024, 1, 1).unwrap(), "2024", "0101", "2024-01-01"),
|
|
(NaiveDate::from_ymd_opt(2024, 12, 31).unwrap(), "2024", "1231", "2024-12-31"),
|
|
(NaiveDate::from_ymd_opt(2023, 7, 4).unwrap(), "2023", "0704", "2023-07-04"),
|
|
(NaiveDate::from_ymd_opt(2024, 2, 29).unwrap(), "2024", "0229", "2024-02-29"), // Leap year
|
|
];
|
|
|
|
for (date, expected_year, expected_episode, expected_aired) in test_cases {
|
|
generator.create_nfo_file(&video_file, "Test Title", &date, None).await.unwrap();
|
|
|
|
let nfo_content = std::fs::read_to_string(&expected_nfo).unwrap();
|
|
|
|
assert!(nfo_content.contains(&format!("<season>{}</season>", expected_year)));
|
|
assert!(nfo_content.contains(&format!("<episode>{}</episode>", expected_episode)));
|
|
assert!(nfo_content.contains(&format!("<aired>{}</aired>", expected_aired)));
|
|
assert!(nfo_content.contains(&format!("<displayseason>{}</displayseason>", expected_year)));
|
|
assert!(nfo_content.contains(&format!("<displayepisode>{}</displayepisode>", expected_episode)));
|
|
|
|
// Clean up for next iteration
|
|
std::fs::remove_file(&expected_nfo).unwrap();
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_nfo_special_characters_handling() {
|
|
let temp_dir = TempDir::new().unwrap();
|
|
let video_file = temp_dir.path().join("special_chars.mp4");
|
|
let expected_nfo = temp_dir.path().join("special_chars.nfo");
|
|
|
|
std::fs::write(&video_file, "fake video content").unwrap();
|
|
|
|
let mut config = VideoProcessingConfig::from_env();
|
|
config.show_title = "Show & Tell <Test>".to_string();
|
|
|
|
let generator = NfoGenerator::new(config);
|
|
|
|
let date = NaiveDate::from_ymd_opt(2024, 6, 15).unwrap();
|
|
let title = "Episode with \"Quotes\" & Ampersands";
|
|
let tag = Some("Special & <Characters>");
|
|
|
|
generator.create_nfo_file(&video_file, title, &date, tag).await.unwrap();
|
|
|
|
let nfo_content = std::fs::read_to_string(&expected_nfo).unwrap();
|
|
|
|
// Verify that special characters are preserved in the XML
|
|
// (Note: In a real implementation, you might want to XML-encode these)
|
|
assert!(nfo_content.contains(title));
|
|
assert!(nfo_content.contains("Show & Tell <Test>"));
|
|
assert!(nfo_content.contains("Special & <Characters>"));
|
|
} |