A Servarr build can emit an enum value this app has no name for, either as a string it does not recognise or as a bare integer for a value the build itself cannot name. Until now any such value in a response failed the whole payload, so one unexpected artist status, download status, task name, series type, minimum availability, credit type, or security setting emptied the entire view with "Failed to parse response!". Every enum-typed field on a struct the app only ever deserializes and displays now uses from_json_or_default, so an unrecognised value degrades to that enum's default and the rest of the record is kept. Known values still map exactly as before and serialization is untouched. Fields on request bodies (Add*Body, Add*Options, Edit*Params, the root folder bodies) are deliberately left alone: those structs are only ever serialized, so the attribute would be meaningless there. No candidate struct is round-tripped: every edit and toggle in the app re-fetches the raw JSON value and patches it by key, so the fallback can never be written back to a server as a real setting. The one Option field, the security config's authentication_required, also carries serde(default), because deserialize_with on an Option turns a missing key into a hard error. An unknown value there yields None. Verified by mutation. Removing the attribute from one field per tree fails exactly that field's test and nothing else. Dropping default from the Option field fails only the missing-key test with "missing field authenticationRequired"; dropping deserialize_with from it fails only the unknown-value test. All 21 new fallback tests fail against the unguarded code with "invalid type: integer 2, expected string or map".
811 lines
23 KiB
Rust
811 lines
23 KiB
Rust
#[cfg(test)]
|
|
mod tests {
|
|
use pretty_assertions::{assert_eq, assert_str_eq};
|
|
use serde::de::DeserializeOwned;
|
|
use serde_json::{Value, json};
|
|
|
|
use crate::models::{
|
|
Serdeable,
|
|
servarr_models::{
|
|
DiskSpace, HostConfig, Indexer, IndexerSettings, IndexerTestResult, Language, Log,
|
|
LogResponse, QualityProfile, QueueEvent, RootFolder, SecurityConfig, SystemStatus, Tag,
|
|
Update,
|
|
},
|
|
sonarr_models::{
|
|
AddSeriesSearchResult, BlocklistItem, BlocklistResponse, DownloadRecord, DownloadStatus,
|
|
DownloadsResponse, Episode, EpisodeFile, Series, SeriesMonitor, SeriesStatus, SeriesType,
|
|
SonarrHistoryEventType, SonarrHistoryItem, SonarrRelease, SonarrSerdeable, SonarrTask,
|
|
SonarrTaskName,
|
|
},
|
|
};
|
|
use crate::network::sonarr_network::sonarr_network_test_utils::test_utils::{
|
|
SERIES_JSON, download_record, task,
|
|
};
|
|
|
|
#[test]
|
|
fn test_episode_display() {
|
|
let episode = Episode {
|
|
title: "Test Title".to_owned(),
|
|
..Episode::default()
|
|
};
|
|
|
|
assert_str_eq!(Episode::default().to_string(), "");
|
|
assert_str_eq!(episode.to_string(), "Test Title");
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_monitor_display() {
|
|
assert_str_eq!(SeriesMonitor::Unknown.to_string(), "unknown");
|
|
assert_str_eq!(SeriesMonitor::All.to_string(), "all");
|
|
assert_str_eq!(SeriesMonitor::Future.to_string(), "future");
|
|
assert_str_eq!(SeriesMonitor::Missing.to_string(), "missing");
|
|
assert_str_eq!(SeriesMonitor::Existing.to_string(), "existing");
|
|
assert_str_eq!(SeriesMonitor::FirstSeason.to_string(), "firstSeason");
|
|
assert_str_eq!(SeriesMonitor::LastSeason.to_string(), "lastSeason");
|
|
assert_str_eq!(SeriesMonitor::LatestSeason.to_string(), "latestSeason");
|
|
assert_str_eq!(SeriesMonitor::Pilot.to_string(), "pilot");
|
|
assert_str_eq!(SeriesMonitor::Recent.to_string(), "recent");
|
|
assert_str_eq!(
|
|
SeriesMonitor::MonitorSpecials.to_string(),
|
|
"monitorSpecials"
|
|
);
|
|
assert_str_eq!(
|
|
SeriesMonitor::UnmonitorSpecials.to_string(),
|
|
"unmonitorSpecials"
|
|
);
|
|
assert_str_eq!(SeriesMonitor::None.to_string(), "none");
|
|
assert_str_eq!(SeriesMonitor::Skip.to_string(), "skip");
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_monitor_to_display_str() {
|
|
assert_str_eq!(SeriesMonitor::Unknown.to_display_str(), "Unknown");
|
|
assert_str_eq!(SeriesMonitor::All.to_display_str(), "All Episodes");
|
|
assert_str_eq!(SeriesMonitor::Future.to_display_str(), "Future Episodes");
|
|
assert_str_eq!(SeriesMonitor::Missing.to_display_str(), "Missing Episodes");
|
|
assert_str_eq!(
|
|
SeriesMonitor::Existing.to_display_str(),
|
|
"Existing Episodes"
|
|
);
|
|
assert_str_eq!(
|
|
SeriesMonitor::FirstSeason.to_display_str(),
|
|
"Only First Season"
|
|
);
|
|
assert_str_eq!(
|
|
SeriesMonitor::LastSeason.to_display_str(),
|
|
"Only Last Season"
|
|
);
|
|
assert_str_eq!(
|
|
SeriesMonitor::LatestSeason.to_display_str(),
|
|
"Only Latest Season"
|
|
);
|
|
assert_str_eq!(SeriesMonitor::Pilot.to_display_str(), "Pilot Episode");
|
|
assert_str_eq!(SeriesMonitor::Recent.to_display_str(), "Recent Episodes");
|
|
assert_str_eq!(
|
|
SeriesMonitor::MonitorSpecials.to_display_str(),
|
|
"Only Specials"
|
|
);
|
|
assert_str_eq!(
|
|
SeriesMonitor::UnmonitorSpecials.to_display_str(),
|
|
"Not Specials"
|
|
);
|
|
assert_str_eq!(SeriesMonitor::None.to_display_str(), "None");
|
|
assert_str_eq!(SeriesMonitor::Skip.to_display_str(), "Skip");
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_status_display() {
|
|
assert_str_eq!(SeriesStatus::Continuing.to_string(), "continuing");
|
|
assert_str_eq!(SeriesStatus::Ended.to_string(), "ended");
|
|
assert_str_eq!(SeriesStatus::Upcoming.to_string(), "upcoming");
|
|
assert_str_eq!(SeriesStatus::Deleted.to_string(), "deleted");
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_status_to_display_str() {
|
|
assert_str_eq!(SeriesStatus::Continuing.to_display_str(), "Continuing");
|
|
assert_str_eq!(SeriesStatus::Ended.to_display_str(), "Ended");
|
|
assert_str_eq!(SeriesStatus::Upcoming.to_display_str(), "Upcoming");
|
|
assert_str_eq!(SeriesStatus::Deleted.to_display_str(), "Deleted");
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_type_display() {
|
|
assert_str_eq!(SeriesType::Standard.to_string(), "standard");
|
|
assert_str_eq!(SeriesType::Daily.to_string(), "daily");
|
|
assert_str_eq!(SeriesType::Anime.to_string(), "anime");
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_type_to_display_str() {
|
|
assert_str_eq!(SeriesType::Standard.to_display_str(), "Standard");
|
|
assert_str_eq!(SeriesType::Daily.to_display_str(), "Daily");
|
|
assert_str_eq!(SeriesType::Anime.to_display_str(), "Anime");
|
|
}
|
|
|
|
#[test]
|
|
fn test_download_status_display() {
|
|
assert_str_eq!(DownloadStatus::Unknown.to_string(), "unknown");
|
|
assert_str_eq!(DownloadStatus::Queued.to_string(), "queued");
|
|
assert_str_eq!(DownloadStatus::Paused.to_string(), "paused");
|
|
assert_str_eq!(DownloadStatus::Downloading.to_string(), "downloading");
|
|
assert_str_eq!(DownloadStatus::Completed.to_string(), "completed");
|
|
assert_str_eq!(DownloadStatus::Failed.to_string(), "failed");
|
|
assert_str_eq!(DownloadStatus::Warning.to_string(), "warning");
|
|
assert_str_eq!(DownloadStatus::Delay.to_string(), "delay");
|
|
assert_str_eq!(
|
|
DownloadStatus::DownloadClientUnavailable.to_string(),
|
|
"downloadClientUnavailable"
|
|
);
|
|
assert_str_eq!(DownloadStatus::Fallback.to_string(), "fallback");
|
|
}
|
|
|
|
#[test]
|
|
fn test_download_status_to_display_str() {
|
|
assert_str_eq!(DownloadStatus::Unknown.to_display_str(), "Unknown");
|
|
assert_str_eq!(DownloadStatus::Queued.to_display_str(), "Queued");
|
|
assert_str_eq!(DownloadStatus::Paused.to_display_str(), "Paused");
|
|
assert_str_eq!(DownloadStatus::Downloading.to_display_str(), "Downloading");
|
|
assert_str_eq!(DownloadStatus::Completed.to_display_str(), "Completed");
|
|
assert_str_eq!(DownloadStatus::Failed.to_display_str(), "Failed");
|
|
assert_str_eq!(DownloadStatus::Warning.to_display_str(), "Warning");
|
|
assert_str_eq!(DownloadStatus::Delay.to_display_str(), "Delay");
|
|
assert_str_eq!(
|
|
DownloadStatus::DownloadClientUnavailable.to_display_str(),
|
|
"Download Client Unavailable"
|
|
);
|
|
assert_str_eq!(DownloadStatus::Fallback.to_display_str(), "Fallback");
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_history_event_type_display() {
|
|
assert_str_eq!(SonarrHistoryEventType::Unknown.to_string(), "unknown",);
|
|
assert_str_eq!(SonarrHistoryEventType::Grabbed.to_string(), "grabbed",);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::SeriesFolderImported.to_string(),
|
|
"seriesFolderImported",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::DownloadFolderImported.to_string(),
|
|
"downloadFolderImported",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::DownloadFailed.to_string(),
|
|
"downloadFailed",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::EpisodeFileDeleted.to_string(),
|
|
"episodeFileDeleted",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::EpisodeFileRenamed.to_string(),
|
|
"episodeFileRenamed",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::DownloadIgnored.to_string(),
|
|
"downloadIgnored",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_history_event_type_to_display_str() {
|
|
assert_str_eq!(SonarrHistoryEventType::Unknown.to_display_str(), "Unknown",);
|
|
assert_str_eq!(SonarrHistoryEventType::Grabbed.to_display_str(), "Grabbed",);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::SeriesFolderImported.to_display_str(),
|
|
"Series Folder Imported",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::DownloadFolderImported.to_display_str(),
|
|
"Download Folder Imported",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::DownloadFailed.to_display_str(),
|
|
"Download Failed",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::EpisodeFileDeleted.to_display_str(),
|
|
"Episode File Deleted",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::EpisodeFileRenamed.to_display_str(),
|
|
"Episode File Renamed",
|
|
);
|
|
assert_str_eq!(
|
|
SonarrHistoryEventType::DownloadIgnored.to_display_str(),
|
|
"Download Ignored",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_history_event_type_deserialization() {
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("unknown")),
|
|
SonarrHistoryEventType::Unknown
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("grabbed")),
|
|
SonarrHistoryEventType::Grabbed
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("seriesFolderImported")),
|
|
SonarrHistoryEventType::SeriesFolderImported
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("downloadFolderImported")),
|
|
SonarrHistoryEventType::DownloadFolderImported
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("downloadFailed")),
|
|
SonarrHistoryEventType::DownloadFailed
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("episodeFileDeleted")),
|
|
SonarrHistoryEventType::EpisodeFileDeleted
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("episodeFileRenamed")),
|
|
SonarrHistoryEventType::EpisodeFileRenamed
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("downloadIgnored")),
|
|
SonarrHistoryEventType::DownloadIgnored
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_history_event_type_deserialization_falls_back_to_unknown() {
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!("episodeFileImportFailed")),
|
|
SonarrHistoryEventType::Unknown
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!(2)),
|
|
SonarrHistoryEventType::Unknown
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!(11)),
|
|
SonarrHistoryEventType::Unknown
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!(null)),
|
|
SonarrHistoryEventType::Unknown
|
|
);
|
|
assert_eq!(
|
|
deserialize_history_event_type(json!({ "id": 2 })),
|
|
SonarrHistoryEventType::Unknown
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_history_event_type_serialization() {
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::Unknown),
|
|
"unknown"
|
|
);
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::Grabbed),
|
|
"grabbed"
|
|
);
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::SeriesFolderImported),
|
|
"seriesFolderImported"
|
|
);
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::DownloadFolderImported),
|
|
"downloadFolderImported"
|
|
);
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::DownloadFailed),
|
|
"downloadFailed"
|
|
);
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::EpisodeFileDeleted),
|
|
"episodeFileDeleted"
|
|
);
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::EpisodeFileRenamed),
|
|
"episodeFileRenamed"
|
|
);
|
|
assert_str_eq!(
|
|
serialize_history_event_type(SonarrHistoryEventType::DownloadIgnored),
|
|
"downloadIgnored"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_task_name_display() {
|
|
assert_str_eq!(
|
|
SonarrTaskName::ApplicationUpdateCheck.to_string(),
|
|
"ApplicationUpdateCheck"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from() {
|
|
let sonarr_serdeable = SonarrSerdeable::Value(json!({}));
|
|
|
|
let serdeable: Serdeable = Serdeable::from(sonarr_serdeable.clone());
|
|
|
|
assert_eq!(serdeable, Serdeable::Sonarr(sonarr_serdeable));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_unit() {
|
|
let sonarr_serdeable = SonarrSerdeable::from(());
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Value(json!({})));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_value() {
|
|
let value = json!({"test": "test"});
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = value.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Value(value));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_episode() {
|
|
let episode = Episode {
|
|
id: 1,
|
|
..Episode::default()
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = episode.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Episode(episode));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_episodes() {
|
|
let episodes = vec![Episode {
|
|
id: 1,
|
|
..Episode::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = episodes.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Episodes(episodes));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_episode_files() {
|
|
let episode_files = vec![EpisodeFile {
|
|
id: 1,
|
|
..EpisodeFile::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = episode_files.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::EpisodeFiles(episode_files)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_host_config() {
|
|
let host_config = HostConfig {
|
|
port: 1234,
|
|
..HostConfig::default()
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = host_config.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::HostConfig(host_config));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_indexers() {
|
|
let indexers = vec![Indexer {
|
|
id: 1,
|
|
..Indexer::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = indexers.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Indexers(indexers));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_indexer_settings() {
|
|
let indexer_settings = IndexerSettings {
|
|
id: 1,
|
|
..IndexerSettings::default()
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = indexer_settings.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::IndexerSettings(indexer_settings)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_series_vec() {
|
|
let series_vec = vec![Series {
|
|
id: 1,
|
|
..Series::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = series_vec.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::SeriesVec(series_vec));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_series() {
|
|
let series = Series {
|
|
id: 1,
|
|
..Series::default()
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = series.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Series(series));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_sonarr_history_items() {
|
|
let history_items = vec![SonarrHistoryItem {
|
|
id: 1,
|
|
..SonarrHistoryItem::default()
|
|
}];
|
|
let sonarr_serdeable: SonarrSerdeable = history_items.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::SonarrHistoryItems(history_items)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_system_status() {
|
|
let system_status = SystemStatus {
|
|
version: "1".to_owned(),
|
|
..SystemStatus::default()
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = system_status.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::SystemStatus(system_status)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_add_series_search_results() {
|
|
let add_series_search_results = vec![AddSeriesSearchResult {
|
|
tvdb_id: 1,
|
|
..AddSeriesSearchResult::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = add_series_search_results.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::AddSeriesSearchResults(add_series_search_results)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_blocklist_response() {
|
|
let blocklist_response = BlocklistResponse {
|
|
records: vec![BlocklistItem {
|
|
id: 1,
|
|
..BlocklistItem::default()
|
|
}],
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = blocklist_response.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::BlocklistResponse(blocklist_response)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_downloads_response() {
|
|
let downloads_response = DownloadsResponse {
|
|
records: vec![DownloadRecord {
|
|
id: 1,
|
|
..DownloadRecord::default()
|
|
}],
|
|
};
|
|
let sonarr_serdeable: SonarrSerdeable = downloads_response.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::DownloadsResponse(downloads_response)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_disk_spaces() {
|
|
let disk_spaces = vec![DiskSpace {
|
|
path: Some("/path".to_owned()),
|
|
free_space: 1,
|
|
total_space: 1,
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = disk_spaces.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::DiskSpaces(disk_spaces));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_language_profiles() {
|
|
let language_profiles = vec![
|
|
Language {
|
|
id: 1,
|
|
name: "English".to_owned(),
|
|
},
|
|
Language {
|
|
id: 2,
|
|
name: "Japanese".to_owned(),
|
|
},
|
|
];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = language_profiles.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::LanguageProfiles(language_profiles)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_log_response() {
|
|
let log_response = LogResponse {
|
|
records: vec![Log {
|
|
level: "info".to_owned(),
|
|
..Log::default()
|
|
}],
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = log_response.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::LogResponse(log_response));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_quality_profiles() {
|
|
let quality_profiles = vec![QualityProfile {
|
|
name: "Test Profile".to_owned(),
|
|
id: 1,
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = quality_profiles.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::QualityProfiles(quality_profiles)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_queue_events() {
|
|
let queue_events = vec![QueueEvent {
|
|
trigger: "test".to_owned(),
|
|
..QueueEvent::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = queue_events.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::QueueEvents(queue_events));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_releases() {
|
|
let releases = vec![SonarrRelease {
|
|
size: 1,
|
|
..SonarrRelease::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = releases.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Releases(releases));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_root_folders() {
|
|
let root_folders = vec![RootFolder {
|
|
id: 1,
|
|
..RootFolder::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = root_folders.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::RootFolders(root_folders));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_security_config() {
|
|
let security_config = SecurityConfig {
|
|
username: Some("Test".to_owned()),
|
|
..SecurityConfig::default()
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = security_config.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::SecurityConfig(security_config)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_tag() {
|
|
let tag = Tag {
|
|
id: 1,
|
|
..Tag::default()
|
|
};
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = tag.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Tag(tag));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_tags() {
|
|
let tags = vec![Tag {
|
|
id: 1,
|
|
..Tag::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = tags.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Tags(tags));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_tasks() {
|
|
let tasks = vec![SonarrTask {
|
|
name: "test".to_owned(),
|
|
..SonarrTask::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = tasks.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Tasks(tasks));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_updates() {
|
|
let updates = vec![Update {
|
|
version: "test".to_owned(),
|
|
..Update::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = updates.clone().into();
|
|
|
|
assert_eq!(sonarr_serdeable, SonarrSerdeable::Updates(updates));
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_serdeable_from_indexer_test_results() {
|
|
let indexer_test_results = vec![IndexerTestResult {
|
|
id: 1,
|
|
..IndexerTestResult::default()
|
|
}];
|
|
|
|
let sonarr_serdeable: SonarrSerdeable = indexer_test_results.clone().into();
|
|
|
|
assert_eq!(
|
|
sonarr_serdeable,
|
|
SonarrSerdeable::IndexerTestResults(indexer_test_results)
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_series_type_deserialization_falls_back_to_default() {
|
|
let expected = Series {
|
|
series_type: SeriesType::default(),
|
|
..serde_json::from_str(SERIES_JSON).unwrap()
|
|
};
|
|
|
|
assert_eq!(
|
|
deserialize_with_field::<Series>(SERIES_JSON, "seriesType", json!(2)),
|
|
expected
|
|
);
|
|
assert_eq!(
|
|
deserialize_with_field::<Series>(SERIES_JSON, "seriesType", json!("notAThing")),
|
|
expected
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_series_status_deserialization_falls_back_to_default() {
|
|
let expected = Series {
|
|
status: SeriesStatus::default(),
|
|
..serde_json::from_str(SERIES_JSON).unwrap()
|
|
};
|
|
|
|
assert_eq!(
|
|
deserialize_with_field::<Series>(SERIES_JSON, "status", json!(2)),
|
|
expected
|
|
);
|
|
assert_eq!(
|
|
deserialize_with_field::<Series>(SERIES_JSON, "status", json!("notAThing")),
|
|
expected
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_download_record_status_deserialization_falls_back_to_default() {
|
|
let download_record_json = serde_json::to_string(&download_record()).unwrap();
|
|
let expected = DownloadRecord {
|
|
status: DownloadStatus::default(),
|
|
..download_record()
|
|
};
|
|
|
|
assert_eq!(
|
|
deserialize_with_field::<DownloadRecord>(&download_record_json, "status", json!(2)),
|
|
expected
|
|
);
|
|
assert_eq!(
|
|
deserialize_with_field::<DownloadRecord>(&download_record_json, "status", json!("notAThing")),
|
|
expected
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn test_sonarr_task_task_name_deserialization_falls_back_to_default() {
|
|
let task_json = serde_json::to_string(&task()).unwrap();
|
|
let expected = SonarrTask {
|
|
task_name: SonarrTaskName::default(),
|
|
..task()
|
|
};
|
|
|
|
assert_eq!(
|
|
deserialize_with_field::<SonarrTask>(&task_json, "taskName", json!(2)),
|
|
expected
|
|
);
|
|
assert_eq!(
|
|
deserialize_with_field::<SonarrTask>(&task_json, "taskName", json!("notAThing")),
|
|
expected
|
|
);
|
|
}
|
|
|
|
fn deserialize_with_field<T: DeserializeOwned>(json: &str, field: &str, value: Value) -> T {
|
|
let mut fixture_json: Value = serde_json::from_str(json).unwrap();
|
|
fixture_json[field] = value;
|
|
|
|
serde_json::from_value(fixture_json).unwrap()
|
|
}
|
|
|
|
fn deserialize_history_event_type(event_type: Value) -> SonarrHistoryEventType {
|
|
let history_item_json = json!({
|
|
"id": 1,
|
|
"sourceTitle": "Test Source Title",
|
|
"episodeId": 1,
|
|
"quality": { "quality": { "name": "HDTV - 1080p" } },
|
|
"languages": [],
|
|
"date": "2024-01-01T00:00:00Z",
|
|
"eventType": event_type,
|
|
"data": {}
|
|
});
|
|
|
|
serde_json::from_value::<SonarrHistoryItem>(history_item_json)
|
|
.unwrap()
|
|
.event_type
|
|
}
|
|
|
|
fn serialize_history_event_type(event_type: SonarrHistoryEventType) -> String {
|
|
let history_item = SonarrHistoryItem {
|
|
event_type,
|
|
..SonarrHistoryItem::default()
|
|
};
|
|
|
|
serde_json::to_value(history_item).unwrap()["eventType"]
|
|
.as_str()
|
|
.unwrap()
|
|
.to_owned()
|
|
}
|
|
}
|