diff --git a/src/cli/sonarr/delete_command_handler.rs b/src/cli/sonarr/delete_command_handler.rs index 84f0198..a497305 100644 --- a/src/cli/sonarr/delete_command_handler.rs +++ b/src/cli/sonarr/delete_command_handler.rs @@ -138,7 +138,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrDeleteCommand> for SonarrDeleteComm }; let resp = self .network - .handle_network_event(SonarrEvent::DeleteSeries(Some(delete_series_params)).into()) + .handle_network_event(SonarrEvent::DeleteSeries(delete_series_params).into()) .await?; serde_json::to_string_pretty(&resp)? } diff --git a/src/cli/sonarr/delete_command_handler_tests.rs b/src/cli/sonarr/delete_command_handler_tests.rs index 531a3c3..a0d32e2 100644 --- a/src/cli/sonarr/delete_command_handler_tests.rs +++ b/src/cli/sonarr/delete_command_handler_tests.rs @@ -440,7 +440,7 @@ mod tests { mock_network .expect_handle_network_event() .with(eq::( - SonarrEvent::DeleteSeries(Some(expected_delete_series_params)).into(), + SonarrEvent::DeleteSeries(expected_delete_series_params).into(), )) .times(1) .returning(|_| { diff --git a/src/handlers/sonarr_handlers/library/delete_series_handler.rs b/src/handlers/sonarr_handlers/library/delete_series_handler.rs index a9fbeff..51326c2 100644 --- a/src/handlers/sonarr_handlers/library/delete_series_handler.rs +++ b/src/handlers/sonarr_handlers/library/delete_series_handler.rs @@ -1,9 +1,10 @@ +use crate::models::sonarr_models::DeleteSeriesParams; +use crate::network::sonarr_network::SonarrEvent; use crate::{ app::{key_binding::DEFAULT_KEYBINDINGS, App}, event::Key, handlers::{handle_prompt_toggle, KeyEventHandler}, models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DELETE_SERIES_BLOCKS}, - network::sonarr_network::SonarrEvent, }; #[cfg(test)] @@ -17,6 +18,21 @@ pub(super) struct DeleteSeriesHandler<'a, 'b> { _context: Option, } +impl<'a, 'b> DeleteSeriesHandler<'a, 'b> { + fn build_delete_series_params(&mut self) -> DeleteSeriesParams { + let id = self.app.data.sonarr_data.series.current_selection().id; + let delete_series_files = self.app.data.sonarr_data.delete_series_files; + let add_list_exclusion = self.app.data.sonarr_data.add_list_exclusion; + self.app.data.sonarr_data.reset_delete_series_preferences(); + + DeleteSeriesParams { + id, + delete_series_files, + add_list_exclusion, + } + } +} + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for DeleteSeriesHandler<'a, 'b> { fn accepts(active_block: ActiveSonarrBlock) -> bool { DELETE_SERIES_BLOCKS.contains(&active_block) @@ -73,7 +89,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for DeleteSeriesHandler< match self.app.data.sonarr_data.selected_block.get_active_block() { ActiveSonarrBlock::DeleteSeriesConfirmPrompt => { if self.app.data.sonarr_data.prompt_confirm { - self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::DeleteSeries(None)); + self.app.data.sonarr_data.prompt_confirm_action = + Some(SonarrEvent::DeleteSeries(self.build_delete_series_params())); self.app.should_refresh = true; } else { self.app.data.sonarr_data.reset_delete_series_preferences(); @@ -109,7 +126,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for DeleteSeriesHandler< && self.key == DEFAULT_KEYBINDINGS.confirm.key { self.app.data.sonarr_data.prompt_confirm = true; - self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::DeleteSeries(None)); + self.app.data.sonarr_data.prompt_confirm_action = + Some(SonarrEvent::DeleteSeries(self.build_delete_series_params())); self.app.should_refresh = true; self.app.pop_navigation_stack(); diff --git a/src/handlers/sonarr_handlers/library/delete_series_handler_tests.rs b/src/handlers/sonarr_handlers/library/delete_series_handler_tests.rs index 13469da..cdaaae4 100644 --- a/src/handlers/sonarr_handlers/library/delete_series_handler_tests.rs +++ b/src/handlers/sonarr_handlers/library/delete_series_handler_tests.rs @@ -1,13 +1,16 @@ #[cfg(test)] mod tests { + use pretty_assertions::assert_eq; use strum::IntoEnumIterator; use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::sonarr_handlers::library::delete_series_handler::DeleteSeriesHandler; + use crate::handlers::sonarr_handlers::sonarr_handler_test_utils::utils::series; use crate::handlers::KeyEventHandler; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DELETE_SERIES_BLOCKS}; + use crate::models::sonarr_models::DeleteSeriesParams; mod test_handle_scroll_up_and_down { use pretty_assertions::assert_eq; @@ -132,6 +135,12 @@ mod tests { app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.delete_series_files = true; app.data.sonarr_data.add_list_exclusion = true; + app.data.sonarr_data.series.set_items(vec![series()]); + let expected_delete_series_params = DeleteSeriesParams { + id: 1, + delete_series_files: true, + add_list_exclusion: true, + }; app.data.sonarr_data.selected_block = BlockSelectionState::new(DELETE_SERIES_SELECTION_BLOCKS); app @@ -151,12 +160,12 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); assert_eq!( app.data.sonarr_data.prompt_confirm_action, - Some(SonarrEvent::DeleteSeries(None)) + Some(SonarrEvent::DeleteSeries(expected_delete_series_params)) ); assert!(app.should_refresh); assert!(app.data.sonarr_data.prompt_confirm); - assert!(app.data.sonarr_data.delete_series_files); - assert!(app.data.sonarr_data.add_list_exclusion); + assert!(!app.data.sonarr_data.delete_series_files); + assert!(!app.data.sonarr_data.add_list_exclusion); } #[test] @@ -222,6 +231,7 @@ mod tests { mod test_handle_esc { use super::*; + use pretty_assertions::assert_eq; use rstest::rstest; const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; @@ -258,6 +268,7 @@ mod tests { }, network::sonarr_network::SonarrEvent, }; + use pretty_assertions::assert_eq; use super::*; @@ -268,6 +279,12 @@ mod tests { app.push_navigation_stack(ActiveSonarrBlock::DeleteSeriesPrompt.into()); app.data.sonarr_data.delete_series_files = true; app.data.sonarr_data.add_list_exclusion = true; + app.data.sonarr_data.series.set_items(vec![series()]); + let expected_delete_series_params = DeleteSeriesParams { + id: 1, + delete_series_files: true, + add_list_exclusion: true, + }; app.data.sonarr_data.selected_block = BlockSelectionState::new(DELETE_SERIES_SELECTION_BLOCKS); app @@ -287,12 +304,12 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); assert_eq!( app.data.sonarr_data.prompt_confirm_action, - Some(SonarrEvent::DeleteSeries(None)) + Some(SonarrEvent::DeleteSeries(expected_delete_series_params)) ); assert!(app.should_refresh); assert!(app.data.sonarr_data.prompt_confirm); - assert!(app.data.sonarr_data.delete_series_files); - assert!(app.data.sonarr_data.add_list_exclusion); + assert!(!app.data.sonarr_data.delete_series_files); + assert!(!app.data.sonarr_data.add_list_exclusion); } } @@ -307,6 +324,31 @@ mod tests { }); } + #[test] + fn test_build_delete_series_params() { + let mut app = App::default(); + app.data.sonarr_data.series.set_items(vec![series()]); + app.data.sonarr_data.delete_series_files = true; + app.data.sonarr_data.add_list_exclusion = true; + let expected_delete_series_params = DeleteSeriesParams { + id: 1, + delete_series_files: true, + add_list_exclusion: true, + }; + + let delete_series_params = DeleteSeriesHandler::with( + DEFAULT_KEYBINDINGS.esc.key, + &mut app, + ActiveSonarrBlock::DeleteSeriesPrompt, + None, + ) + .build_delete_series_params(); + + assert_eq!(delete_series_params, expected_delete_series_params); + assert!(!app.data.sonarr_data.delete_series_files); + assert!(!app.data.sonarr_data.add_list_exclusion); + } + #[test] fn test_delete_series_handler_not_ready_when_loading() { let mut app = App::default(); diff --git a/src/models/sonarr_models.rs b/src/models/sonarr_models.rs index 010c0ef..8fbe1f5 100644 --- a/src/models/sonarr_models.rs +++ b/src/models/sonarr_models.rs @@ -97,7 +97,7 @@ pub struct BlocklistResponse { pub records: Vec, } -#[derive(Serialize, Deserialize, Debug, Clone, Eq, PartialEq)] +#[derive(Serialize, Deserialize, Debug, Default, Clone, Eq, PartialEq)] #[serde(rename_all = "lowercase")] pub struct DeleteSeriesParams { pub id: i64, diff --git a/src/network/sonarr_network.rs b/src/network/sonarr_network.rs index 229f15b..80b6619 100644 --- a/src/network/sonarr_network.rs +++ b/src/network/sonarr_network.rs @@ -47,7 +47,7 @@ pub enum SonarrEvent { DeleteEpisodeFile(i64), DeleteIndexer(i64), DeleteRootFolder(i64), - DeleteSeries(Option), + DeleteSeries(DeleteSeriesParams), DeleteTag(i64), DownloadRelease(SonarrReleaseDownloadBody), EditAllIndexerSettings(Option), @@ -554,53 +554,31 @@ impl<'a, 'b> Network<'a, 'b> { .await } - async fn delete_series( - &mut self, - delete_series_params: Option, - ) -> Result<()> { - let event = SonarrEvent::DeleteSeries(None); - let (series_id, delete_files, add_import_exclusion) = if let Some(params) = delete_series_params - { - ( - params.id, - params.delete_series_files, - params.add_list_exclusion, - ) - } else { - let (series_id, _) = self.extract_series_id(None).await; - let delete_files = self.app.lock().await.data.sonarr_data.delete_series_files; - let add_import_exclusion = self.app.lock().await.data.sonarr_data.add_list_exclusion; + async fn delete_series(&mut self, delete_series_params: DeleteSeriesParams) -> Result<()> { + let event = SonarrEvent::DeleteSeries(delete_series_params.clone()); + let DeleteSeriesParams { + id, + delete_series_files, + add_list_exclusion, + } = delete_series_params; - (series_id, delete_files, add_import_exclusion) - }; - - info!("Deleting Sonarr series with ID: {series_id} with deleteFiles={delete_files} and addImportExclusion={add_import_exclusion}"); + info!("Deleting Sonarr series with ID: {id} with deleteFiles={delete_series_files} and addImportExclusion={add_list_exclusion}"); let request_props = self .request_props_from( event, RequestMethod::Delete, None::<()>, - Some(format!("/{series_id}")), + Some(format!("/{id}")), Some(format!( - "deleteFiles={delete_files}&addImportExclusion={add_import_exclusion}" + "deleteFiles={delete_series_files}&addImportExclusion={add_list_exclusion}" )), ) .await; - let resp = self - .handle_request::<(), ()>(request_props, |_, _| ()) - .await; - self - .app - .lock() + .handle_request::<(), ()>(request_props, |_, _| ()) .await - .data - .sonarr_data - .reset_delete_series_preferences(); - - resp } async fn delete_sonarr_tag(&mut self, id: i64) -> Result<()> { diff --git a/src/network/sonarr_network_tests.rs b/src/network/sonarr_network_tests.rs index 5ea38e5..7cc1dfc 100644 --- a/src/network/sonarr_network_tests.rs +++ b/src/network/sonarr_network_tests.rs @@ -162,7 +162,7 @@ mod test { SonarrEvent::AddSeries(AddSeriesBody::default()), SonarrEvent::ListSeries, SonarrEvent::GetSeriesDetails(None), - SonarrEvent::DeleteSeries(None), + SonarrEvent::DeleteSeries(DeleteSeriesParams::default()), SonarrEvent::EditSeries(None), SonarrEvent::ToggleSeasonMonitoring(None) )] @@ -665,61 +665,29 @@ mod test { #[tokio::test] async fn test_handle_delete_series_event() { - let (async_server, app_arc, _server) = mock_servarr_api( - RequestMethod::Delete, - None, - None, - None, - SonarrEvent::DeleteSeries(None), - Some("/1"), - Some("deleteFiles=true&addImportExclusion=true"), - ) - .await; - { - let mut app = app_arc.lock().await; - app.data.sonarr_data.series.set_items(vec![series()]); - app.data.sonarr_data.delete_series_files = true; - app.data.sonarr_data.add_list_exclusion = true; - } - let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); - - assert!(network - .handle_sonarr_event(SonarrEvent::DeleteSeries(None)) - .await - .is_ok()); - - async_server.assert_async().await; - assert!(!app_arc.lock().await.data.sonarr_data.delete_series_files); - assert!(!app_arc.lock().await.data.sonarr_data.add_list_exclusion); - } - - #[tokio::test] - async fn test_handle_delete_series_event_use_provided_params() { - let (async_server, app_arc, _server) = mock_servarr_api( - RequestMethod::Delete, - None, - None, - None, - SonarrEvent::DeleteSeries(None), - Some("/1"), - Some("deleteFiles=true&addImportExclusion=true"), - ) - .await; - let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); let delete_series_params = DeleteSeriesParams { id: 1, delete_series_files: true, add_list_exclusion: true, }; + let (async_server, app_arc, _server) = mock_servarr_api( + RequestMethod::Delete, + None, + None, + None, + SonarrEvent::DeleteSeries(delete_series_params.clone()), + Some("/1"), + Some("deleteFiles=true&addImportExclusion=true"), + ) + .await; + let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); assert!(network - .handle_sonarr_event(SonarrEvent::DeleteSeries(Some(delete_series_params))) + .handle_sonarr_event(SonarrEvent::DeleteSeries(delete_series_params)) .await .is_ok()); async_server.assert_async().await; - assert!(!app_arc.lock().await.data.sonarr_data.delete_series_files); - assert!(!app_arc.lock().await.data.sonarr_data.add_list_exclusion); } #[tokio::test]