diff --git a/src/cli/sonarr/edit_command_handler.rs b/src/cli/sonarr/edit_command_handler.rs index 6147f1e..7d06313 100644 --- a/src/cli/sonarr/edit_command_handler.rs +++ b/src/cli/sonarr/edit_command_handler.rs @@ -348,12 +348,13 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrEditCommand> for SonarrEditCommandH language_profile_id, root_folder_path, tags: tag, + tag_input_string: None, clear_tags, }; self .network - .handle_network_event(SonarrEvent::EditSeries(Some(edit_series_params)).into()) + .handle_network_event(SonarrEvent::EditSeries(edit_series_params).into()) .await?; "Series Updated".to_owned() } diff --git a/src/cli/sonarr/edit_command_handler_tests.rs b/src/cli/sonarr/edit_command_handler_tests.rs index 5276f9b..c388ed8 100644 --- a/src/cli/sonarr/edit_command_handler_tests.rs +++ b/src/cli/sonarr/edit_command_handler_tests.rs @@ -742,13 +742,14 @@ mod tests { language_profile_id: Some(1), root_folder_path: Some("/nfs/test".to_owned()), tags: Some(vec![1, 2]), + tag_input_string: None, clear_tags: false, }; let mut mock_network = MockNetworkTrait::new(); mock_network .expect_handle_network_event() .with(eq::( - SonarrEvent::EditSeries(Some(expected_edit_series_params)).into(), + SonarrEvent::EditSeries(expected_edit_series_params).into(), )) .times(1) .returning(|_| { @@ -789,13 +790,14 @@ mod tests { language_profile_id: Some(1), root_folder_path: Some("/nfs/test".to_owned()), tags: Some(vec![1, 2]), + tag_input_string: None, clear_tags: false, }; let mut mock_network = MockNetworkTrait::new(); mock_network .expect_handle_network_event() .with(eq::( - SonarrEvent::EditSeries(Some(expected_edit_series_params)).into(), + SonarrEvent::EditSeries(expected_edit_series_params).into(), )) .times(1) .returning(|_| { @@ -836,13 +838,14 @@ mod tests { language_profile_id: Some(1), root_folder_path: Some("/nfs/test".to_owned()), tags: Some(vec![1, 2]), + tag_input_string: None, clear_tags: false, }; let mut mock_network = MockNetworkTrait::new(); mock_network .expect_handle_network_event() .with(eq::( - SonarrEvent::EditSeries(Some(expected_edit_series_params)).into(), + SonarrEvent::EditSeries(expected_edit_series_params).into(), )) .times(1) .returning(|_| { diff --git a/src/handlers/sonarr_handlers/library/edit_series_handler.rs b/src/handlers/sonarr_handlers/library/edit_series_handler.rs index dbab8c8..4583b02 100644 --- a/src/handlers/sonarr_handlers/library/edit_series_handler.rs +++ b/src/handlers/sonarr_handlers/library/edit_series_handler.rs @@ -2,7 +2,9 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; +use crate::models::servarr_data::sonarr::modals::EditSeriesModal; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_SERIES_BLOCKS}; +use crate::models::sonarr_models::EditSeriesParams; use crate::models::Scrollable; use crate::network::sonarr_network::SonarrEvent; use crate::{handle_text_box_keys, handle_text_box_left_right_keys}; @@ -18,6 +20,78 @@ pub(super) struct EditSeriesHandler<'a, 'b> { context: Option, } +impl<'a, 'b> EditSeriesHandler<'a, 'b> { + fn build_edit_series_params(&mut self) -> EditSeriesParams { + let series_id = self.app.data.sonarr_data.series.current_selection().id; + let tags = self + .app + .data + .sonarr_data + .edit_series_modal + .as_ref() + .unwrap() + .tags + .text + .clone(); + + let params = { + let EditSeriesModal { + monitored, + use_season_folders, + path, + series_type_list, + quality_profile_list, + language_profile_list, + .. + } = self + .app + .data + .sonarr_data + .edit_series_modal + .as_ref() + .unwrap(); + let quality_profile = quality_profile_list.current_selection(); + let quality_profile_id = *self + .app + .data + .sonarr_data + .quality_profile_map + .iter() + .filter(|(_, value)| *value == quality_profile) + .map(|(key, _)| key) + .next() + .unwrap(); + let language_profile = language_profile_list.current_selection(); + let language_profile_id = *self + .app + .data + .sonarr_data + .language_profiles_map + .iter() + .filter(|(_, value)| *value == language_profile) + .map(|(key, _)| key) + .next() + .unwrap(); + + EditSeriesParams { + series_id, + monitored: Some(monitored.unwrap_or_default()), + use_season_folders: Some(use_season_folders.unwrap_or_default()), + series_type: Some(*series_type_list.current_selection()), + quality_profile_id: Some(quality_profile_id), + language_profile_id: Some(language_profile_id), + root_folder_path: Some(path.text.clone()), + tag_input_string: Some(tags), + ..EditSeriesParams::default() + } + }; + + self.app.data.sonarr_data.edit_series_modal = None; + + params + } +} + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditSeriesHandler<'a, 'b> { fn accepts(active_block: ActiveSonarrBlock) -> bool { EDIT_SERIES_BLOCKS.contains(&active_block) @@ -258,7 +332,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditSeriesHandler<'a match self.app.data.sonarr_data.selected_block.get_active_block() { ActiveSonarrBlock::EditSeriesConfirmPrompt => { if self.app.data.sonarr_data.prompt_confirm { - self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::EditSeries(None)); + self.app.data.sonarr_data.prompt_confirm_action = + Some(SonarrEvent::EditSeries(self.build_edit_series_params())); self.app.should_refresh = true; } @@ -392,7 +467,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditSeriesHandler<'a && key == DEFAULT_KEYBINDINGS.confirm.key { self.app.data.sonarr_data.prompt_confirm = true; - self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::EditSeries(None)); + self.app.data.sonarr_data.prompt_confirm_action = + Some(SonarrEvent::EditSeries(self.build_edit_series_params())); self.app.should_refresh = true; self.app.pop_navigation_stack(); diff --git a/src/handlers/sonarr_handlers/library/edit_series_handler_tests.rs b/src/handlers/sonarr_handlers/library/edit_series_handler_tests.rs index 6b73c63..fdc4828 100644 --- a/src/handlers/sonarr_handlers/library/edit_series_handler_tests.rs +++ b/src/handlers/sonarr_handlers/library/edit_series_handler_tests.rs @@ -1,16 +1,18 @@ #[cfg(test)] mod tests { - use pretty_assertions::assert_str_eq; + use bimap::BiMap; + use pretty_assertions::{assert_eq, assert_str_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::edit_series_handler::EditSeriesHandler; + use crate::handlers::sonarr_handlers::sonarr_handler_test_utils::utils::series; use crate::handlers::KeyEventHandler; use crate::models::servarr_data::sonarr::modals::EditSeriesModal; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_SERIES_BLOCKS}; - use crate::models::sonarr_models::SeriesType; + use crate::models::sonarr_models::{EditSeriesParams, Series, SeriesType}; mod test_handle_scroll_up_and_down { use pretty_assertions::assert_eq; @@ -243,6 +245,7 @@ mod tests { } mod test_handle_home_end { + use pretty_assertions::assert_eq; use std::sync::atomic::Ordering; use strum::IntoEnumIterator; @@ -531,6 +534,7 @@ mod tests { } mod test_handle_left_right_action { + use pretty_assertions::assert_eq; use std::sync::atomic::Ordering; use crate::models::servarr_data::sonarr::modals::EditSeriesModal; @@ -770,7 +774,43 @@ mod tests { #[test] fn test_edit_series_confirm_prompt_prompt_confirmation_submit() { let mut app = App::default(); - app.data.sonarr_data.edit_series_modal = Some(EditSeriesModal::default()); + let mut edit_series = EditSeriesModal { + tags: "usenet, testing".to_owned().into(), + path: "/nfs/Test Path".to_owned().into(), + monitored: Some(false), + use_season_folders: Some(false), + ..EditSeriesModal::default() + }; + edit_series + .quality_profile_list + .set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]); + edit_series + .language_profile_list + .set_items(vec!["Any".to_owned(), "English".to_owned()]); + edit_series + .series_type_list + .set_items(Vec::from_iter(SeriesType::iter())); + app.data.sonarr_data.edit_series_modal = Some(edit_series); + app.data.sonarr_data.series.set_items(vec![Series { + monitored: false, + season_folder: false, + ..series() + }]); + app.data.sonarr_data.quality_profile_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "English".to_owned())]); + let expected_edit_series_params = EditSeriesParams { + series_id: 1, + monitored: Some(false), + use_season_folders: Some(false), + series_type: Some(SeriesType::Standard), + quality_profile_id: Some(1111), + language_profile_id: Some(1111), + root_folder_path: Some("/nfs/Test Path".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + ..EditSeriesParams::default() + }; app.push_navigation_stack(ActiveSonarrBlock::Series.into()); app.push_navigation_stack(ActiveSonarrBlock::EditSeriesPrompt.into()); app.data.sonarr_data.prompt_confirm = true; @@ -792,9 +832,9 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); assert_eq!( app.data.sonarr_data.prompt_confirm_action, - Some(SonarrEvent::EditSeries(None)) + Some(SonarrEvent::EditSeries(expected_edit_series_params)) ); - assert!(app.data.sonarr_data.edit_series_modal.is_some()); + assert!(app.data.sonarr_data.edit_series_modal.is_none()); assert!(app.should_refresh); } @@ -1135,6 +1175,7 @@ mod tests { }, network::sonarr_network::SonarrEvent, }; + use pretty_assertions::assert_eq; #[test] fn test_edit_series_path_input_backspace() { @@ -1253,7 +1294,43 @@ mod tests { #[test] fn test_edit_series_confirm_prompt_prompt_confirm() { let mut app = App::default(); - app.data.sonarr_data.edit_series_modal = Some(EditSeriesModal::default()); + let mut edit_series = EditSeriesModal { + tags: "usenet, testing".to_owned().into(), + path: "/nfs/Test Path".to_owned().into(), + monitored: Some(false), + use_season_folders: Some(false), + ..EditSeriesModal::default() + }; + edit_series + .quality_profile_list + .set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]); + edit_series + .language_profile_list + .set_items(vec!["Any".to_owned(), "English".to_owned()]); + edit_series + .series_type_list + .set_items(Vec::from_iter(SeriesType::iter())); + app.data.sonarr_data.edit_series_modal = Some(edit_series); + app.data.sonarr_data.series.set_items(vec![Series { + monitored: false, + season_folder: false, + ..series() + }]); + app.data.sonarr_data.quality_profile_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "English".to_owned())]); + let expected_edit_series_params = EditSeriesParams { + series_id: 1, + monitored: Some(false), + use_season_folders: Some(false), + series_type: Some(SeriesType::Standard), + quality_profile_id: Some(1111), + language_profile_id: Some(1111), + root_folder_path: Some("/nfs/Test Path".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + ..EditSeriesParams::default() + }; app.push_navigation_stack(ActiveSonarrBlock::Series.into()); app.push_navigation_stack(ActiveSonarrBlock::EditSeriesPrompt.into()); app.data.sonarr_data.selected_block = BlockSelectionState::new(EDIT_SERIES_SELECTION_BLOCKS); @@ -1274,9 +1351,9 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); assert_eq!( app.data.sonarr_data.prompt_confirm_action, - Some(SonarrEvent::EditSeries(None)) + Some(SonarrEvent::EditSeries(expected_edit_series_params)) ); - assert!(app.data.sonarr_data.edit_series_modal.is_some()); + assert!(app.data.sonarr_data.edit_series_modal.is_none()); assert!(app.should_refresh); } } @@ -1292,6 +1369,59 @@ mod tests { }); } + #[test] + fn test_build_edit_series_params() { + let mut app = App::default(); + let mut edit_series = EditSeriesModal { + tags: "usenet, testing".to_owned().into(), + path: "/nfs/Test Path".to_owned().into(), + monitored: Some(false), + use_season_folders: Some(false), + ..EditSeriesModal::default() + }; + edit_series + .quality_profile_list + .set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]); + edit_series + .language_profile_list + .set_items(vec!["Any".to_owned(), "English".to_owned()]); + edit_series + .series_type_list + .set_items(Vec::from_iter(SeriesType::iter())); + app.data.sonarr_data.edit_series_modal = Some(edit_series); + app.data.sonarr_data.series.set_items(vec![Series { + monitored: false, + season_folder: false, + ..series() + }]); + app.data.sonarr_data.quality_profile_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "English".to_owned())]); + let expected_edit_series_params = EditSeriesParams { + series_id: 1, + monitored: Some(false), + use_season_folders: Some(false), + series_type: Some(SeriesType::Standard), + quality_profile_id: Some(1111), + language_profile_id: Some(1111), + root_folder_path: Some("/nfs/Test Path".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + ..EditSeriesParams::default() + }; + + let edit_series_params = EditSeriesHandler::with( + DEFAULT_KEYBINDINGS.esc.key, + &mut app, + ActiveSonarrBlock::EditSeriesPrompt, + None, + ) + .build_edit_series_params(); + + assert_eq!(edit_series_params, expected_edit_series_params); + assert!(app.data.sonarr_data.edit_series_modal.is_none()); + } + #[test] fn test_edit_series_handler_is_not_ready_when_loading() { let mut app = App::default(); diff --git a/src/models/sonarr_models.rs b/src/models/sonarr_models.rs index 8fbe1f5..5606a73 100644 --- a/src/models/sonarr_models.rs +++ b/src/models/sonarr_models.rs @@ -194,6 +194,8 @@ pub struct EditSeriesParams { pub series_type: Option, pub root_folder_path: Option, pub tags: Option>, + #[serde(skip_serializing, skip_deserializing)] + pub tag_input_string: Option, pub clear_tags: bool, } diff --git a/src/network/sonarr_network.rs b/src/network/sonarr_network.rs index 41a76b0..a343ce5 100644 --- a/src/network/sonarr_network.rs +++ b/src/network/sonarr_network.rs @@ -12,7 +12,7 @@ use crate::{ servarr_data::{ modals::IndexerTestResultModalItem, sonarr::{ - modals::{EditSeriesModal, EpisodeDetailsModal, SeasonDetailsModal}, + modals::{EpisodeDetailsModal, SeasonDetailsModal}, sonarr_data::ActiveSonarrBlock, }, }, @@ -52,7 +52,7 @@ pub enum SonarrEvent { DownloadRelease(SonarrReleaseDownloadBody), EditAllIndexerSettings(IndexerSettings), EditIndexer(EditIndexerParams), - EditSeries(Option), + EditSeries(EditSeriesParams), GetAllIndexerSettings, GetBlocklist, GetDownloads, @@ -840,19 +840,17 @@ impl<'a, 'b> Network<'a, 'b> { .await } - async fn edit_sonarr_series( - &mut self, - edit_series_params: Option, - ) -> Result<()> { + async fn edit_sonarr_series(&mut self, mut edit_series_params: EditSeriesParams) -> Result<()> { info!("Editing Sonarr series"); + if let Some(tag_input_string) = edit_series_params.tag_input_string.as_ref() { + let tag_ids_vec = self + .extract_and_add_sonarr_tag_ids_vec(tag_input_string.clone()) + .await; + edit_series_params.tags = Some(tag_ids_vec); + } let detail_event = SonarrEvent::GetSeriesDetails(None); - let event = SonarrEvent::EditSeries(None); - - let (series_id, _) = if let Some(ref params) = edit_series_params { - self.extract_series_id(Some(params.series_id)).await - } else { - self.extract_series_id(None).await - }; + let event = SonarrEvent::EditSeries(edit_series_params.clone()); + let series_id = edit_series_params.series_id; info!("Fetching series details for series with ID: {series_id}"); let request_props = self @@ -884,44 +882,44 @@ impl<'a, 'b> Network<'a, 'b> { language_profile_id, root_folder_path, tags, - ) = if let Some(params) = edit_series_params { - let monitored = params.monitored.unwrap_or( + ) = { + let monitored = edit_series_params.monitored.unwrap_or( detailed_series_body["monitored"] .as_bool() .expect("Unable to deserialize 'monitored'"), ); - let use_season_folders = params.use_season_folders.unwrap_or( + let use_season_folders = edit_series_params.use_season_folders.unwrap_or( detailed_series_body["seasonFolder"] .as_bool() .expect("Unable to deserialize 'season_folder'"), ); - let series_type = params + let series_type = edit_series_params .series_type .unwrap_or_else(|| { serde_json::from_value(detailed_series_body["seriesType"].clone()) .expect("Unable to deserialize 'seriesType'") }) .to_string(); - let quality_profile_id = params.quality_profile_id.unwrap_or_else(|| { + let quality_profile_id = edit_series_params.quality_profile_id.unwrap_or_else(|| { detailed_series_body["qualityProfileId"] .as_i64() .expect("Unable to deserialize 'qualityProfileId'") }); - let language_profile_id = params.language_profile_id.unwrap_or_else(|| { + let language_profile_id = edit_series_params.language_profile_id.unwrap_or_else(|| { detailed_series_body["languageProfileId"] .as_i64() .expect("Unable to deserialize 'languageProfileId'") }); - let root_folder_path = params.root_folder_path.unwrap_or_else(|| { + let root_folder_path = edit_series_params.root_folder_path.unwrap_or_else(|| { detailed_series_body["path"] .as_str() .expect("Unable to deserialize 'path'") .to_owned() }); - let tags = if params.clear_tags { + let tags = if edit_series_params.clear_tags { vec![] } else { - params.tags.unwrap_or( + edit_series_params.tags.unwrap_or( detailed_series_body["tags"] .as_array() .expect("Unable to deserialize 'tags'") @@ -940,67 +938,6 @@ impl<'a, 'b> Network<'a, 'b> { root_folder_path, tags, ) - } else { - let tags = self - .app - .lock() - .await - .data - .sonarr_data - .edit_series_modal - .as_ref() - .unwrap() - .tags - .text - .clone(); - let tag_ids_vec = self.extract_and_add_sonarr_tag_ids_vec(tags).await; - let mut app = self.app.lock().await; - - let params = { - let EditSeriesModal { - monitored, - use_season_folders, - path, - series_type_list, - quality_profile_list, - language_profile_list, - .. - } = app.data.sonarr_data.edit_series_modal.as_ref().unwrap(); - let quality_profile = quality_profile_list.current_selection(); - let quality_profile_id = *app - .data - .sonarr_data - .quality_profile_map - .iter() - .filter(|(_, value)| *value == quality_profile) - .map(|(key, _)| key) - .next() - .unwrap(); - let language_profile = language_profile_list.current_selection(); - let language_profile_id = *app - .data - .sonarr_data - .language_profiles_map - .iter() - .filter(|(_, value)| *value == language_profile) - .map(|(key, _)| key) - .next() - .unwrap(); - - ( - monitored.unwrap_or_default(), - use_season_folders.unwrap_or_default(), - series_type_list.current_selection().to_string(), - quality_profile_id, - language_profile_id, - path.text.clone(), - tag_ids_vec, - ) - }; - - app.data.sonarr_data.edit_series_modal = None; - - params }; *detailed_series_body.get_mut("monitored").unwrap() = json!(monitored); diff --git a/src/network/sonarr_network_tests.rs b/src/network/sonarr_network_tests.rs index 30ba7f1..76183ff 100644 --- a/src/network/sonarr_network_tests.rs +++ b/src/network/sonarr_network_tests.rs @@ -11,7 +11,6 @@ mod test { use rstest::rstest; use serde_json::json; use serde_json::{Number, Value}; - use strum::IntoEnumIterator; use tokio::sync::Mutex; use tokio_util::sync::CancellationToken; @@ -24,7 +23,7 @@ mod test { use crate::models::radarr_models::IndexerTestResult; use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::sonarr::modals::{ - AddSeriesModal, EditSeriesModal, EpisodeDetailsModal, SeasonDetailsModal, + AddSeriesModal, EpisodeDetailsModal, SeasonDetailsModal, }; use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock; use crate::models::servarr_models::{ @@ -163,7 +162,7 @@ mod test { SonarrEvent::ListSeries, SonarrEvent::GetSeriesDetails(None), SonarrEvent::DeleteSeries(DeleteSeriesParams::default()), - SonarrEvent::EditSeries(None), + SonarrEvent::EditSeries(EditSeriesParams::default()), SonarrEvent::ToggleSeasonMonitoring(None) )] event: SonarrEvent, @@ -1323,6 +1322,17 @@ mod test { *expected_body.get_mut("languageProfileId").unwrap() = json!(1111); *expected_body.get_mut("path").unwrap() = json!("/nfs/Test Path"); *expected_body.get_mut("tags").unwrap() = json!([1, 2]); + let edit_series_params = EditSeriesParams { + series_id: 1, + monitored: Some(false), + use_season_folders: Some(false), + series_type: Some(SeriesType::Standard), + quality_profile_id: Some(1111), + language_profile_id: Some(1111), + root_folder_path: Some("/nfs/Test Path".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + ..EditSeriesParams::default() + }; let (async_details_server, app_arc, mut server) = mock_servarr_api( RequestMethod::Get, @@ -1337,60 +1347,33 @@ mod test { let async_edit_server = server .mock( "PUT", - format!("/api/v3{}/1", SonarrEvent::EditSeries(None).resource()).as_str(), + format!( + "/api/v3{}/1", + SonarrEvent::EditSeries(edit_series_params.clone()).resource() + ) + .as_str(), ) .with_status(202) .match_header("X-Api-Key", "test1234") .match_body(Matcher::Json(expected_body)) .create_async() .await; - { - let mut app = app_arc.lock().await; - app.data.sonarr_data.tags_map = - BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]); - let mut edit_series = EditSeriesModal { - tags: "usenet, testing".to_owned().into(), - path: "/nfs/Test Path".to_owned().into(), - monitored: Some(false), - use_season_folders: Some(false), - ..EditSeriesModal::default() - }; - edit_series - .quality_profile_list - .set_items(vec!["Any".to_owned(), "HD - 1080p".to_owned()]); - edit_series - .language_profile_list - .set_items(vec!["Any".to_owned(), "English".to_owned()]); - edit_series - .series_type_list - .set_items(Vec::from_iter(SeriesType::iter())); - app.data.sonarr_data.edit_series_modal = Some(edit_series); - app.data.sonarr_data.series.set_items(vec![Series { - monitored: false, - season_folder: false, - ..series() - }]); - app.data.sonarr_data.quality_profile_map = - BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]); - app.data.sonarr_data.language_profiles_map = - BiMap::from_iter([(1111, "Any".to_owned()), (2222, "English".to_owned())]); - } + app_arc.lock().await.data.sonarr_data.tags_map = + BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); assert!(network - .handle_sonarr_event(SonarrEvent::EditSeries(None)) + .handle_sonarr_event(SonarrEvent::EditSeries(edit_series_params)) .await .is_ok()); async_details_server.assert_async().await; async_edit_server.assert_async().await; - - let app = app_arc.lock().await; - assert!(app.data.sonarr_data.edit_series_modal.is_none()); } #[tokio::test] - async fn test_handle_edit_series_event_uses_provided_parameters() { + async fn test_handle_edit_series_event_does_not_overwrite_tag_ids_vec_when_tag_input_string_is_none( + ) { let mut expected_body: Value = serde_json::from_str(SERIES_JSON).unwrap(); *expected_body.get_mut("monitored").unwrap() = json!(false); *expected_body.get_mut("seasonFolder").unwrap() = json!(false); @@ -1399,27 +1382,6 @@ mod test { *expected_body.get_mut("languageProfileId").unwrap() = json!(1111); *expected_body.get_mut("path").unwrap() = json!("/nfs/Test Path"); *expected_body.get_mut("tags").unwrap() = json!([1, 2]); - - let (async_details_server, app_arc, mut server) = mock_servarr_api( - RequestMethod::Get, - None, - Some(serde_json::from_str(SERIES_JSON).unwrap()), - None, - SonarrEvent::GetSeriesDetails(None), - Some("/1"), - None, - ) - .await; - let async_edit_server = server - .mock( - "PUT", - format!("/api/v3{}/1", SonarrEvent::EditSeries(None).resource()).as_str(), - ) - .with_status(202) - .match_header("X-Api-Key", "test1234") - .match_body(Matcher::Json(expected_body)) - .create_async() - .await; let edit_series_params = EditSeriesParams { series_id: 1, monitored: Some(false), @@ -1431,10 +1393,37 @@ mod test { tags: Some(vec![1, 2]), ..EditSeriesParams::default() }; + + let (async_details_server, app_arc, mut server) = mock_servarr_api( + RequestMethod::Get, + None, + Some(serde_json::from_str(SERIES_JSON).unwrap()), + None, + SonarrEvent::GetSeriesDetails(None), + Some("/1"), + None, + ) + .await; + let async_edit_server = server + .mock( + "PUT", + format!( + "/api/v3{}/1", + SonarrEvent::EditSeries(edit_series_params.clone()).resource() + ) + .as_str(), + ) + .with_status(202) + .match_header("X-Api-Key", "test1234") + .match_body(Matcher::Json(expected_body)) + .create_async() + .await; + app_arc.lock().await.data.sonarr_data.tags_map = + BiMap::from_iter([(1, "usenet".to_owned()), (2, "testing".to_owned())]); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); assert!(network - .handle_sonarr_event(SonarrEvent::EditSeries(Some(edit_series_params))) + .handle_sonarr_event(SonarrEvent::EditSeries(edit_series_params)) .await .is_ok()); @@ -1443,7 +1432,11 @@ mod test { } #[tokio::test] - async fn test_handle_edit_series_event_uses_provided_parameters_defaults_to_previous_values() { + async fn test_handle_edit_series_event_defaults_to_previous_values() { + let edit_series_params = EditSeriesParams { + series_id: 1, + ..EditSeriesParams::default() + }; let expected_body: Value = serde_json::from_str(SERIES_JSON).unwrap(); let (async_details_server, app_arc, mut server) = mock_servarr_api( RequestMethod::Get, @@ -1458,21 +1451,21 @@ mod test { let async_edit_server = server .mock( "PUT", - format!("/api/v3{}/1", SonarrEvent::EditSeries(None).resource()).as_str(), + format!( + "/api/v3{}/1", + SonarrEvent::EditSeries(edit_series_params.clone()).resource() + ) + .as_str(), ) .with_status(202) .match_header("X-Api-Key", "test1234") .match_body(Matcher::Json(expected_body)) .create_async() .await; - let edit_series_params = EditSeriesParams { - series_id: 1, - ..EditSeriesParams::default() - }; let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); assert!(network - .handle_sonarr_event(SonarrEvent::EditSeries(Some(edit_series_params))) + .handle_sonarr_event(SonarrEvent::EditSeries(edit_series_params)) .await .is_ok()); @@ -1481,8 +1474,7 @@ mod test { } #[tokio::test] - async fn test_handle_edit_series_event_uses_provided_parameters_returns_empty_tags_vec_when_clear_tags_is_true( - ) { + async fn test_handle_edit_series_event_returns_empty_tags_vec_when_clear_tags_is_true() { let mut expected_body: Value = serde_json::from_str(SERIES_JSON).unwrap(); *expected_body.get_mut("tags").unwrap() = json!([]); @@ -1496,25 +1488,29 @@ mod test { None, ) .await; + let edit_series_params = EditSeriesParams { + series_id: 1, + clear_tags: true, + ..EditSeriesParams::default() + }; let async_edit_server = server .mock( "PUT", - format!("/api/v3{}/1", SonarrEvent::EditSeries(None).resource()).as_str(), + format!( + "/api/v3{}/1", + SonarrEvent::EditSeries(edit_series_params.clone()).resource() + ) + .as_str(), ) .with_status(202) .match_header("X-Api-Key", "test1234") .match_body(Matcher::Json(expected_body)) .create_async() .await; - let edit_series_params = EditSeriesParams { - series_id: 1, - clear_tags: true, - ..EditSeriesParams::default() - }; let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); assert!(network - .handle_sonarr_event(SonarrEvent::EditSeries(Some(edit_series_params))) + .handle_sonarr_event(SonarrEvent::EditSeries(edit_series_params)) .await .is_ok());