video-processing-support/tests/nfo_generator_tests.rs
Benjamin Slingo a38143c28b Initial commit: Shared video processing crate
- 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
2025-09-06 18:26:58 -04:00

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>"));
}