#[cfg(test)]
mod tests {
use futures::StreamExt;
use std::io::Write;
use tempfile::{NamedTempFile, TempDir};
use crate::app::manifest::{streaming::ManifestStreamer, types::ManifestConfig, utils};
use crate::app::models::QualityControlVersion;
async fn create_test_manifest(content: &str) -> NamedTempFile {
let mut file = NamedTempFile::new().unwrap();
file.write_all(content.as_bytes()).unwrap();
file.flush().unwrap();
file
}
#[tokio::test]
async fn test_malformed_lines_handling() {
let content = r#"50c9d1c465f3cbff652be1509c2e2a4e ./data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/test1.csv
invalid_hash ./data/uk-daily-temperature-obs/dataset-version-202407/devon/01382_twist/test2.csv
50c9d1c465f3cbff652be1509c2e2a4e data/uk-daily-temperature-obs/dataset-version-202407/devon/01383_twist/test3.csv
9734faa872681f96b144f60d29d52011 ./data/uk-daily-temperature-obs/dataset-version-202407/devon/01384_twist/test4.csv"#;
let manifest_file = create_test_manifest(content).await;
let temp_dir = TempDir::new().unwrap();
let config = ManifestConfig {
destination_root: temp_dir.path().to_path_buf(),
..Default::default()
};
let mut streamer = ManifestStreamer::with_config(config);
let (valid_files, errors) = {
let mut stream = streamer.stream(manifest_file.path()).await.unwrap();
let mut valid_files = 0;
let mut errors = 0;
while let Some(result) = stream.next().await {
match result {
Ok(_) => valid_files += 1,
Err(_) => errors += 1,
}
}
(valid_files, errors)
};
assert_eq!(valid_files, 2); assert_eq!(errors, 2);
let stats = streamer.stats();
assert_eq!(stats.valid_entries, 2);
assert_eq!(stats.invalid_lines, 2);
assert_eq!(stats.empty_lines, 1);
assert_eq!(stats.lines_processed, 5);
}
#[tokio::test]
async fn test_real_manifest_sample() {
let content = r#"50c9d1c465f3cbff652be1509c2e2a4e ./data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/midas-open_uk-daily-temperature-obs_dv-202407_devon_01381_twist_capability.csv
9734faa872681f96b144f60d29d52011 ./data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/qc-version-1/midas-open_uk-daily-temperature-obs_dv-202407_devon_01381_twist_qcv-1_1992.csv"#;
let manifest_file = create_test_manifest(content).await;
let temp_dir = TempDir::new().unwrap();
let config = ManifestConfig {
destination_root: temp_dir.path().to_path_buf(),
..Default::default()
};
let files = utils::collect_all_files(manifest_file.path(), config)
.await
.unwrap();
assert_eq!(files.len(), 2);
let capability_file = &files[0];
assert_eq!(
capability_file.hash.to_hex(),
"50c9d1c465f3cbff652be1509c2e2a4e"
);
assert_eq!(
capability_file.dataset_info.dataset_name,
"uk-daily-temperature-obs"
);
assert_eq!(capability_file.dataset_info.version, "202407");
assert_eq!(
capability_file.dataset_info.county,
Some("devon".to_string())
);
assert_eq!(
capability_file.dataset_info.station_id,
Some("01381".to_string())
);
assert_eq!(
capability_file.dataset_info.station_name,
Some("twist".to_string())
);
assert_eq!(
capability_file.dataset_info.file_type,
Some("capability".to_string())
);
let data_file = &files[1];
assert_eq!(data_file.hash.to_hex(), "9734faa872681f96b144f60d29d52011");
assert_eq!(data_file.dataset_info.year, Some("1992".to_string()));
assert_eq!(
data_file.dataset_info.quality_version,
Some(QualityControlVersion::V1)
);
assert_eq!(data_file.dataset_info.file_type, Some("data".to_string()));
}
#[tokio::test]
async fn test_comprehensive_fileinfo_generation() {
let content = r#"50c9d1c465f3cbff652be1509c2e2a4e ./data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/midas-open_uk-daily-temperature-obs_dv-202407_devon_01381_twist_capability.csv"#;
let manifest_file = create_test_manifest(content).await;
let temp_dir = TempDir::new().unwrap();
let config = ManifestConfig {
destination_root: temp_dir.path().to_path_buf(),
..Default::default()
};
let files = utils::collect_all_files(manifest_file.path(), config)
.await
.unwrap();
assert_eq!(files.len(), 1);
let file_info = &files[0];
assert_eq!(file_info.hash.to_hex(), "50c9d1c465f3cbff652be1509c2e2a4e");
assert_eq!(
file_info.relative_path,
"./data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/midas-open_uk-daily-temperature-obs_dv-202407_devon_01381_twist_capability.csv"
);
assert_eq!(
file_info.file_name,
"midas-open_uk-daily-temperature-obs_dv-202407_devon_01381_twist_capability.csv"
);
let dataset = &file_info.dataset_info;
assert_eq!(dataset.dataset_name, "uk-daily-temperature-obs");
assert_eq!(dataset.version, "202407");
assert_eq!(dataset.county, Some("devon".to_string()));
assert_eq!(dataset.station_id, Some("01381".to_string()));
assert_eq!(dataset.station_name, Some("twist".to_string()));
assert_eq!(dataset.quality_version, None); assert_eq!(dataset.year, None); assert_eq!(dataset.file_type, Some("capability".to_string()));
let expected_dest = temp_dir.path().join("data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/midas-open_uk-daily-temperature-obs_dv-202407_devon_01381_twist_capability.csv");
assert_eq!(file_info.destination_path, expected_dest);
assert_eq!(file_info.retry_count, 0);
assert!(file_info.last_attempt.is_none());
assert!(file_info.estimated_size.is_none());
let download_url = file_info.download_url("https://data.ceda.ac.uk");
assert_eq!(
download_url,
"https://data.ceda.ac.uk/badc/ukmo-midas-open/data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/midas-open_uk-daily-temperature-obs_dv-202407_devon_01381_twist_capability.csv"
);
let display_name = dataset.display_name();
assert_eq!(display_name, "uk-daily-temperature-obs-v202407-devon-twist");
}
#[tokio::test]
async fn test_manifest_version_folder_renaming() {
let content = r#"50c9d1c465f3cbff652be1509c2e2a4e ./data/uk-daily-temperature-obs/dataset-version-202407/devon/01381_twist/test.csv
9734faa872681f96b144f60d29d52011 ./data/uk-daily-rain-obs/dataset-version-202407/devon/01382_another/test2.csv"#;
let mut manifest_file = NamedTempFile::new().unwrap();
manifest_file.write_all(content.as_bytes()).unwrap();
manifest_file.flush().unwrap();
let versioned_manifest_path = manifest_file
.path()
.with_file_name("midas-open-v202407-md5s.txt");
std::fs::copy(manifest_file.path(), &versioned_manifest_path).unwrap();
let temp_dir = TempDir::new().unwrap();
let config = ManifestConfig {
destination_root: temp_dir.path().to_path_buf(),
..Default::default()
};
let mut streamer = ManifestStreamer::with_config(config);
let files = {
let mut stream = streamer.stream(&versioned_manifest_path).await.unwrap();
let mut files = Vec::new();
while let Some(result) = stream.next().await {
files.push(result.unwrap());
}
files
};
std::fs::remove_file(&versioned_manifest_path).ok();
assert_eq!(files.len(), 2);
assert!(files[0]
.destination_path
.to_str()
.unwrap()
.contains("uk-daily-temperature-obs-202407"));
assert!(!files[0]
.destination_path
.to_str()
.unwrap()
.contains("uk-daily-temperature-obs/dataset-version-202407"));
assert!(files[1]
.destination_path
.to_str()
.unwrap()
.contains("uk-daily-rain-obs-202407"));
assert!(!files[1]
.destination_path
.to_str()
.unwrap()
.contains("uk-daily-rain-obs/dataset-version-202407"));
}
}