fix(sonarr): Pass the episode ID alongside all GetEpisodeDetails events when publishing to the networking channel

This commit is contained in:
2024-12-17 23:52:18 -07:00
parent 4fdf9b3df1
commit 30ba1f3317
6 changed files with 54 additions and 73 deletions
+15 -1
View File
@@ -69,7 +69,9 @@ impl<'a> App<'a> {
}
ActiveSonarrBlock::EpisodeDetails | ActiveSonarrBlock::EpisodeFile => {
self
.dispatch_network_event(SonarrEvent::GetEpisodeDetails(None).into())
.dispatch_network_event(
SonarrEvent::GetEpisodeDetails(self.extract_episode_id().await).into(),
)
.await;
}
ActiveSonarrBlock::EpisodeHistory => {
@@ -242,4 +244,16 @@ impl<'a> App<'a> {
.collect();
self.data.sonarr_data.seasons.set_items(seasons);
}
async fn extract_episode_id(&self) -> i64 {
self
.data
.sonarr_data
.season_details_modal
.as_ref()
.expect("Season details have not been loaded")
.episodes
.current_selection()
.id
}
}
+21 -2
View File
@@ -4,6 +4,7 @@ mod tests {
use pretty_assertions::{assert_eq, assert_str_eq};
use tokio::sync::mpsc;
use crate::models::servarr_data::sonarr::sonarr_data::sonarr_test_utils::utils::create_test_sonarr_data;
use crate::{
app::App,
models::{
@@ -174,6 +175,7 @@ mod tests {
#[tokio::test]
async fn test_dispatch_by_episode_details_block() {
let (mut app, mut sync_network_rx) = construct_app_unit();
app.data.sonarr_data = create_test_sonarr_data();
app
.dispatch_by_sonarr_block(&ActiveSonarrBlock::EpisodeDetails)
@@ -182,7 +184,7 @@ mod tests {
assert!(app.is_loading);
assert_eq!(
sync_network_rx.recv().await.unwrap(),
SonarrEvent::GetEpisodeDetails(None).into()
SonarrEvent::GetEpisodeDetails(0).into()
);
assert!(!app.data.sonarr_data.prompt_confirm);
assert_eq!(app.tick_count, 0);
@@ -191,6 +193,7 @@ mod tests {
#[tokio::test]
async fn test_dispatch_by_episode_file_block() {
let (mut app, mut sync_network_rx) = construct_app_unit();
app.data.sonarr_data = create_test_sonarr_data();
app
.dispatch_by_sonarr_block(&ActiveSonarrBlock::EpisodeFile)
@@ -199,7 +202,7 @@ mod tests {
assert!(app.is_loading);
assert_eq!(
sync_network_rx.recv().await.unwrap(),
SonarrEvent::GetEpisodeDetails(None).into()
SonarrEvent::GetEpisodeDetails(0).into()
);
assert!(!app.data.sonarr_data.prompt_confirm);
assert_eq!(app.tick_count, 0);
@@ -727,6 +730,22 @@ mod tests {
);
}
#[tokio::test]
async fn test_extract_episode_id() {
let mut app = App::default();
app.data.sonarr_data = create_test_sonarr_data();
assert_eq!(app.extract_episode_id().await, 0);
}
#[tokio::test]
#[should_panic(expected = "Season details have not been loaded")]
async fn test_extract_episode_id_requires_season_details_modal_to_be_some() {
let app = App::default();
assert_eq!(app.extract_episode_id().await, 0);
}
fn construct_app_unit<'a>() -> (App<'a>, mpsc::Receiver<NetworkEvent>) {
let (sync_network_tx, sync_network_rx) = mpsc::channel::<NetworkEvent>(500);
let mut app = App {
+1 -1
View File
@@ -83,7 +83,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrGetCommand> for SonarrGetCommandHan
SonarrGetCommand::EpisodeDetails { episode_id } => {
let resp = self
.network
.handle_network_event(SonarrEvent::GetEpisodeDetails(Some(episode_id)).into())
.handle_network_event(SonarrEvent::GetEpisodeDetails(episode_id).into())
.await?;
serde_json::to_string_pretty(&resp)?
}
+1 -1
View File
@@ -160,7 +160,7 @@ mod tests {
mock_network
.expect_handle_network_event()
.with(eq::<NetworkEvent>(
SonarrEvent::GetEpisodeDetails(Some(expected_episode_id)).into(),
SonarrEvent::GetEpisodeDetails(expected_episode_id).into(),
))
.times(1)
.returning(|_| {
+6 -7
View File
@@ -59,7 +59,7 @@ pub enum SonarrEvent {
GetHistory(u64),
GetHostConfig,
GetIndexers,
GetEpisodeDetails(Option<i64>),
GetEpisodeDetails(i64),
GetEpisodes(Option<i64>),
GetEpisodeFiles(Option<i64>),
GetEpisodeHistory(Option<i64>),
@@ -1305,19 +1305,18 @@ impl<'a, 'b> Network<'a, 'b> {
.await
}
async fn get_episode_details(&mut self, episode_id: Option<i64>) -> Result<Episode> {
async fn get_episode_details(&mut self, episode_id: i64) -> Result<Episode> {
info!("Fetching Sonarr episode details");
let event = SonarrEvent::GetEpisodeDetails(None);
let id = self.extract_episode_id(episode_id).await;
let event = SonarrEvent::GetEpisodeDetails(episode_id);
info!("Fetching episode details for episode with ID: {id}");
info!("Fetching episode details for episode with ID: {episode_id}");
let request_props = self
.request_props_from(
event,
RequestMethod::Get,
None::<()>,
Some(format!("/{id}")),
Some(format!("/{episode_id}")),
None,
)
.await;
@@ -2227,7 +2226,7 @@ impl<'a, 'b> Network<'a, 'b> {
async fn toggle_sonarr_episode_monitoring(&mut self, episode_id: Option<i64>) -> Result<()> {
let event = SonarrEvent::ToggleEpisodeMonitoring(episode_id);
let detail_event = SonarrEvent::GetEpisodeDetails(None);
let detail_event = SonarrEvent::GetEpisodeDetails(0);
let (id, monitored) = if let Some(episode_id) = episode_id {
info!("Fetching episode details for episode id: {episode_id}");
+10 -61
View File
@@ -149,8 +149,7 @@ mod test {
#[rstest]
fn test_resource_episode(
#[values(SonarrEvent::GetEpisodes(None), SonarrEvent::GetEpisodeDetails(None))]
event: SonarrEvent,
#[values(SonarrEvent::GetEpisodes(None), SonarrEvent::GetEpisodeDetails(0))] event: SonarrEvent,
) {
assert_str_eq!(event.resource(), "/episode");
}
@@ -2651,7 +2650,7 @@ mod test {
None,
Some(serde_json::from_str(EPISODE_JSON).unwrap()),
None,
SonarrEvent::GetEpisodeDetails(None),
SonarrEvent::GetEpisodeDetails(1),
Some("/1"),
None,
)
@@ -2669,7 +2668,7 @@ mod test {
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let SonarrSerdeable::Episode(episode) = network
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(None))
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(1))
.await
.unwrap()
{
@@ -2767,7 +2766,7 @@ mod test {
None,
Some(serde_json::from_str(EPISODE_JSON).unwrap()),
None,
SonarrEvent::GetEpisodeDetails(None),
SonarrEvent::GetEpisodeDetails(1),
Some("/1"),
None,
)
@@ -2782,7 +2781,7 @@ mod test {
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let SonarrSerdeable::Episode(episode) = network
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(None))
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(1))
.await
.unwrap()
{
@@ -2856,34 +2855,6 @@ mod test {
}
}
#[tokio::test]
async fn test_handle_get_episode_details_event_uses_provided_id() {
let response: Episode = serde_json::from_str(EPISODE_JSON).unwrap();
let (async_server, app_arc, _server) = mock_servarr_api(
RequestMethod::Get,
None,
Some(serde_json::from_str(EPISODE_JSON).unwrap()),
None,
SonarrEvent::GetEpisodeDetails(None),
Some("/1"),
None,
)
.await;
let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal.episodes.set_items(vec![episode()]);
app_arc.lock().await.data.sonarr_data.season_details_modal = Some(season_details_modal);
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let SonarrSerdeable::Episode(episode) = network
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(Some(1)))
.await
.unwrap()
{
async_server.assert_async().await;
assert_eq!(episode, response);
}
}
#[tokio::test]
async fn test_handle_get_sonarr_episode_history_event() {
let history_json = json!({"records": [{
@@ -3356,7 +3327,7 @@ mod test {
None,
Some(serde_json::from_str(EPISODE_JSON).unwrap()),
None,
SonarrEvent::GetEpisodeDetails(None),
SonarrEvent::GetEpisodeDetails(1),
Some("/1"),
None,
)
@@ -3365,7 +3336,7 @@ mod test {
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let SonarrSerdeable::Episode(episode) = network
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(Some(1)))
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(1))
.await
.unwrap()
{
@@ -3374,28 +3345,6 @@ mod test {
}
}
#[tokio::test]
#[should_panic(expected = "Season details have not been loaded")]
async fn test_handle_get_episode_details_event_requires_season_details_modal_to_be_some_when_no_parameter_is_passed(
) {
let (_async_server, app_arc, _server) = mock_servarr_api(
RequestMethod::Get,
None,
Some(serde_json::from_str(EPISODE_JSON).unwrap()),
None,
SonarrEvent::GetEpisodeDetails(None),
Some("/1"),
None,
)
.await;
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
network
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(None))
.await
.unwrap();
}
#[tokio::test]
#[should_panic(expected = "Season details modal is empty")]
async fn test_handle_get_episode_details_event_requires_season_details_modal_to_be_some_when_in_tui_mode(
@@ -3405,7 +3354,7 @@ mod test {
None,
Some(serde_json::from_str(EPISODE_JSON).unwrap()),
None,
SonarrEvent::GetEpisodeDetails(None),
SonarrEvent::GetEpisodeDetails(1),
Some("/1"),
None,
)
@@ -3413,7 +3362,7 @@ mod test {
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
network
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(Some(1)))
.handle_sonarr_event(SonarrEvent::GetEpisodeDetails(1))
.await
.unwrap();
}
@@ -6186,7 +6135,7 @@ mod test {
None,
Some(json!(body)),
None,
SonarrEvent::GetEpisodeDetails(None),
SonarrEvent::GetEpisodeDetails(2),
Some("/2"),
None,
)