feat(network): Support for fetching Sonarr updates
This commit is contained in:
@@ -11,7 +11,7 @@ use crate::{models::HorizontallyScrollableText, serde_enum_from};
|
|||||||
|
|
||||||
use super::servarr_models::{
|
use super::servarr_models::{
|
||||||
DiskSpace, HostConfig, Indexer, Language, LogResponse, QualityProfile, QualityWrapper,
|
DiskSpace, HostConfig, Indexer, Language, LogResponse, QualityProfile, QualityWrapper,
|
||||||
QueueEvent, Release, RootFolder, SecurityConfig, Tag,
|
QueueEvent, Release, RootFolder, SecurityConfig, Tag, Update,
|
||||||
};
|
};
|
||||||
use super::{EnumDisplayStyle, Serdeable};
|
use super::{EnumDisplayStyle, Serdeable};
|
||||||
|
|
||||||
@@ -471,24 +471,6 @@ impl Display for RadarrTaskName {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct Update {
|
|
||||||
pub version: String,
|
|
||||||
pub release_date: DateTime<Utc>,
|
|
||||||
pub installed: bool,
|
|
||||||
pub latest: bool,
|
|
||||||
pub installed_on: Option<DateTime<Utc>>,
|
|
||||||
pub changes: UpdateChanges,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
pub struct UpdateChanges {
|
|
||||||
pub new: Option<Vec<String>>,
|
|
||||||
pub fixed: Option<Vec<String>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
#[derive(Clone, Serialize, Deserialize, Debug, PartialEq, Eq)]
|
||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ use crate::models::{
|
|||||||
},
|
},
|
||||||
stateful_list::StatefulList,
|
stateful_list::StatefulList,
|
||||||
stateful_table::StatefulTable,
|
stateful_table::StatefulTable,
|
||||||
HorizontallyScrollableText, Route,
|
HorizontallyScrollableText, Route, ScrollableText,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::modals::SeasonDetailsModal;
|
use super::modals::SeasonDetailsModal;
|
||||||
@@ -37,6 +37,7 @@ pub struct SonarrData {
|
|||||||
pub start_time: DateTime<Utc>,
|
pub start_time: DateTime<Utc>,
|
||||||
pub tags_map: BiMap<i64, String>,
|
pub tags_map: BiMap<i64, String>,
|
||||||
pub tasks: StatefulTable<SonarrTask>,
|
pub tasks: StatefulTable<SonarrTask>,
|
||||||
|
pub updates: ScrollableText,
|
||||||
pub version: String,
|
pub version: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +62,7 @@ impl Default for SonarrData {
|
|||||||
start_time: DateTime::default(),
|
start_time: DateTime::default(),
|
||||||
tags_map: BiMap::default(),
|
tags_map: BiMap::default(),
|
||||||
tasks: StatefulTable::default(),
|
tasks: StatefulTable::default(),
|
||||||
|
updates: ScrollableText::default(),
|
||||||
version: String::new(),
|
version: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ mod tests {
|
|||||||
assert_eq!(sonarr_data.start_time, <DateTime<Utc>>::default());
|
assert_eq!(sonarr_data.start_time, <DateTime<Utc>>::default());
|
||||||
assert!(sonarr_data.tags_map.is_empty());
|
assert!(sonarr_data.tags_map.is_empty());
|
||||||
assert!(sonarr_data.tasks.is_empty());
|
assert!(sonarr_data.tasks.is_empty());
|
||||||
|
assert!(sonarr_data.updates.is_empty());
|
||||||
assert!(sonarr_data.version.is_empty());
|
assert!(sonarr_data.version.is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,3 +249,21 @@ pub struct UnmappedFolder {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
pub path: String,
|
pub path: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct Update {
|
||||||
|
pub version: String,
|
||||||
|
pub release_date: DateTime<Utc>,
|
||||||
|
pub installed: bool,
|
||||||
|
pub latest: bool,
|
||||||
|
pub installed_on: Option<DateTime<Utc>>,
|
||||||
|
pub changes: UpdateChanges,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct UpdateChanges {
|
||||||
|
pub new: Option<Vec<String>>,
|
||||||
|
pub fixed: Option<Vec<String>>,
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ use crate::serde_enum_from;
|
|||||||
use super::{
|
use super::{
|
||||||
servarr_models::{
|
servarr_models::{
|
||||||
DiskSpace, HostConfig, Indexer, Language, LogResponse, QualityProfile, QualityWrapper,
|
DiskSpace, HostConfig, Indexer, Language, LogResponse, QualityProfile, QualityWrapper,
|
||||||
QueueEvent, Release, RootFolder, SecurityConfig, Tag,
|
QueueEvent, Release, RootFolder, SecurityConfig, Tag, Update,
|
||||||
},
|
},
|
||||||
EnumDisplayStyle, HorizontallyScrollableText, Serdeable,
|
EnumDisplayStyle, HorizontallyScrollableText, Serdeable,
|
||||||
};
|
};
|
||||||
@@ -430,7 +430,7 @@ impl Display for SonarrTaskName {
|
|||||||
#[serde(untagged)]
|
#[serde(untagged)]
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
pub enum SonarrSerdeable {
|
pub enum SonarrSerdeable {
|
||||||
Value(Value),
|
BlocklistResponse(BlocklistResponse),
|
||||||
DownloadsResponse(DownloadsResponse),
|
DownloadsResponse(DownloadsResponse),
|
||||||
DiskSpaces(Vec<DiskSpace>),
|
DiskSpaces(Vec<DiskSpace>),
|
||||||
Episode(Episode),
|
Episode(Episode),
|
||||||
@@ -438,6 +438,7 @@ pub enum SonarrSerdeable {
|
|||||||
HostConfig(HostConfig),
|
HostConfig(HostConfig),
|
||||||
IndexerSettings(IndexerSettings),
|
IndexerSettings(IndexerSettings),
|
||||||
Indexers(Vec<Indexer>),
|
Indexers(Vec<Indexer>),
|
||||||
|
LogResponse(LogResponse),
|
||||||
QualityProfiles(Vec<QualityProfile>),
|
QualityProfiles(Vec<QualityProfile>),
|
||||||
QueueEvents(Vec<QueueEvent>),
|
QueueEvents(Vec<QueueEvent>),
|
||||||
Releases(Vec<Release>),
|
Releases(Vec<Release>),
|
||||||
@@ -451,8 +452,8 @@ pub enum SonarrSerdeable {
|
|||||||
Tag(Tag),
|
Tag(Tag),
|
||||||
Tags(Vec<Tag>),
|
Tags(Vec<Tag>),
|
||||||
Tasks(Vec<SonarrTask>),
|
Tasks(Vec<SonarrTask>),
|
||||||
BlocklistResponse(BlocklistResponse),
|
Updates(Vec<Update>),
|
||||||
LogResponse(LogResponse),
|
Value(Value),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SonarrSerdeable> for Serdeable {
|
impl From<SonarrSerdeable> for Serdeable {
|
||||||
@@ -469,7 +470,7 @@ impl From<()> for SonarrSerdeable {
|
|||||||
|
|
||||||
serde_enum_from!(
|
serde_enum_from!(
|
||||||
SonarrSerdeable {
|
SonarrSerdeable {
|
||||||
Value(Value),
|
BlocklistResponse(BlocklistResponse),
|
||||||
DownloadsResponse(DownloadsResponse),
|
DownloadsResponse(DownloadsResponse),
|
||||||
DiskSpaces(Vec<DiskSpace>),
|
DiskSpaces(Vec<DiskSpace>),
|
||||||
Episode(Episode),
|
Episode(Episode),
|
||||||
@@ -477,6 +478,7 @@ serde_enum_from!(
|
|||||||
HostConfig(HostConfig),
|
HostConfig(HostConfig),
|
||||||
IndexerSettings(IndexerSettings),
|
IndexerSettings(IndexerSettings),
|
||||||
Indexers(Vec<Indexer>),
|
Indexers(Vec<Indexer>),
|
||||||
|
LogResponse(LogResponse),
|
||||||
QualityProfiles(Vec<QualityProfile>),
|
QualityProfiles(Vec<QualityProfile>),
|
||||||
QueueEvents(Vec<QueueEvent>),
|
QueueEvents(Vec<QueueEvent>),
|
||||||
Releases(Vec<Release>),
|
Releases(Vec<Release>),
|
||||||
@@ -490,8 +492,8 @@ serde_enum_from!(
|
|||||||
Tag(Tag),
|
Tag(Tag),
|
||||||
Tags(Vec<Tag>),
|
Tags(Vec<Tag>),
|
||||||
Tasks(Vec<SonarrTask>),
|
Tasks(Vec<SonarrTask>),
|
||||||
BlocklistResponse(BlocklistResponse),
|
Updates(Vec<Update>),
|
||||||
LogResponse(LogResponse),
|
Value(Value),
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ mod tests {
|
|||||||
use crate::models::{
|
use crate::models::{
|
||||||
servarr_models::{
|
servarr_models::{
|
||||||
DiskSpace, HostConfig, Indexer, Log, LogResponse, QualityProfile, QueueEvent, Release,
|
DiskSpace, HostConfig, Indexer, Log, LogResponse, QualityProfile, QueueEvent, Release,
|
||||||
RootFolder, SecurityConfig, Tag,
|
RootFolder, SecurityConfig, Tag, Update,
|
||||||
},
|
},
|
||||||
sonarr_models::{
|
sonarr_models::{
|
||||||
BlocklistItem, BlocklistResponse, DownloadRecord, DownloadsResponse, Episode,
|
BlocklistItem, BlocklistResponse, DownloadRecord, DownloadsResponse, Episode,
|
||||||
@@ -426,4 +426,16 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(sonarr_serdeable, SonarrSerdeable::Tasks(tasks));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::models::radarr_models::{
|
|||||||
CommandBody, Credit, CreditType, DeleteMovieParams, DownloadRecord, DownloadsResponse,
|
CommandBody, Credit, CreditType, DeleteMovieParams, DownloadRecord, DownloadsResponse,
|
||||||
EditCollectionParams, EditIndexerParams, EditMovieParams, IndexerSettings, IndexerTestResult,
|
EditCollectionParams, EditIndexerParams, EditMovieParams, IndexerSettings, IndexerTestResult,
|
||||||
Movie, MovieCommandBody, MovieHistoryItem, RadarrSerdeable, RadarrTask, RadarrTaskName,
|
Movie, MovieCommandBody, MovieHistoryItem, RadarrSerdeable, RadarrTask, RadarrTaskName,
|
||||||
ReleaseDownloadBody, SystemStatus, Update,
|
ReleaseDownloadBody, SystemStatus,
|
||||||
};
|
};
|
||||||
use crate::models::servarr_data::radarr::modals::{
|
use crate::models::servarr_data::radarr::modals::{
|
||||||
AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, IndexerTestResultModalItem,
|
AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, IndexerTestResultModalItem,
|
||||||
@@ -20,7 +20,7 @@ use crate::models::servarr_data::radarr::modals::{
|
|||||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||||
use crate::models::servarr_models::{
|
use crate::models::servarr_models::{
|
||||||
AddRootFolderBody, DiskSpace, HostConfig, Indexer, LogResponse, QualityProfile, QueueEvent,
|
AddRootFolderBody, DiskSpace, HostConfig, Indexer, LogResponse, QualityProfile, QueueEvent,
|
||||||
Release, RootFolder, SecurityConfig, Tag,
|
Release, RootFolder, SecurityConfig, Tag, Update,
|
||||||
};
|
};
|
||||||
use crate::models::stateful_table::StatefulTable;
|
use crate::models::stateful_table::StatefulTable;
|
||||||
use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText};
|
use crate::models::{HorizontallyScrollableText, Route, Scrollable, ScrollableText};
|
||||||
@@ -244,7 +244,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
|||||||
RadarrEvent::GetStatus => self.get_radarr_status().await.map(RadarrSerdeable::from),
|
RadarrEvent::GetStatus => self.get_radarr_status().await.map(RadarrSerdeable::from),
|
||||||
RadarrEvent::GetTags => self.get_radarr_tags().await.map(RadarrSerdeable::from),
|
RadarrEvent::GetTags => self.get_radarr_tags().await.map(RadarrSerdeable::from),
|
||||||
RadarrEvent::GetTasks => self.get_radarr_tasks().await.map(RadarrSerdeable::from),
|
RadarrEvent::GetTasks => self.get_radarr_tasks().await.map(RadarrSerdeable::from),
|
||||||
RadarrEvent::GetUpdates => self.get_updates().await.map(RadarrSerdeable::from),
|
RadarrEvent::GetUpdates => self.get_radarr_updates().await.map(RadarrSerdeable::from),
|
||||||
RadarrEvent::HealthCheck => self
|
RadarrEvent::HealthCheck => self
|
||||||
.get_radarr_healthcheck()
|
.get_radarr_healthcheck()
|
||||||
.await
|
.await
|
||||||
@@ -1870,7 +1870,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_updates(&mut self) -> Result<Vec<Update>> {
|
async fn get_radarr_updates(&mut self) -> Result<Vec<Update>> {
|
||||||
info!("Fetching Radarr updates");
|
info!("Fetching Radarr updates");
|
||||||
let event = RadarrEvent::GetUpdates;
|
let event = RadarrEvent::GetUpdates;
|
||||||
|
|
||||||
|
|||||||
@@ -2730,7 +2730,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_handle_get_updates_event() {
|
async fn test_handle_get_radarr_updates_event() {
|
||||||
let updates_json = json!([{
|
let updates_json = json!([{
|
||||||
"version": "4.3.2.1",
|
"version": "4.3.2.1",
|
||||||
"releaseDate": "2023-04-15T02:02:53Z",
|
"releaseDate": "2023-04-15T02:02:53Z",
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
servarr_models::{
|
servarr_models::{
|
||||||
AddRootFolderBody, DiskSpace, HostConfig, Indexer, LogResponse, QualityProfile, QueueEvent,
|
AddRootFolderBody, DiskSpace, HostConfig, Indexer, LogResponse, QualityProfile, QueueEvent,
|
||||||
Release, RootFolder, SecurityConfig, Tag,
|
Release, RootFolder, SecurityConfig, Tag, Update,
|
||||||
},
|
},
|
||||||
sonarr_models::{
|
sonarr_models::{
|
||||||
BlocklistResponse, DownloadRecord, DownloadsResponse, Episode, IndexerSettings, Series,
|
BlocklistResponse, DownloadRecord, DownloadsResponse, Episode, IndexerSettings, Series,
|
||||||
@@ -59,6 +59,7 @@ pub enum SonarrEvent {
|
|||||||
GetSeriesDetails(Option<i64>),
|
GetSeriesDetails(Option<i64>),
|
||||||
GetSeriesHistory(Option<i64>),
|
GetSeriesHistory(Option<i64>),
|
||||||
GetStatus,
|
GetStatus,
|
||||||
|
GetUpdates,
|
||||||
GetTags,
|
GetTags,
|
||||||
GetTasks,
|
GetTasks,
|
||||||
HealthCheck,
|
HealthCheck,
|
||||||
@@ -90,6 +91,7 @@ impl NetworkResource for SonarrEvent {
|
|||||||
SonarrEvent::GetSeriesHistory(_) => "/history/series",
|
SonarrEvent::GetSeriesHistory(_) => "/history/series",
|
||||||
SonarrEvent::GetStatus => "/system/status",
|
SonarrEvent::GetStatus => "/system/status",
|
||||||
SonarrEvent::GetTasks => "/system/task",
|
SonarrEvent::GetTasks => "/system/task",
|
||||||
|
SonarrEvent::GetUpdates => "/update",
|
||||||
SonarrEvent::HealthCheck => "/health",
|
SonarrEvent::HealthCheck => "/health",
|
||||||
SonarrEvent::ListSeries | SonarrEvent::GetSeriesDetails(_) => "/series",
|
SonarrEvent::ListSeries | SonarrEvent::GetSeriesDetails(_) => "/series",
|
||||||
SonarrEvent::MarkHistoryItemAsFailed(_) => "/history/failed",
|
SonarrEvent::MarkHistoryItemAsFailed(_) => "/history/failed",
|
||||||
@@ -205,6 +207,7 @@ impl<'a, 'b> Network<'a, 'b> {
|
|||||||
SonarrEvent::GetStatus => self.get_sonarr_status().await.map(SonarrSerdeable::from),
|
SonarrEvent::GetStatus => self.get_sonarr_status().await.map(SonarrSerdeable::from),
|
||||||
SonarrEvent::GetTags => self.get_sonarr_tags().await.map(SonarrSerdeable::from),
|
SonarrEvent::GetTags => self.get_sonarr_tags().await.map(SonarrSerdeable::from),
|
||||||
SonarrEvent::GetTasks => self.get_sonarr_tasks().await.map(SonarrSerdeable::from),
|
SonarrEvent::GetTasks => self.get_sonarr_tasks().await.map(SonarrSerdeable::from),
|
||||||
|
SonarrEvent::GetUpdates => self.get_sonarr_updates().await.map(SonarrSerdeable::from),
|
||||||
SonarrEvent::HealthCheck => self
|
SonarrEvent::HealthCheck => self
|
||||||
.get_sonarr_healthcheck()
|
.get_sonarr_healthcheck()
|
||||||
.await
|
.await
|
||||||
@@ -1174,6 +1177,84 @@ impl<'a, 'b> Network<'a, 'b> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn get_sonarr_updates(&mut self) -> Result<Vec<Update>> {
|
||||||
|
info!("Fetching Sonarr updates");
|
||||||
|
let event = SonarrEvent::GetUpdates;
|
||||||
|
|
||||||
|
let request_props = self
|
||||||
|
.request_props_from(event, RequestMethod::Get, None::<()>, None, None)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
self
|
||||||
|
.handle_request::<(), Vec<Update>>(request_props, |updates_vec, mut app| {
|
||||||
|
let latest_installed = if updates_vec
|
||||||
|
.iter()
|
||||||
|
.any(|update| update.latest && update.installed_on.is_some())
|
||||||
|
{
|
||||||
|
"already".to_owned()
|
||||||
|
} else {
|
||||||
|
"not".to_owned()
|
||||||
|
};
|
||||||
|
let updates = updates_vec
|
||||||
|
.into_iter()
|
||||||
|
.map(|update| {
|
||||||
|
let install_status = if update.installed_on.is_some() {
|
||||||
|
if update.installed {
|
||||||
|
"(Currently Installed)".to_owned()
|
||||||
|
} else {
|
||||||
|
"(Previously Installed)".to_owned()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String::new()
|
||||||
|
};
|
||||||
|
let vec_to_bullet_points = |vec: Vec<String>| {
|
||||||
|
vec
|
||||||
|
.iter()
|
||||||
|
.map(|change| format!(" * {change}"))
|
||||||
|
.collect::<Vec<String>>()
|
||||||
|
.join("\n")
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut update_info = formatdoc!(
|
||||||
|
"{} - {} {install_status}
|
||||||
|
{}",
|
||||||
|
update.version,
|
||||||
|
update.release_date,
|
||||||
|
"-".repeat(200)
|
||||||
|
);
|
||||||
|
|
||||||
|
if let Some(new_changes) = update.changes.new {
|
||||||
|
let changes = vec_to_bullet_points(new_changes);
|
||||||
|
update_info = formatdoc!(
|
||||||
|
"{update_info}
|
||||||
|
New:
|
||||||
|
{changes}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(fixes) = update.changes.fixed {
|
||||||
|
let fixes = vec_to_bullet_points(fixes);
|
||||||
|
update_info = formatdoc!(
|
||||||
|
"{update_info}
|
||||||
|
Fixed:
|
||||||
|
{fixes}"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
update_info
|
||||||
|
})
|
||||||
|
.reduce(|version_1, version_2| format!("{version_1}\n\n\n{version_2}"))
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
app.data.sonarr_data.updates = ScrollableText::with_string(formatdoc!(
|
||||||
|
"The latest version of Sonarr is {latest_installed} installed
|
||||||
|
|
||||||
|
{updates}"
|
||||||
|
));
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
async fn mark_sonarr_history_item_as_failed(&mut self, history_item_id: i64) -> Result<Value> {
|
async fn mark_sonarr_history_item_as_failed(&mut self, history_item_id: i64) -> Result<Value> {
|
||||||
info!("Marking the Sonarr history item with ID: {history_item_id} as 'failed'");
|
info!("Marking the Sonarr history item with ID: {history_item_id} as 'failed'");
|
||||||
let event = SonarrEvent::MarkHistoryItemAsFailed(history_item_id);
|
let event = SonarrEvent::MarkHistoryItemAsFailed(history_item_id);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ mod test {
|
|||||||
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
||||||
use crate::models::servarr_models::{
|
use crate::models::servarr_models::{
|
||||||
DiskSpace, HostConfig, Indexer, IndexerField, Language, LogResponse, Quality, QualityProfile,
|
DiskSpace, HostConfig, Indexer, IndexerField, Language, LogResponse, Quality, QualityProfile,
|
||||||
QualityWrapper, QueueEvent, Release, RootFolder, SecurityConfig, Tag,
|
QualityWrapper, QueueEvent, Release, RootFolder, SecurityConfig, Tag, Update,
|
||||||
};
|
};
|
||||||
use crate::models::sonarr_models::{
|
use crate::models::sonarr_models::{
|
||||||
BlocklistItem, DownloadRecord, DownloadsResponse, Episode, EpisodeFile, MediaInfo,
|
BlocklistItem, DownloadRecord, DownloadsResponse, Episode, EpisodeFile, MediaInfo,
|
||||||
@@ -29,8 +29,8 @@ mod test {
|
|||||||
};
|
};
|
||||||
use crate::models::sonarr_models::{SonarrTask, SystemStatus};
|
use crate::models::sonarr_models::{SonarrTask, SystemStatus};
|
||||||
use crate::models::stateful_table::StatefulTable;
|
use crate::models::stateful_table::StatefulTable;
|
||||||
use crate::models::HorizontallyScrollableText;
|
|
||||||
use crate::models::{sonarr_models::SonarrSerdeable, stateful_table::SortOption};
|
use crate::models::{sonarr_models::SonarrSerdeable, stateful_table::SortOption};
|
||||||
|
use crate::models::{HorizontallyScrollableText, ScrollableText};
|
||||||
|
|
||||||
use crate::network::sonarr_network::get_episode_status;
|
use crate::network::sonarr_network::get_episode_status;
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -219,6 +219,7 @@ mod test {
|
|||||||
#[case(SonarrEvent::GetQualityProfiles, "/qualityprofile")]
|
#[case(SonarrEvent::GetQualityProfiles, "/qualityprofile")]
|
||||||
#[case(SonarrEvent::GetStatus, "/system/status")]
|
#[case(SonarrEvent::GetStatus, "/system/status")]
|
||||||
#[case(SonarrEvent::GetTasks, "/system/task")]
|
#[case(SonarrEvent::GetTasks, "/system/task")]
|
||||||
|
#[case(SonarrEvent::GetUpdates, "/update")]
|
||||||
#[case(SonarrEvent::MarkHistoryItemAsFailed(0), "/history/failed")]
|
#[case(SonarrEvent::MarkHistoryItemAsFailed(0), "/history/failed")]
|
||||||
fn test_resource(#[case] event: SonarrEvent, #[case] expected_uri: String) {
|
fn test_resource(#[case] event: SonarrEvent, #[case] expected_uri: String) {
|
||||||
assert_str_eq!(event.resource(), expected_uri);
|
assert_str_eq!(event.resource(), expected_uri);
|
||||||
@@ -3741,6 +3742,101 @@ mod test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_handle_get_sonarr_updates_event() {
|
||||||
|
let updates_json = json!([{
|
||||||
|
"version": "4.3.2.1",
|
||||||
|
"releaseDate": "2023-04-15T02:02:53Z",
|
||||||
|
"installed": true,
|
||||||
|
"installedOn": "2023-04-15T02:02:53Z",
|
||||||
|
"latest": true,
|
||||||
|
"changes": {
|
||||||
|
"new": [
|
||||||
|
"Cool new thing"
|
||||||
|
],
|
||||||
|
"fixed": [
|
||||||
|
"Some bugs killed"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "3.2.1.0",
|
||||||
|
"releaseDate": "2023-04-15T02:02:53Z",
|
||||||
|
"installed": false,
|
||||||
|
"installedOn": "2023-04-15T02:02:53Z",
|
||||||
|
"latest": false,
|
||||||
|
"changes": {
|
||||||
|
"new": [
|
||||||
|
"Cool new thing (old)",
|
||||||
|
"Other cool new thing (old)"
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"version": "2.1.0",
|
||||||
|
"releaseDate": "2023-04-15T02:02:53Z",
|
||||||
|
"installed": false,
|
||||||
|
"latest": false,
|
||||||
|
"changes": {
|
||||||
|
"fixed": [
|
||||||
|
"Killed bug 1",
|
||||||
|
"Fixed bug 2"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
}]);
|
||||||
|
let response: Vec<Update> = serde_json::from_value(updates_json.clone()).unwrap();
|
||||||
|
let line_break = "-".repeat(200);
|
||||||
|
let expected_text = ScrollableText::with_string(formatdoc!(
|
||||||
|
"
|
||||||
|
The latest version of Sonarr is already installed
|
||||||
|
|
||||||
|
4.3.2.1 - 2023-04-15 02:02:53 UTC (Currently Installed)
|
||||||
|
{line_break}
|
||||||
|
New:
|
||||||
|
* Cool new thing
|
||||||
|
Fixed:
|
||||||
|
* Some bugs killed
|
||||||
|
|
||||||
|
|
||||||
|
3.2.1.0 - 2023-04-15 02:02:53 UTC (Previously Installed)
|
||||||
|
{line_break}
|
||||||
|
New:
|
||||||
|
* Cool new thing (old)
|
||||||
|
* Other cool new thing (old)
|
||||||
|
|
||||||
|
|
||||||
|
2.1.0 - 2023-04-15 02:02:53 UTC
|
||||||
|
{line_break}
|
||||||
|
Fixed:
|
||||||
|
* Killed bug 1
|
||||||
|
* Fixed bug 2"
|
||||||
|
));
|
||||||
|
let (async_server, app_arc, _server) = mock_servarr_api(
|
||||||
|
RequestMethod::Get,
|
||||||
|
None,
|
||||||
|
Some(updates_json),
|
||||||
|
None,
|
||||||
|
SonarrEvent::GetUpdates,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await;
|
||||||
|
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
|
||||||
|
|
||||||
|
if let SonarrSerdeable::Updates(updates) = network
|
||||||
|
.handle_sonarr_event(SonarrEvent::GetUpdates)
|
||||||
|
.await
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
async_server.assert_async().await;
|
||||||
|
assert_str_eq!(
|
||||||
|
app_arc.lock().await.data.sonarr_data.updates.get_text(),
|
||||||
|
expected_text.get_text()
|
||||||
|
);
|
||||||
|
assert_eq!(updates, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_handle_mark_sonarr_history_item_as_failed_event() {
|
async fn test_handle_mark_sonarr_history_item_as_failed_event() {
|
||||||
let expected_history_item_id = 1;
|
let expected_history_item_id = 1;
|
||||||
|
|||||||
Reference in New Issue
Block a user