diff --git a/src/app/sonarr/mod.rs b/src/app/sonarr/mod.rs index 3d96f94..99bdb44 100644 --- a/src/app/sonarr/mod.rs +++ b/src/app/sonarr/mod.rs @@ -55,9 +55,14 @@ impl<'a> App<'a> { .await; } ActiveSonarrBlock::SeasonHistory => { - self - .dispatch_network_event(SonarrEvent::GetSeasonHistory(None).into()) - .await; + if !self.data.sonarr_data.seasons.is_empty() { + self + .dispatch_network_event( + SonarrEvent::GetSeasonHistory(self.extract_series_id_season_number_tuple().await) + .into(), + ) + .await; + } } ActiveSonarrBlock::ManualSeasonSearch => { match self.data.sonarr_data.season_details_modal.as_ref() { @@ -266,4 +271,15 @@ impl<'a> App<'a> { async fn extract_series_id(&self) -> i64 { self.data.sonarr_data.series.current_selection().id } + + async fn extract_series_id_season_number_tuple(&self) -> (i64, i64) { + let series_id = self.data.sonarr_data.series.current_selection().id; + let season_number = self + .data + .sonarr_data + .seasons + .current_selection() + .season_number; + (series_id, season_number) + } } diff --git a/src/app/sonarr/sonarr_tests.rs b/src/app/sonarr/sonarr_tests.rs index 0f00a9e..7e6c5b7 100644 --- a/src/app/sonarr/sonarr_tests.rs +++ b/src/app/sonarr/sonarr_tests.rs @@ -111,6 +111,14 @@ mod tests { #[tokio::test] async fn test_dispatch_by_season_history_block() { let (mut app, mut sync_network_rx) = construct_app_unit(); + app.data.sonarr_data.series.set_items(vec![Series { + id: 1, + ..Series::default() + }]); + app.data.sonarr_data.seasons.set_items(vec![Season { + season_number: 1, + ..Season::default() + }]); app .dispatch_by_sonarr_block(&ActiveSonarrBlock::SeasonHistory) @@ -119,12 +127,29 @@ mod tests { assert!(app.is_loading); assert_eq!( sync_network_rx.recv().await.unwrap(), - SonarrEvent::GetSeasonHistory(None).into() + SonarrEvent::GetSeasonHistory((1, 1)).into() ); assert!(!app.data.sonarr_data.prompt_confirm); assert_eq!(app.tick_count, 0); } + #[tokio::test] + async fn test_dispatch_by_season_history_block_no_op_when_seasons_table_is_empty() { + let (mut app, _) = construct_app_unit(); + app.data.sonarr_data.series.set_items(vec![Series { + id: 1, + ..Series::default() + }]); + + app + .dispatch_by_sonarr_block(&ActiveSonarrBlock::SeasonHistory) + .await; + + assert!(!app.is_loading); + assert!(!app.data.sonarr_data.prompt_confirm); + assert_eq!(app.tick_count, 0); + } + #[tokio::test] async fn test_dispatch_by_manual_season_search_block() { let (mut app, mut sync_network_rx) = construct_app_unit(); @@ -777,6 +802,21 @@ mod tests { assert_eq!(app.extract_series_id().await, 1); } + #[tokio::test] + async fn test_extract_series_id_season_number_tuple() { + let mut app = App::default(); + app.data.sonarr_data.series.set_items(vec![Series { + id: 1, + ..Series::default() + }]); + app.data.sonarr_data.seasons.set_items(vec![Season { + season_number: 1, + ..Season::default() + }]); + + assert_eq!(app.extract_series_id_season_number_tuple().await, (1, 1)); + } + fn construct_app_unit<'a>() -> (App<'a>, mpsc::Receiver) { let (sync_network_tx, sync_network_rx) = mpsc::channel::(500); let mut app = App { diff --git a/src/cli/sonarr/list_command_handler.rs b/src/cli/sonarr/list_command_handler.rs index e695cca..c261624 100644 --- a/src/cli/sonarr/list_command_handler.rs +++ b/src/cli/sonarr/list_command_handler.rs @@ -246,9 +246,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrListCommand> for SonarrListCommandH } => { let resp = self .network - .handle_network_event( - SonarrEvent::GetSeasonHistory(Some((series_id, season_number))).into(), - ) + .handle_network_event(SonarrEvent::GetSeasonHistory((series_id, season_number)).into()) .await?; serde_json::to_string_pretty(&resp)? } diff --git a/src/cli/sonarr/list_command_handler_tests.rs b/src/cli/sonarr/list_command_handler_tests.rs index ce69f67..620a514 100644 --- a/src/cli/sonarr/list_command_handler_tests.rs +++ b/src/cli/sonarr/list_command_handler_tests.rs @@ -488,7 +488,7 @@ mod tests { mock_network .expect_handle_network_event() .with(eq::( - SonarrEvent::GetSeasonHistory(Some((expected_series_id, expected_season_number))).into(), + SonarrEvent::GetSeasonHistory((expected_series_id, expected_season_number)).into(), )) .times(1) .returning(|_| { diff --git a/src/network/sonarr_network.rs b/src/network/sonarr_network.rs index eb15f6f..0d548ef 100644 --- a/src/network/sonarr_network.rs +++ b/src/network/sonarr_network.rs @@ -70,7 +70,7 @@ pub enum SonarrEvent { GetQueuedEvents, GetRootFolders, GetEpisodeReleases(i64), - GetSeasonHistory(Option<(i64, i64)>), + GetSeasonHistory((i64, i64)), GetSeasonReleases(Option<(i64, i64)>), GetSecurityConfig, GetSeriesDetails(Option), @@ -1718,22 +1718,13 @@ impl<'a, 'b> Network<'a, 'b> { async fn get_sonarr_season_history( &mut self, - series_season_id_tuple: Option<(i64, i64)>, + series_season_id_tuple: (i64, i64), ) -> Result> { - let event = SonarrEvent::GetSeasonHistory(None); - let (series_id, season_number) = - if let Some((series_id, season_number)) = series_season_id_tuple { - (Some(series_id), Some(season_number)) - } else { - (None, None) - }; - - let (series_id, series_id_param) = self.extract_series_id(series_id).await; - let (season_number, season_number_param) = self.extract_season_number(season_number).await?; - + let event = SonarrEvent::GetSeasonHistory(series_season_id_tuple); + let (series_id, season_number) = series_season_id_tuple; info!("Fetching history for series with ID: {series_id} and season number: {season_number}"); - let params = format!("{series_id_param}&{season_number_param}",); + let params = format!("seriesId={series_id}&seasonNumber={season_number}",); let request_props = self .request_props_from(event, RequestMethod::Get, None::<()>, None, Some(params)) .await; diff --git a/src/network/sonarr_network_tests.rs b/src/network/sonarr_network_tests.rs index b6f90cc..ffa26d7 100644 --- a/src/network/sonarr_network_tests.rs +++ b/src/network/sonarr_network_tests.rs @@ -228,7 +228,7 @@ mod test { fn test_resource_series_history( #[values( SonarrEvent::GetSeriesHistory(None), - SonarrEvent::GetSeasonHistory(None) + SonarrEvent::GetSeasonHistory((0, 0)) )] event: SonarrEvent, ) { @@ -3511,7 +3511,7 @@ mod test { None, Some(history_json), None, - SonarrEvent::GetSeasonHistory(None), + SonarrEvent::GetSeasonHistory((1, 1)), None, Some("seriesId=1&seasonNumber=1"), ) @@ -3545,123 +3545,7 @@ mod test { let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); if let SonarrSerdeable::SonarrHistoryItems(history) = network - .handle_sonarr_event(SonarrEvent::GetSeasonHistory(None)) - .await - .unwrap() - { - async_server.assert_async().await; - assert_eq!( - app_arc - .lock() - .await - .data - .sonarr_data - .season_details_modal - .as_ref() - .unwrap() - .season_history - .items, - expected_history_items - ); - assert!( - app_arc - .lock() - .await - .data - .sonarr_data - .season_details_modal - .as_ref() - .unwrap() - .season_history - .sort_asc - ); - assert_eq!(history, response); - } - } - - #[tokio::test] - async fn test_handle_get_sonarr_season_history_event_uses_provided_series_id_and_season_number() { - let history_json = json!([{ - "id": 123, - "sourceTitle": "z episode", - "episodeId": 1007, - "quality": { "quality": { "name": "Bluray-1080p" } }, - "languages": [{ "id": 1, "name": "English" }], - "date": "2024-02-10T07:28:45Z", - "eventType": "grabbed", - "data": { - "droppedPath": "/nfs/nzbget/completed/series/Coolness/something.cool.mkv", - "importedPath": "/nfs/tv/Coolness/Season 1/Coolness - S01E01 - Something Cool Bluray-1080p.mkv" - } - }, - { - "id": 456, - "sourceTitle": "A Episode", - "episodeId": 2001, - "quality": { "quality": { "name": "Bluray-1080p" } }, - "languages": [{ "id": 1, "name": "English" }], - "date": "2024-02-10T07:28:45Z", - "eventType": "grabbed", - "data": { - "droppedPath": "/nfs/nzbget/completed/series/Coolness/something.cool.mkv", - "importedPath": "/nfs/tv/Coolness/Season 1/Coolness - S01E01 - Something Cool Bluray-1080p.mkv" - } - }]); - let response: Vec = serde_json::from_value(history_json.clone()).unwrap(); - let expected_history_items = vec![ - SonarrHistoryItem { - id: 123, - episode_id: 1007, - source_title: "z episode".into(), - ..history_item() - }, - SonarrHistoryItem { - id: 456, - episode_id: 2001, - source_title: "A Episode".into(), - ..history_item() - }, - ]; - let (async_server, app_arc, _server) = mock_servarr_api( - RequestMethod::Get, - None, - Some(history_json), - None, - SonarrEvent::GetSeasonHistory(Some((2, 2))), - None, - Some("seriesId=2&seasonNumber=2"), - ) - .await; - app_arc.lock().await.data.sonarr_data.season_details_modal = - Some(SeasonDetailsModal::default()); - app_arc - .lock() - .await - .data - .sonarr_data - .series - .set_items(vec![series()]); - app_arc - .lock() - .await - .data - .sonarr_data - .seasons - .set_items(vec![season()]); - app_arc - .lock() - .await - .data - .sonarr_data - .season_details_modal - .as_mut() - .unwrap() - .season_history - .sort_asc = true; - let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); - - if let SonarrSerdeable::SonarrHistoryItems(history) = network - .handle_sonarr_event(SonarrEvent::GetSeasonHistory(Some((2, 2)))) + .handle_sonarr_event(SonarrEvent::GetSeasonHistory((1, 1))) .await .unwrap() { @@ -3743,7 +3627,7 @@ mod test { None, Some(history_json), None, - SonarrEvent::GetSeasonHistory(None), + SonarrEvent::GetSeasonHistory((1, 1)), None, Some("seriesId=1&seasonNumber=1"), ) @@ -3765,7 +3649,7 @@ mod test { let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); if let SonarrSerdeable::SonarrHistoryItems(history) = network - .handle_sonarr_event(SonarrEvent::GetSeasonHistory(None)) + .handle_sonarr_event(SonarrEvent::GetSeasonHistory((1, 1))) .await .unwrap() {