diff --git a/src/cli/sonarr/edit_command_handler.rs b/src/cli/sonarr/edit_command_handler.rs index 05d3716..6147f1e 100644 --- a/src/cli/sonarr/edit_command_handler.rs +++ b/src/cli/sonarr/edit_command_handler.rs @@ -319,7 +319,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrEditCommand> for SonarrEditCommandH self .network - .handle_network_event(SonarrEvent::EditIndexer(Some(edit_indexer_params)).into()) + .handle_network_event(SonarrEvent::EditIndexer(edit_indexer_params).into()) .await?; "Indexer updated".to_owned() } diff --git a/src/cli/sonarr/edit_command_handler_tests.rs b/src/cli/sonarr/edit_command_handler_tests.rs index 9d2a429..5276f9b 100644 --- a/src/cli/sonarr/edit_command_handler_tests.rs +++ b/src/cli/sonarr/edit_command_handler_tests.rs @@ -697,7 +697,7 @@ mod tests { mock_network .expect_handle_network_event() .with(eq::( - SonarrEvent::EditIndexer(Some(expected_edit_indexer_params)).into(), + SonarrEvent::EditIndexer(expected_edit_indexer_params).into(), )) .times(1) .returning(|_| { diff --git a/src/handlers/sonarr_handlers/indexers/edit_indexer_handler.rs b/src/handlers/sonarr_handlers/indexers/edit_indexer_handler.rs index ca41e51..7e5cf98 100644 --- a/src/handlers/sonarr_handlers/indexers/edit_indexer_handler.rs +++ b/src/handlers/sonarr_handlers/indexers/edit_indexer_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::modals::EditIndexerModal; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS}; +use crate::models::servarr_models::EditIndexerParams; use crate::network::sonarr_network::SonarrEvent; use crate::{handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys}; @@ -17,6 +19,60 @@ pub(super) struct EditIndexerHandler<'a, 'b> { _context: Option, } +impl<'a, 'b> EditIndexerHandler<'a, 'b> { + fn build_edit_indexer_params(&mut self) -> EditIndexerParams { + let indexer_id = self.app.data.sonarr_data.indexers.current_selection().id; + let tags = self + .app + .data + .sonarr_data + .edit_indexer_modal + .as_ref() + .unwrap() + .tags + .text + .clone(); + let params = { + let EditIndexerModal { + name, + enable_rss, + enable_automatic_search, + enable_interactive_search, + url, + api_key, + seed_ratio, + priority, + .. + } = self + .app + .data + .sonarr_data + .edit_indexer_modal + .as_ref() + .unwrap(); + + EditIndexerParams { + indexer_id, + name: Some(name.text.clone()), + enable_rss: Some(enable_rss.unwrap_or_default()), + enable_automatic_search: Some(enable_automatic_search.unwrap_or_default()), + enable_interactive_search: Some(enable_interactive_search.unwrap_or_default()), + url: Some(url.text.clone()), + api_key: Some(api_key.text.clone()), + seed_ratio: Some(seed_ratio.text.clone()), + tags: None, + tag_input_string: Some(tags), + priority: Some(*priority), + clear_tags: false, + } + }; + + self.app.data.sonarr_data.edit_indexer_modal = None; + + params + } +} + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditIndexerHandler<'a, 'b> { fn accepts(active_block: ActiveSonarrBlock) -> bool { EDIT_INDEXER_BLOCKS.contains(&active_block) @@ -297,12 +353,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditIndexerHandler<' let selected_block = self.app.data.sonarr_data.selected_block.get_active_block(); match selected_block { ActiveSonarrBlock::EditIndexerConfirmPrompt => { - let sonarr_data = &mut self.app.data.sonarr_data; - if sonarr_data.prompt_confirm { - sonarr_data.prompt_confirm_action = Some(SonarrEvent::EditIndexer(None)); + if self.app.data.sonarr_data.prompt_confirm { + self.app.data.sonarr_data.prompt_confirm_action = + Some(SonarrEvent::EditIndexer(self.build_edit_indexer_params())); self.app.should_refresh = true; } else { - sonarr_data.edit_indexer_modal = None; + self.app.data.sonarr_data.edit_indexer_modal = None; } self.app.pop_navigation_stack(); @@ -464,7 +520,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditIndexerHandler<' && self.key == DEFAULT_KEYBINDINGS.confirm.key { self.app.data.sonarr_data.prompt_confirm = true; - self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::EditIndexer(None)); + self.app.data.sonarr_data.prompt_confirm_action = + Some(SonarrEvent::EditIndexer(self.build_edit_indexer_params())); self.app.should_refresh = true; self.app.pop_navigation_stack(); diff --git a/src/handlers/sonarr_handlers/indexers/edit_indexer_handler_tests.rs b/src/handlers/sonarr_handlers/indexers/edit_indexer_handler_tests.rs index 1008ec2..100658e 100644 --- a/src/handlers/sonarr_handlers/indexers/edit_indexer_handler_tests.rs +++ b/src/handlers/sonarr_handlers/indexers/edit_indexer_handler_tests.rs @@ -4,9 +4,12 @@ mod tests { use crate::app::App; use crate::event::Key; use crate::handlers::sonarr_handlers::indexers::edit_indexer_handler::EditIndexerHandler; + use crate::handlers::sonarr_handlers::sonarr_handler_test_utils::utils::indexer; use crate::handlers::KeyEventHandler; use crate::models::servarr_data::modals::EditIndexerModal; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS}; + use crate::models::servarr_models::EditIndexerParams; + use pretty_assertions::assert_eq; use strum::IntoEnumIterator; mod test_handle_scroll_up_and_down { @@ -896,7 +899,32 @@ mod tests { .sonarr_data .selected_block .set_index(0, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1); - app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); + let edit_indexer_modal = EditIndexerModal { + name: "Test Update".into(), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: "https://localhost:9696/1/".into(), + api_key: "test1234".into(), + seed_ratio: "1.3".into(), + tags: "usenet, testing".into(), + priority: 0, + }; + app.data.sonarr_data.edit_indexer_modal = Some(edit_indexer_modal); + app.data.sonarr_data.indexers.set_items(vec![indexer()]); + let expected_edit_indexer_params = EditIndexerParams { + indexer_id: 1, + name: Some("Test Update".to_owned()), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: Some("https://localhost:9696/1/".to_owned()), + api_key: Some("test1234".to_owned()), + seed_ratio: Some("1.3".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + priority: Some(0), + ..EditIndexerParams::default() + }; app.data.sonarr_data.prompt_confirm = true; EditIndexerHandler::with( @@ -908,11 +936,11 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Indexers.into()); - assert!(app.data.sonarr_data.edit_indexer_modal.is_some()); + assert!(app.data.sonarr_data.edit_indexer_modal.is_none()); assert!(app.should_refresh); assert_eq!( app.data.sonarr_data.prompt_confirm_action, - Some(SonarrEvent::EditIndexer(None)) + Some(SonarrEvent::EditIndexer(expected_edit_indexer_params)) ); } @@ -1408,7 +1436,7 @@ mod tests { use crate::models::servarr_data::sonarr::sonarr_data::EDIT_INDEXER_TORRENT_SELECTION_BLOCKS; use crate::models::BlockSelectionState; use crate::network::sonarr_network::SonarrEvent; - use pretty_assertions::assert_str_eq; + use pretty_assertions::{assert_eq, assert_str_eq}; use super::*; @@ -1709,7 +1737,32 @@ mod tests { .sonarr_data .selected_block .set_index(0, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1); - app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); + let edit_indexer_modal = EditIndexerModal { + name: "Test Update".into(), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: "https://localhost:9696/1/".into(), + api_key: "test1234".into(), + seed_ratio: "1.3".into(), + tags: "usenet, testing".into(), + priority: 0, + }; + app.data.sonarr_data.edit_indexer_modal = Some(edit_indexer_modal); + app.data.sonarr_data.indexers.set_items(vec![indexer()]); + let expected_edit_indexer_params = EditIndexerParams { + indexer_id: 1, + name: Some("Test Update".to_owned()), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: Some("https://localhost:9696/1/".to_owned()), + api_key: Some("test1234".to_owned()), + seed_ratio: Some("1.3".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + priority: Some(0), + ..EditIndexerParams::default() + }; EditIndexerHandler::with( DEFAULT_KEYBINDINGS.confirm.key, @@ -1720,11 +1773,11 @@ mod tests { .handle(); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Indexers.into()); - assert!(app.data.sonarr_data.edit_indexer_modal.is_some()); + assert!(app.data.sonarr_data.edit_indexer_modal.is_none()); assert!(app.should_refresh); assert_eq!( app.data.sonarr_data.prompt_confirm_action, - Some(SonarrEvent::EditIndexer(None)) + Some(SonarrEvent::EditIndexer(expected_edit_indexer_params)) ); } } @@ -1740,6 +1793,48 @@ mod tests { }) } + #[test] + fn test_build_edit_indexer_params() { + let mut app = App::default(); + let edit_indexer_modal = EditIndexerModal { + name: "Test Update".into(), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: "https://localhost:9696/1/".into(), + api_key: "test1234".into(), + seed_ratio: "1.3".into(), + tags: "usenet, testing".into(), + priority: 0, + }; + app.data.sonarr_data.edit_indexer_modal = Some(edit_indexer_modal); + app.data.sonarr_data.indexers.set_items(vec![indexer()]); + let expected_edit_indexer_params = EditIndexerParams { + indexer_id: 1, + name: Some("Test Update".to_owned()), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: Some("https://localhost:9696/1/".to_owned()), + api_key: Some("test1234".to_owned()), + seed_ratio: Some("1.3".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + priority: Some(0), + ..EditIndexerParams::default() + }; + + let params = EditIndexerHandler::with( + DEFAULT_KEYBINDINGS.confirm.key, + &mut app, + ActiveSonarrBlock::EditIndexerPrompt, + None, + ) + .build_edit_indexer_params(); + + assert_eq!(params, expected_edit_indexer_params); + assert!(app.data.sonarr_data.edit_indexer_modal.is_none()); + } + #[test] fn test_edit_indexer_handler_is_not_ready_when_loading() { let mut app = App::default(); diff --git a/src/network/sonarr_network.rs b/src/network/sonarr_network.rs index 6be7dae..41a76b0 100644 --- a/src/network/sonarr_network.rs +++ b/src/network/sonarr_network.rs @@ -10,7 +10,7 @@ use crate::{ models::{ radarr_models::IndexerTestResult, servarr_data::{ - modals::{EditIndexerModal, IndexerTestResultModalItem}, + modals::IndexerTestResultModalItem, sonarr::{ modals::{EditSeriesModal, EpisodeDetailsModal, SeasonDetailsModal}, sonarr_data::ActiveSonarrBlock, @@ -51,7 +51,7 @@ pub enum SonarrEvent { DeleteTag(i64), DownloadRelease(SonarrReleaseDownloadBody), EditAllIndexerSettings(IndexerSettings), - EditIndexer(Option), + EditIndexer(EditIndexerParams), EditSeries(Option), GetAllIndexerSettings, GetBlocklist, @@ -638,25 +638,18 @@ impl<'a, 'b> Network<'a, 'b> { async fn edit_sonarr_indexer( &mut self, - edit_indexer_params: Option, + mut edit_indexer_params: EditIndexerParams, ) -> Result<()> { + if let Some(tag_input_string) = edit_indexer_params.tag_input_string.as_ref() { + let tag_ids_vec = self + .extract_and_add_sonarr_tag_ids_vec(tag_input_string.clone()) + .await; + edit_indexer_params.tags = Some(tag_ids_vec); + } let detail_event = SonarrEvent::GetIndexers; - let event = SonarrEvent::EditIndexer(None); - let id = if let Some(ref params) = edit_indexer_params { - params.indexer_id - } else { - self - .app - .lock() - .await - .data - .sonarr_data - .indexers - .current_selection() - .id - }; + let event = SonarrEvent::EditIndexer(edit_indexer_params.clone()); + let id = edit_indexer_params.indexer_id; info!("Updating Sonarr indexer with ID: {id}"); - info!("Fetching indexer details for indexer with ID: {id}"); let request_props = self @@ -691,7 +684,7 @@ impl<'a, 'b> Network<'a, 'b> { seed_ratio, tags, priority, - ) = if let Some(params) = edit_indexer_params { + ) = { let priority = detailed_indexer_body["priority"] .as_i64() .expect("Unable to deserialize 'priority'"); @@ -700,28 +693,28 @@ impl<'a, 'b> Network<'a, 'b> { .unwrap() .iter() .find(|field| field["name"] == "seedCriteria.seedRatio"); - let name = params.name.unwrap_or( + let name = edit_indexer_params.name.unwrap_or( detailed_indexer_body["name"] .as_str() .expect("Unable to deserialize 'name'") .to_owned(), ); - let enable_rss = params.enable_rss.unwrap_or( + let enable_rss = edit_indexer_params.enable_rss.unwrap_or( detailed_indexer_body["enableRss"] .as_bool() .expect("Unable to deserialize 'enableRss'"), ); - let enable_automatic_search = params.enable_automatic_search.unwrap_or( + let enable_automatic_search = edit_indexer_params.enable_automatic_search.unwrap_or( detailed_indexer_body["enableAutomaticSearch"] .as_bool() .expect("Unable to deserialize 'enableAutomaticSearch"), ); - let enable_interactive_search = params.enable_interactive_search.unwrap_or( + let enable_interactive_search = edit_indexer_params.enable_interactive_search.unwrap_or( detailed_indexer_body["enableInteractiveSearch"] .as_bool() .expect("Unable to deserialize 'enableInteractiveSearch'"), ); - let url = params.url.unwrap_or( + let url = edit_indexer_params.url.unwrap_or( detailed_indexer_body["fields"] .as_array() .expect("Unable to deserialize 'fields'") @@ -734,7 +727,7 @@ impl<'a, 'b> Network<'a, 'b> { .expect("Unable to deserialize 'baseUrl value'") .to_owned(), ); - let api_key = params.api_key.unwrap_or( + let api_key = edit_indexer_params.api_key.unwrap_or( detailed_indexer_body["fields"] .as_array() .expect("Unable to deserialize 'fields'") @@ -747,7 +740,7 @@ impl<'a, 'b> Network<'a, 'b> { .expect("Unable to deserialize 'apiKey value'") .to_owned(), ); - let seed_ratio = params.seed_ratio.unwrap_or_else(|| { + let seed_ratio = edit_indexer_params.seed_ratio.unwrap_or_else(|| { if let Some(seed_ratio_field) = seed_ratio_field_option { return seed_ratio_field .get("value") @@ -759,10 +752,10 @@ impl<'a, 'b> Network<'a, 'b> { String::new() }); - let tags = if params.clear_tags { + let tags = if edit_indexer_params.clear_tags { vec![] } else { - params.tags.unwrap_or( + edit_indexer_params.tags.unwrap_or( detailed_indexer_body["tags"] .as_array() .expect("Unable to deserialize 'tags'") @@ -771,7 +764,7 @@ impl<'a, 'b> Network<'a, 'b> { .collect(), ) }; - let priority = params.priority.unwrap_or(priority); + let priority = edit_indexer_params.priority.unwrap_or(priority); ( name, @@ -784,51 +777,6 @@ impl<'a, 'b> Network<'a, 'b> { tags, priority, ) - } else { - let tags = self - .app - .lock() - .await - .data - .sonarr_data - .edit_indexer_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 EditIndexerModal { - name, - enable_rss, - enable_automatic_search, - enable_interactive_search, - url, - api_key, - seed_ratio, - priority, - .. - } = app.data.sonarr_data.edit_indexer_modal.as_ref().unwrap(); - - ( - name.text.clone(), - enable_rss.unwrap_or_default(), - enable_automatic_search.unwrap_or_default(), - enable_interactive_search.unwrap_or_default(), - url.text.clone(), - api_key.text.clone(), - seed_ratio.text.clone(), - tag_ids_vec, - *priority, - ) - }; - - app.data.sonarr_data.edit_indexer_modal = None; - - params }; *detailed_indexer_body.get_mut("name").unwrap() = json!(name); diff --git a/src/network/sonarr_network_tests.rs b/src/network/sonarr_network_tests.rs index 638d576..30ba7f1 100644 --- a/src/network/sonarr_network_tests.rs +++ b/src/network/sonarr_network_tests.rs @@ -22,7 +22,7 @@ mod test { use crate::app::{App, ServarrConfig}; use crate::models::radarr_models::IndexerTestResult; - use crate::models::servarr_data::modals::{EditIndexerModal, IndexerTestResultModalItem}; + use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::sonarr::modals::{ AddSeriesModal, EditSeriesModal, EpisodeDetailsModal, SeasonDetailsModal, }; @@ -212,7 +212,7 @@ mod test { #[values( SonarrEvent::GetIndexers, SonarrEvent::DeleteIndexer(0), - SonarrEvent::EditIndexer(None) + SonarrEvent::EditIndexer(EditIndexerParams::default()) )] event: SonarrEvent, ) { @@ -776,6 +776,19 @@ mod test { #[tokio::test] async fn test_handle_edit_sonarr_indexer_event() { + let expected_edit_indexer_params = EditIndexerParams { + indexer_id: 1, + name: Some("Test Update".to_owned()), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: Some("https://localhost:9696/1/".to_owned()), + api_key: Some("test1234".to_owned()), + seed_ratio: Some("1.3".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + priority: Some(0), + ..EditIndexerParams::default() + }; let indexer_details_json = json!({ "enableRss": true, "enableAutomaticSearch": true, @@ -822,7 +835,6 @@ mod test { "tags": [1, 2], "id": 1 }); - let (async_details_server, app_arc, mut server) = mock_servarr_api( RequestMethod::Get, None, @@ -838,7 +850,7 @@ mod test { "PUT", format!( "/api/v3{}/1?forceSave=true", - SonarrEvent::EditIndexer(None).resource() + SonarrEvent::EditIndexer(expected_edit_indexer_params.clone()).resource() ) .as_str(), ) @@ -847,315 +859,23 @@ mod test { .match_body(Matcher::Json(expected_indexer_edit_body_json)) .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 edit_indexer_modal = EditIndexerModal { - name: "Test Update".into(), - enable_rss: Some(false), - enable_automatic_search: Some(false), - enable_interactive_search: Some(false), - url: "https://localhost:9696/1/".into(), - api_key: "test1234".into(), - seed_ratio: "1.3".into(), - tags: "usenet, testing".into(), - priority: 0, - }; - app.data.sonarr_data.edit_indexer_modal = Some(edit_indexer_modal); - app.data.sonarr_data.indexers.set_items(vec![indexer()]); - } + 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::EditIndexer(None)) + .handle_sonarr_event(SonarrEvent::EditIndexer(expected_edit_indexer_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_indexer_modal.is_none()); } #[tokio::test] - async fn test_handle_edit_sonarr_indexer_event_does_not_add_seed_ratio_when_seed_ratio_field_is_none_in_details( + async fn test_handle_edit_sonarr_indexer_event_does_not_overwrite_tags_vec_if_tag_input_string_is_none( ) { - let indexer_details_json = json!({ - "enableRss": true, - "enableAutomaticSearch": true, - "enableInteractiveSearch": true, - "name": "Test Indexer", - "priority": 1, - "fields": [ - { - "name": "baseUrl", - "value": "https://test.com", - }, - { - "name": "apiKey", - "value": "", - }, - ], - "tags": [1], - "id": 1 - }); - let expected_indexer_edit_body_json = json!({ - "enableRss": false, - "enableAutomaticSearch": false, - "enableInteractiveSearch": false, - "name": "Test Update", - "priority": 0, - "fields": [ - { - "name": "baseUrl", - "value": "https://localhost:9696/1/", - }, - { - "name": "apiKey", - "value": "test1234", - }, - ], - "tags": [1, 2], - "id": 1 - }); - - let (async_details_server, app_arc, mut server) = mock_servarr_api( - RequestMethod::Get, - None, - Some(indexer_details_json), - None, - SonarrEvent::GetIndexers, - Some("/1"), - None, - ) - .await; - let async_edit_server = server - .mock( - "PUT", - format!( - "/api/v3{}/1?forceSave=true", - SonarrEvent::EditIndexer(None).resource() - ) - .as_str(), - ) - .with_status(202) - .match_header("X-Api-Key", "test1234") - .match_body(Matcher::Json(expected_indexer_edit_body_json)) - .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 edit_indexer_modal = EditIndexerModal { - name: "Test Update".into(), - enable_rss: Some(false), - enable_automatic_search: Some(false), - enable_interactive_search: Some(false), - url: "https://localhost:9696/1/".into(), - api_key: "test1234".into(), - seed_ratio: "1.3".into(), - tags: "usenet, testing".into(), - priority: 0, - }; - app.data.sonarr_data.edit_indexer_modal = Some(edit_indexer_modal); - let mut indexer = indexer(); - indexer.fields = Some( - indexer - .fields - .unwrap() - .into_iter() - .filter(|field| field.name != Some("seedCriteria.seedRatio".to_string())) - .collect(), - ); - app.data.sonarr_data.indexers.set_items(vec![indexer]); - } - let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); - - assert!(network - .handle_sonarr_event(SonarrEvent::EditIndexer(None)) - .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_indexer_modal.is_none()); - } - - #[tokio::test] - async fn test_handle_edit_sonarr_indexer_event_populates_the_seed_ratio_value_when_seed_ratio_field_is_present_in_details( - ) { - let indexer_details_json = json!({ - "enableRss": true, - "enableAutomaticSearch": true, - "enableInteractiveSearch": true, - "name": "Test Indexer", - "priority": 1, - "fields": [ - { - "name": "baseUrl", - "value": "https://test.com", - }, - { - "name": "apiKey", - "value": "", - }, - { - "name": "seedCriteria.seedRatio", - }, - ], - "tags": [1], - "id": 1 - }); - let expected_indexer_edit_body_json = json!({ - "enableRss": false, - "enableAutomaticSearch": false, - "enableInteractiveSearch": false, - "name": "Test Update", - "priority": 0, - "fields": [ - { - "name": "baseUrl", - "value": "https://localhost:9696/1/", - }, - { - "name": "apiKey", - "value": "test1234", - }, - { - "name": "seedCriteria.seedRatio", - "value": "1.3", - }, - ], - "tags": [1, 2], - "id": 1 - }); - - let (async_details_server, app_arc, mut server) = mock_servarr_api( - RequestMethod::Get, - None, - Some(indexer_details_json), - None, - SonarrEvent::GetIndexers, - Some("/1"), - None, - ) - .await; - let async_edit_server = server - .mock( - "PUT", - format!( - "/api/v3{}/1?forceSave=true", - SonarrEvent::EditIndexer(None).resource() - ) - .as_str(), - ) - .with_status(202) - .match_header("X-Api-Key", "test1234") - .match_body(Matcher::Json(expected_indexer_edit_body_json)) - .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 edit_indexer_modal = EditIndexerModal { - name: "Test Update".into(), - enable_rss: Some(false), - enable_automatic_search: Some(false), - enable_interactive_search: Some(false), - url: "https://localhost:9696/1/".into(), - api_key: "test1234".into(), - seed_ratio: "1.3".into(), - tags: "usenet, testing".into(), - priority: 0, - }; - app.data.sonarr_data.edit_indexer_modal = Some(edit_indexer_modal); - let mut indexer = indexer(); - indexer.fields = Some( - indexer - .fields - .unwrap() - .into_iter() - .map(|mut field| { - if field.name == Some("seedCriteria.seedRatio".to_string()) { - field.value = None; - field - } else { - field - } - }) - .collect(), - ); - app.data.sonarr_data.indexers.set_items(vec![indexer]); - } - let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); - - assert!(network - .handle_sonarr_event(SonarrEvent::EditIndexer(None)) - .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_indexer_modal.is_none()); - } - - #[tokio::test] - async fn test_handle_edit_sonarr_indexer_event_uses_provided_parameters() { - let indexer_details_json = json!({ - "enableRss": true, - "enableAutomaticSearch": true, - "enableInteractiveSearch": true, - "name": "Test Indexer", - "priority": 1, - "fields": [ - { - "name": "baseUrl", - "value": "https://test.com", - }, - { - "name": "apiKey", - "value": "", - }, - { - "name": "seedCriteria.seedRatio", - "value": "1.2", - }, - ], - "tags": [1], - "id": 1 - }); - let expected_indexer_edit_body_json = json!({ - "enableRss": false, - "enableAutomaticSearch": false, - "enableInteractiveSearch": false, - "name": "Test Update", - "priority": 25, - "fields": [ - { - "name": "baseUrl", - "value": "https://localhost:9696/1/", - }, - { - "name": "apiKey", - "value": "test1234", - }, - { - "name": "seedCriteria.seedRatio", - "value": "1.3", - }, - ], - "tags": [1, 2], - "id": 1 - }); - let edit_indexer_params = EditIndexerParams { + let expected_edit_indexer_params = EditIndexerParams { indexer_id: 1, name: Some("Test Update".to_owned()), enable_rss: Some(false), @@ -1165,9 +885,144 @@ mod test { api_key: Some("test1234".to_owned()), seed_ratio: Some("1.3".to_owned()), tags: Some(vec![1, 2]), - priority: Some(25), + priority: Some(0), ..EditIndexerParams::default() }; + let indexer_details_json = json!({ + "enableRss": true, + "enableAutomaticSearch": true, + "enableInteractiveSearch": true, + "name": "Test Indexer", + "priority": 1, + "fields": [ + { + "name": "baseUrl", + "value": "https://test.com", + }, + { + "name": "apiKey", + "value": "", + }, + { + "name": "seedCriteria.seedRatio", + "value": "1.2", + }, + ], + "tags": [1], + "id": 1 + }); + let expected_indexer_edit_body_json = json!({ + "enableRss": false, + "enableAutomaticSearch": false, + "enableInteractiveSearch": false, + "name": "Test Update", + "priority": 0, + "fields": [ + { + "name": "baseUrl", + "value": "https://localhost:9696/1/", + }, + { + "name": "apiKey", + "value": "test1234", + }, + { + "name": "seedCriteria.seedRatio", + "value": "1.3", + }, + ], + "tags": [1, 2], + "id": 1 + }); + let (async_details_server, app_arc, mut server) = mock_servarr_api( + RequestMethod::Get, + None, + Some(indexer_details_json), + None, + SonarrEvent::GetIndexers, + Some("/1"), + None, + ) + .await; + let async_edit_server = server + .mock( + "PUT", + format!( + "/api/v3{}/1?forceSave=true", + SonarrEvent::EditIndexer(expected_edit_indexer_params.clone()).resource() + ) + .as_str(), + ) + .with_status(202) + .match_header("X-Api-Key", "test1234") + .match_body(Matcher::Json(expected_indexer_edit_body_json)) + .create_async() + .await; + let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); + + assert!(network + .handle_sonarr_event(SonarrEvent::EditIndexer(expected_edit_indexer_params)) + .await + .is_ok()); + + async_details_server.assert_async().await; + async_edit_server.assert_async().await; + } + + #[tokio::test] + async fn test_handle_edit_sonarr_indexer_event_does_not_add_seed_ratio_when_seed_ratio_field_is_none_in_details( + ) { + let expected_edit_indexer_params = EditIndexerParams { + indexer_id: 1, + name: Some("Test Update".to_owned()), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: Some("https://localhost:9696/1/".to_owned()), + api_key: Some("test1234".to_owned()), + seed_ratio: Some("1.3".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + priority: Some(0), + ..EditIndexerParams::default() + }; + let indexer_details_json = json!({ + "enableRss": true, + "enableAutomaticSearch": true, + "enableInteractiveSearch": true, + "name": "Test Indexer", + "priority": 1, + "fields": [ + { + "name": "baseUrl", + "value": "https://test.com", + }, + { + "name": "apiKey", + "value": "", + }, + ], + "tags": [1], + "id": 1 + }); + let expected_indexer_edit_body_json = json!({ + "enableRss": false, + "enableAutomaticSearch": false, + "enableInteractiveSearch": false, + "name": "Test Update", + "priority": 0, + "fields": [ + { + "name": "baseUrl", + "value": "https://localhost:9696/1/", + }, + { + "name": "apiKey", + "value": "test1234", + }, + ], + "tags": [1, 2], + "id": 1 + }); let (async_details_server, app_arc, mut server) = mock_servarr_api( RequestMethod::Get, @@ -1184,7 +1039,7 @@ mod test { "PUT", format!( "/api/v3{}/1?forceSave=true", - SonarrEvent::EditIndexer(None).resource() + SonarrEvent::EditIndexer(expected_edit_indexer_params.clone()).resource() ) .as_str(), ) @@ -1193,10 +1048,12 @@ mod test { .match_body(Matcher::Json(expected_indexer_edit_body_json)) .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::EditIndexer(Some(edit_indexer_params))) + .handle_sonarr_event(SonarrEvent::EditIndexer(expected_edit_indexer_params)) .await .is_ok()); @@ -1205,8 +1062,106 @@ mod test { } #[tokio::test] - async fn test_handle_edit_sonarr_indexer_event_uses_provided_parameters_defaults_to_previous_values( + async fn test_handle_edit_sonarr_indexer_event_populates_the_seed_ratio_value_when_seed_ratio_field_is_present_in_details( ) { + let expected_edit_indexer_params = EditIndexerParams { + indexer_id: 1, + name: Some("Test Update".to_owned()), + enable_rss: Some(false), + enable_automatic_search: Some(false), + enable_interactive_search: Some(false), + url: Some("https://localhost:9696/1/".to_owned()), + api_key: Some("test1234".to_owned()), + seed_ratio: Some("1.3".to_owned()), + tag_input_string: Some("usenet, testing".to_owned()), + priority: Some(0), + ..EditIndexerParams::default() + }; + let indexer_details_json = json!({ + "enableRss": true, + "enableAutomaticSearch": true, + "enableInteractiveSearch": true, + "name": "Test Indexer", + "priority": 1, + "fields": [ + { + "name": "baseUrl", + "value": "https://test.com", + }, + { + "name": "apiKey", + "value": "", + }, + { + "name": "seedCriteria.seedRatio", + }, + ], + "tags": [1], + "id": 1 + }); + let expected_indexer_edit_body_json = json!({ + "enableRss": false, + "enableAutomaticSearch": false, + "enableInteractiveSearch": false, + "name": "Test Update", + "priority": 0, + "fields": [ + { + "name": "baseUrl", + "value": "https://localhost:9696/1/", + }, + { + "name": "apiKey", + "value": "test1234", + }, + { + "name": "seedCriteria.seedRatio", + "value": "1.3", + }, + ], + "tags": [1, 2], + "id": 1 + }); + + let (async_details_server, app_arc, mut server) = mock_servarr_api( + RequestMethod::Get, + None, + Some(indexer_details_json), + None, + SonarrEvent::GetIndexers, + Some("/1"), + None, + ) + .await; + let async_edit_server = server + .mock( + "PUT", + format!( + "/api/v3{}/1?forceSave=true", + SonarrEvent::EditIndexer(expected_edit_indexer_params.clone()).resource() + ) + .as_str(), + ) + .with_status(202) + .match_header("X-Api-Key", "test1234") + .match_body(Matcher::Json(expected_indexer_edit_body_json)) + .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::EditIndexer(expected_edit_indexer_params)) + .await + .is_ok()); + + async_details_server.assert_async().await; + async_edit_server.assert_async().await; + } + + #[tokio::test] + async fn test_handle_edit_sonarr_indexer_event_defaults_to_previous_values() { let indexer_details_json = json!({ "enableRss": true, "enableAutomaticSearch": true, @@ -1234,7 +1189,6 @@ mod test { indexer_id: 1, ..EditIndexerParams::default() }; - let (async_details_server, app_arc, mut server) = mock_servarr_api( RequestMethod::Get, None, @@ -1250,7 +1204,7 @@ mod test { "PUT", format!( "/api/v3{}/1?forceSave=true", - SonarrEvent::EditIndexer(None).resource() + SonarrEvent::EditIndexer(edit_indexer_params.clone()).resource() ) .as_str(), ) @@ -1262,7 +1216,7 @@ mod test { let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); assert!(network - .handle_sonarr_event(SonarrEvent::EditIndexer(Some(edit_indexer_params))) + .handle_sonarr_event(SonarrEvent::EditIndexer(edit_indexer_params)) .await .is_ok()); @@ -1271,8 +1225,7 @@ mod test { } #[tokio::test] - async fn test_handle_edit_sonarr_indexer_event_uses_provided_parameters_clears_tags_when_clear_tags_is_true( - ) { + async fn test_handle_edit_sonarr_indexer_event_clears_tags_when_clear_tags_is_true() { let indexer_details_json = json!({ "enableRss": true, "enableAutomaticSearch": true, @@ -1340,7 +1293,7 @@ mod test { "PUT", format!( "/api/v3{}/1?forceSave=true", - SonarrEvent::EditIndexer(None).resource() + SonarrEvent::EditIndexer(edit_indexer_params.clone()).resource() ) .as_str(), ) @@ -1352,7 +1305,7 @@ mod test { let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new()); assert!(network - .handle_sonarr_event(SonarrEvent::EditIndexer(Some(edit_indexer_params))) + .handle_sonarr_event(SonarrEvent::EditIndexer(edit_indexer_params)) .await .is_ok());