diff --git a/src/handlers/handler_test_utils.rs b/src/handlers/handler_test_utils.rs index 122c35e..1a49e94 100644 --- a/src/handlers/handler_test_utils.rs +++ b/src/handlers/handler_test_utils.rs @@ -112,14 +112,14 @@ mod test_utils { $handler::with(&key, &mut app, &$block, &$context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection(), "Test 2" ); $handler::with(&key, &mut app, &$block, &$context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection(), "Test 1" ); @@ -139,14 +139,14 @@ mod test_utils { $handler::with(key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 2" ); $handler::with(key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 1" ); @@ -162,14 +162,14 @@ mod test_utils { $handler::with(key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 2" ); $handler::with(key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 1" ); @@ -185,7 +185,7 @@ mod test_utils { $handler::with(key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app .data .$servarr_data @@ -198,7 +198,7 @@ mod test_utils { $handler::with(key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app .data .$servarr_data @@ -227,14 +227,14 @@ mod test_utils { $handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection(), "Test 3" ); $handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection(), "Test 1" ); @@ -254,14 +254,14 @@ mod test_utils { $handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 3" ); $handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 1" ); @@ -277,14 +277,14 @@ mod test_utils { $handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 3" ); $handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app.data.$servarr_data.$data_ref.current_selection().$field, "Test 1" ); @@ -300,7 +300,7 @@ mod test_utils { $handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app .data .$servarr_data @@ -313,7 +313,7 @@ mod test_utils { $handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); - assert_str_eq!( + pretty_assertions::assert_str_eq!( app .data .$servarr_data @@ -335,12 +335,14 @@ mod test_utils { app.data.sonarr_data.root_folders.set_items(vec![$crate::models::servarr_models::RootFolder::default()]); app.data.sonarr_data.indexers.set_items(vec![$crate::models::servarr_models::Indexer::default()]); app.data.sonarr_data.blocklist.set_items(vec![$crate::models::sonarr_models::BlocklistItem::default()]); + app.data.sonarr_data.add_searched_series = Some($crate::models::stateful_table::StatefulTable::default()); app.data.radarr_data.movies.set_items(vec![$crate::models::radarr_models::Movie::default()]); app.data.radarr_data.collections.set_items(vec![$crate::models::radarr_models::Collection::default()]); app.data.radarr_data.collection_movies.set_items(vec![$crate::models::radarr_models::CollectionMovie::default()]); app.data.radarr_data.indexers.set_items(vec![$crate::models::servarr_models::Indexer::default()]); app.data.radarr_data.root_folders.set_items(vec![$crate::models::servarr_models::RootFolder::default()]); app.data.radarr_data.blocklist.set_items(vec![$crate::models::radarr_models::BlocklistItem::default()]); + app.data.radarr_data.add_searched_movies = Some($crate::models::stateful_table::StatefulTable::default()); let mut movie_details_modal = $crate::models::servarr_data::radarr::modals::MovieDetailsModal::default(); movie_details_modal .movie_history @@ -362,7 +364,7 @@ mod test_utils { $handler::with(DEFAULT_KEYBINDINGS.esc.key, &mut app, $active_block, None).handle(); - assert_eq!(app.get_current_route(), $base.into()); + pretty_assertions::assert_eq!(app.get_current_route(), $base.into()); }; } @@ -373,13 +375,13 @@ mod test_utils { $handler::with(DELETE_KEY, &mut app, $block, None).handle(); - assert_eq!(app.get_current_route(), $expected_block.into()); + pretty_assertions::assert_eq!(app.get_current_route(), $expected_block.into()); }; ($handler:ident, $app:expr, $block:expr, $expected_block:expr) => { $handler::with(DELETE_KEY, &mut $app, $block, None).handle(); - assert_eq!($app.get_current_route(), $expected_block.into()); + pretty_assertions::assert_eq!($app.get_current_route(), $expected_block.into()); }; } @@ -391,7 +393,7 @@ mod test_utils { $handler::with(DEFAULT_KEYBINDINGS.refresh.key, &mut app, $block, None).handle(); - assert_eq!(app.get_current_route(), $block.into()); + pretty_assertions::assert_eq!(app.get_current_route(), $block.into()); assert!(app.should_refresh); }; } diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index e3d2ddc..ed2a906 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -132,10 +132,10 @@ fn handle_prompt_toggle(app: &mut App<'_>, key: Key) { macro_rules! handle_text_box_left_right_keys { ($self:expr, $key:expr, $input:expr) => { match $self.key { - _ if $key == DEFAULT_KEYBINDINGS.left.key => { + _ if $key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.left.key => { $input.scroll_left(); } - _ if $key == DEFAULT_KEYBINDINGS.right.key => { + _ if $key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.right.key => { $input.scroll_right(); } _ => (), @@ -147,7 +147,7 @@ macro_rules! handle_text_box_left_right_keys { macro_rules! handle_text_box_keys { ($self:expr, $key:expr, $input:expr) => { match $self.key { - _ if $key == DEFAULT_KEYBINDINGS.backspace.key => { + _ if $key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.backspace.key => { $input.pop(); } Key::Char(character) => { @@ -163,7 +163,7 @@ macro_rules! handle_prompt_left_right_keys { ($self:expr, $confirm_prompt:expr, $data:ident) => { if $self.app.data.$data.selected_block.get_active_block() == $confirm_prompt { handle_prompt_toggle($self.app, $self.key); - } else if $self.key == DEFAULT_KEYBINDINGS.left.key { + } else if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.left.key { $self.app.data.$data.selected_block.left(); } else { $self.app.data.$data.selected_block.right(); diff --git a/src/handlers/radarr_handlers/blocklist/blocklist_handler_tests.rs b/src/handlers/radarr_handlers/blocklist/blocklist_handler_tests.rs index bfb9bce..2a44f7f 100644 --- a/src/handlers/radarr_handlers/blocklist/blocklist_handler_tests.rs +++ b/src/handlers/radarr_handlers/blocklist/blocklist_handler_tests.rs @@ -14,238 +14,6 @@ mod tests { use crate::models::radarr_models::{BlocklistItem, BlocklistItemMovie}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS}; use crate::models::servarr_models::{Language, Quality, QualityWrapper}; - use crate::models::stateful_table::SortOption; - - mod test_handle_scroll_up_and_down { - use pretty_assertions::{assert_eq, assert_str_eq}; - use rstest::rstest; - - use crate::models::radarr_models::BlocklistItem; - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_blocklist_scroll, - BlocklistHandler, - radarr_data, - blocklist, - simple_stateful_iterable_vec!(BlocklistItem, String, source_title), - ActiveRadarrBlock::Blocklist, - None, - source_title, - to_string - ); - - #[rstest] - fn test_blocklist_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .blocklist - .set_items(simple_stateful_iterable_vec!( - BlocklistItem, - String, - source_title - )); - - BlocklistHandler::with(key, &mut app, ActiveRadarrBlock::Blocklist, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - BlocklistHandler::with(key, &mut app, ActiveRadarrBlock::Blocklist, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_blocklist_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let blocklist_field_vec = sort_options(); - let mut app = App::default(); - app.data.radarr_data.blocklist.sorting(sort_options()); - - if key == Key::Up { - for i in (0..blocklist_field_vec.len()).rev() { - BlocklistHandler::with(key, &mut app, ActiveRadarrBlock::BlocklistSortPrompt, None) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[i] - ); - } - } else { - for i in 0..blocklist_field_vec.len() { - BlocklistHandler::with(key, &mut app, ActiveRadarrBlock::BlocklistSortPrompt, None) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[(i + 1) % blocklist_field_vec.len()] - ); - } - } - } - } - - mod test_handle_home_end { - use pretty_assertions::{assert_eq, assert_str_eq}; - - use crate::models::radarr_models::BlocklistItem; - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_blocklist_home_and_end, - BlocklistHandler, - radarr_data, - blocklist, - extended_stateful_iterable_vec!(BlocklistItem, String, source_title), - ActiveRadarrBlock::Blocklist, - None, - source_title, - to_string - ); - - #[test] - fn test_blocklist_home_and_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .blocklist - .set_items(extended_stateful_iterable_vec!( - BlocklistItem, - String, - source_title - )); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Blocklist, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Blocklist, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_blocklist_sort_home_end() { - let blocklist_field_vec = sort_options(); - let mut app = App::default(); - app.data.radarr_data.blocklist.sorting(sort_options()); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[blocklist_field_vec.len() - 1] - ); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[0] - ); - } - } mod test_handle_delete { use pretty_assertions::assert_eq; @@ -439,31 +207,6 @@ mod tests { assert_eq!(app.data.radarr_data.prompt_confirm_action, None); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); } - - #[test] - fn test_blocklist_sort_prompt_submit() { - let mut app = App::default(); - app.data.radarr_data.blocklist.sort_asc = true; - app.data.radarr_data.blocklist.sorting(sort_options()); - app.data.radarr_data.blocklist.set_items(blocklist_vec()); - app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); - app.push_navigation_stack(ActiveRadarrBlock::BlocklistSortPrompt.into()); - - let mut expected_vec = blocklist_vec(); - expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); - expected_vec.reverse(); - - BlocklistHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); - assert_eq!(app.data.radarr_data.blocklist.items, expected_vec); - } } mod test_handle_esc { @@ -517,24 +260,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); } - #[test] - fn test_blocklist_sort_prompt_block_esc() { - let mut app = App::default(); - app.data.radarr_data.blocklist.set_items(vec![BlocklistItem::default()]); - app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); - app.push_navigation_stack(ActiveRadarrBlock::BlocklistSortPrompt.into()); - - BlocklistHandler::with( - ESC_KEY, - &mut app, - ActiveRadarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); - } - #[rstest] fn test_default_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); @@ -632,51 +357,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); } - #[test] - fn test_sort_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); - app.data.radarr_data.blocklist.set_items(blocklist_vec()); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::Blocklist, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::BlocklistSortPrompt.into() - ); - assert_eq!( - app.data.radarr_data.blocklist.sort.as_ref().unwrap().items, - blocklist_sorting_options() - ); - assert!(!app.data.radarr_data.blocklist.sort_asc); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); - app.data.radarr_data.blocklist.set_items(blocklist_vec()); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::Blocklist, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); - assert!(app.data.radarr_data.blocklist.sort.is_none()); - assert!(!app.data.radarr_data.blocklist.sort_asc); - } - #[rstest] #[case( ActiveRadarrBlock::Blocklist, @@ -987,15 +667,4 @@ mod tests { }, ] } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| { - b.source_title - .to_lowercase() - .cmp(&a.source_title.to_lowercase()) - }), - }] - } } diff --git a/src/handlers/radarr_handlers/blocklist/mod.rs b/src/handlers/radarr_handlers/blocklist/mod.rs index 372412b..2f23683 100644 --- a/src/handlers/radarr_handlers/blocklist/mod.rs +++ b/src/handlers/radarr_handlers/blocklist/mod.rs @@ -3,12 +3,11 @@ use crate::app::App; use crate::event::Key; use crate::handle_table_events; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::radarr_models::BlocklistItem; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS}; use crate::models::stateful_table::SortOption; -use crate::models::Scrollable; use crate::network::radarr_network::RadarrEvent; #[cfg(test)] @@ -33,13 +32,13 @@ impl<'a, 'b> BlocklistHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a, 'b> { fn handle(&mut self) { - let blocklist_table_handling_props = - TableHandlingProps::new(ActiveRadarrBlock::Blocklist.into()) + let blocklist_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::Blocklist.into()) .sorting_block(ActiveRadarrBlock::BlocklistSortPrompt.into()) .sort_by_fn(|a: &BlocklistItem, b: &BlocklistItem| a.id.cmp(&b.id)) .sort_options(blocklist_sorting_options()); - if !self.handle_blocklist_table_events(blocklist_table_handling_props) { + if !self.handle_blocklist_table_events(blocklist_table_handling_config) { self.handle_key_event(); } } diff --git a/src/handlers/radarr_handlers/collections/collection_details_handler.rs b/src/handlers/radarr_handlers/collections/collection_details_handler.rs index a058d7e..1d13768 100644 --- a/src/handlers/radarr_handlers/collections/collection_details_handler.rs +++ b/src/handlers/radarr_handlers/collections/collection_details_handler.rs @@ -2,7 +2,7 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handle_table_events; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::KeyEventHandler; use crate::models::radarr_models::CollectionMovie; use crate::models::servarr_data::radarr::radarr_data::{ @@ -10,7 +10,7 @@ use crate::models::servarr_data::radarr::radarr_data::{ EDIT_COLLECTION_SELECTION_BLOCKS, }; use crate::models::stateful_table::StatefulTable; -use crate::models::{BlockSelectionState, Scrollable}; +use crate::models::BlockSelectionState; #[cfg(test)] #[path = "collection_details_handler_tests.rs"] @@ -34,10 +34,10 @@ impl<'a, 'b> CollectionDetailsHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHandler<'a, 'b> { fn handle(&mut self) { - let collection_movies_table_handling_props = - TableHandlingProps::new(ActiveRadarrBlock::CollectionDetails.into()); + let collection_movies_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::CollectionDetails.into()); - if !self.handle_collection_movies_table_events(collection_movies_table_handling_props) { + if !self.handle_collection_movies_table_events(collection_movies_table_handling_config) { self.handle_key_event(); } } diff --git a/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs b/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs index 294fffc..c23a644 100644 --- a/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs @@ -12,144 +12,6 @@ mod tests { use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, }; - use crate::models::HorizontallyScrollableText; - - mod test_handle_scroll_up_and_down { - use rstest::rstest; - - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_collection_details_scroll, - CollectionDetailsHandler, - radarr_data, - collection_movies, - simple_stateful_iterable_vec!(CollectionMovie, HorizontallyScrollableText), - ActiveRadarrBlock::CollectionDetails, - None, - title, - to_string - ); - - #[rstest] - fn test_collection_details_scroll_no_op_when_not_ready( - #[values( - DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key - )] - key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .collection_movies - .set_items(simple_stateful_iterable_vec!( - CollectionMovie, - HorizontallyScrollableText - )); - - CollectionDetailsHandler::with(key, &mut app, ActiveRadarrBlock::CollectionDetails, None) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collection_movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - - CollectionDetailsHandler::with(key, &mut app, ActiveRadarrBlock::CollectionDetails, None) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collection_movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - } - - mod test_handle_home_end { - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_collection_details_home_end, - CollectionDetailsHandler, - radarr_data, - collection_movies, - extended_stateful_iterable_vec!(CollectionMovie, HorizontallyScrollableText), - ActiveRadarrBlock::CollectionDetails, - None, - title, - to_string - ); - - #[test] - fn test_collection_details_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .collection_movies - .set_items(extended_stateful_iterable_vec!( - CollectionMovie, - HorizontallyScrollableText - )); - - CollectionDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::CollectionDetails, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collection_movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - - CollectionDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::CollectionDetails, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collection_movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - } mod test_handle_submit { use bimap::BiMap; diff --git a/src/handlers/radarr_handlers/collections/collections_handler_tests.rs b/src/handlers/radarr_handlers/collections/collections_handler_tests.rs index a62a6aa..a5d72ae 100644 --- a/src/handlers/radarr_handlers/collections/collections_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/collections_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use core::sync::atomic::Ordering::SeqCst; use std::cmp::Ordering; use std::iter; @@ -19,357 +18,7 @@ mod tests { use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTIONS_BLOCKS, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_BLOCKS, }; - use crate::models::stateful_table::SortOption; - use crate::models::HorizontallyScrollableText; - use crate::{extended_stateful_iterable_vec, test_handler_delegation}; - - mod test_handle_scroll_up_and_down { - use pretty_assertions::assert_eq; - use rstest::rstest; - - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_collections_scroll, - CollectionsHandler, - radarr_data, - collections, - simple_stateful_iterable_vec!(Collection, HorizontallyScrollableText), - ActiveRadarrBlock::Collections, - None, - title, - to_string - ); - - #[rstest] - fn test_collections_scroll_no_op_when_not_ready( - #[values( - DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key - )] - key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .collections - .set_items(simple_stateful_iterable_vec!( - Collection, - HorizontallyScrollableText - )); - - CollectionsHandler::with(key, &mut app, ActiveRadarrBlock::Collections, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .to_string(), - "Test 1" - ); - - CollectionsHandler::with(key, &mut app, ActiveRadarrBlock::Collections, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_collections_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let collection_field_vec = sort_options(); - let mut app = App::default(); - app.data.radarr_data.collections.sorting(sort_options()); - - if key == Key::Up { - for i in (0..collection_field_vec.len()).rev() { - CollectionsHandler::with( - key, - &mut app, - ActiveRadarrBlock::CollectionsSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .sort - .as_ref() - .unwrap() - .current_selection(), - &collection_field_vec[i] - ); - } - } else { - for i in 0..collection_field_vec.len() { - CollectionsHandler::with( - key, - &mut app, - ActiveRadarrBlock::CollectionsSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .sort - .as_ref() - .unwrap() - .current_selection(), - &collection_field_vec[(i + 1) % collection_field_vec.len()] - ); - } - } - } - } - - mod test_handle_home_end { - use pretty_assertions::assert_eq; - - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_collections_home_end, - CollectionsHandler, - radarr_data, - collections, - extended_stateful_iterable_vec!(Collection, HorizontallyScrollableText), - ActiveRadarrBlock::Collections, - None, - title, - to_string - ); - - #[test] - fn test_collections_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .collections - .set_items(extended_stateful_iterable_vec!( - Collection, - HorizontallyScrollableText - )); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .to_string(), - "Test 1" - ); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_collection_search_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.data.radarr_data.collections.search = Some("Test".into()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_collection_filter_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.data.radarr_data.collections.filter = Some("Test".into()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_collections_sort_home_end() { - let collection_field_vec = sort_options(); - let mut app = App::default(); - app.data.radarr_data.collections.sorting(sort_options()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::CollectionsSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .sort - .as_ref() - .unwrap() - .current_selection(), - &collection_field_vec[collection_field_vec.len() - 1] - ); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::CollectionsSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .sort - .as_ref() - .unwrap() - .current_selection(), - &collection_field_vec[0] - ); - } - } + use crate::test_handler_delegation; mod test_handle_left_right_action { use pretty_assertions::assert_eq; @@ -445,114 +94,6 @@ mod tests { assert!(!app.data.radarr_data.prompt_confirm); } - - #[test] - fn test_collection_search_box_left_right_keys() { - let mut app = App::default(); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); - app.data.radarr_data.collections.search = Some("Test".into()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_collection_filter_box_left_right_keys() { - let mut app = App::default(); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into()); - app.data.radarr_data.collections.filter = Some("Test".into()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .collections - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } } mod test_handle_submit { @@ -600,206 +141,6 @@ mod tests { ); } - #[test] - fn test_search_collections_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); - app - .data - .radarr_data - .collections - .set_items(extended_stateful_iterable_vec!( - Collection, - HorizontallyScrollableText - )); - app.data.radarr_data.collections.search = Some("Test 2".into()); - - CollectionsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .text, - "Test 2" - ); - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - } - - #[test] - fn test_search_collections_submit_error_on_no_search_hits() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); - app - .data - .radarr_data - .collections - .set_items(extended_stateful_iterable_vec!( - Collection, - HorizontallyScrollableText - )); - app.data.radarr_data.collections.search = Some("Test 5".into()); - - CollectionsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .text, - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::SearchCollectionError.into() - ); - } - - #[test] - fn test_search_filtered_collections_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); - app - .data - .radarr_data - .collections - .set_items(extended_stateful_iterable_vec!( - Collection, - HorizontallyScrollableText - )); - app.data.radarr_data.collections.search = Some("Test 2".into()); - - CollectionsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .text, - "Test 2" - ); - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - } - - #[test] - fn test_filter_collections_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into()); - app - .data - .radarr_data - .collections - .set_items(extended_stateful_iterable_vec!( - Collection, - HorizontallyScrollableText - )); - app.data.radarr_data.collections.filter = Some("Test".into()); - - CollectionsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert!(!app.should_ignore_quit_key); - assert!(app.data.radarr_data.collections.filtered_items.is_some()); - assert_eq!( - app - .data - .radarr_data - .collections - .filtered_items - .as_ref() - .unwrap() - .len(), - 3 - ); - assert_str_eq!( - app - .data - .radarr_data - .collections - .current_selection() - .title - .text, - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - } - - #[test] - fn test_filter_collections_submit_error_on_no_filter_matches() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into()); - app - .data - .radarr_data - .collections - .set_items(extended_stateful_iterable_vec!( - Collection, - HorizontallyScrollableText - )); - app.data.radarr_data.collections.filter = Some("Test 5".into()); - - CollectionsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert!(!app.should_ignore_quit_key); - assert!(app.data.radarr_data.collections.filtered_items.is_none()); - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::FilterCollectionsError.into() - ); - } - #[test] fn test_update_all_collections_prompt_confirm_submit() { let mut app = App::default(); @@ -857,113 +198,17 @@ mod tests { ActiveRadarrBlock::Collections.into() ); } - - #[test] - fn test_collections_sort_prompt_submit() { - let mut app = App::default(); - app.data.radarr_data.collections.sort_asc = true; - app.data.radarr_data.collections.sorting(sort_options()); - app - .data - .radarr_data - .collections - .set_items(collections_vec()); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(ActiveRadarrBlock::CollectionsSortPrompt.into()); - - let mut expected_vec = collections_vec(); - expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); - expected_vec.reverse(); - - CollectionsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::CollectionsSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - assert_eq!(app.data.radarr_data.collections.items, expected_vec); - } } mod test_handle_esc { use pretty_assertions::assert_eq; - use ratatui::widgets::TableState; use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; - use crate::models::stateful_table::StatefulTable; use super::*; const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; - #[rstest] - fn test_search_collection_block_esc( - #[values( - ActiveRadarrBlock::SearchCollection, - ActiveRadarrBlock::SearchCollectionError - )] - active_radarr_block: ActiveRadarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(active_radarr_block.into()); - app.data.radarr_data = create_test_radarr_data(); - app.data.radarr_data.collections.search = Some("Test".into()); - - CollectionsHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.radarr_data.collections.search, None); - } - - #[rstest] - fn test_filter_collections_block_esc( - #[values( - ActiveRadarrBlock::FilterCollections, - ActiveRadarrBlock::FilterCollectionsError - )] - active_radarr_block: ActiveRadarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(active_radarr_block.into()); - app.data.radarr_data = create_test_radarr_data(); - app.data.radarr_data.collections = StatefulTable { - filter: Some("Test".into()), - filtered_items: Some(Vec::new()), - filtered_state: Some(TableState::default()), - ..StatefulTable::default() - }; - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - - CollectionsHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.radarr_data.collections.filter, None); - assert_eq!(app.data.radarr_data.collections.filtered_items, None); - assert_eq!(app.data.radarr_data.collections.filtered_state, None); - } - #[test] fn test_update_all_collections_prompt_block_esc() { let mut app = App::default(); @@ -986,31 +231,6 @@ mod tests { assert!(!app.data.radarr_data.prompt_confirm); } - #[test] - fn test_collections_sort_prompt_block_esc() { - let mut app = App::default(); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.push_navigation_stack(ActiveRadarrBlock::CollectionsSortPrompt.into()); - - CollectionsHandler::with( - ESC_KEY, - &mut app, - ActiveRadarrBlock::CollectionsSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - } - #[rstest] fn test_default_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); @@ -1045,149 +265,6 @@ mod tests { use super::*; - #[test] - fn test_search_collections_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::SearchCollection.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.radarr_data.collections.search, - Some(HorizontallyScrollableText::default()) - ); - } - - #[test] - fn test_search_collections_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.radarr_data.collections.search, None); - } - - #[test] - fn test_filter_collections_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::FilterCollections.into() - ); - assert!(app.should_ignore_quit_key); - assert!(app.data.radarr_data.collections.filter.is_some()); - } - - #[test] - fn test_filter_collections_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - assert!(!app.should_ignore_quit_key); - assert!(app.data.radarr_data.collections.filter.is_none()); - } - - #[test] - fn test_filter_collections_key_resets_previous_filter() { - let mut app = App::default(); - app.data.radarr_data = create_test_radarr_data(); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app.data.radarr_data.collections.filter = Some("Test".into()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::FilterCollections.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.radarr_data.collections.filter, - Some(HorizontallyScrollableText::default()) - ); - assert!(app.data.radarr_data.collections.filtered_items.is_none()); - assert!(app.data.radarr_data.collections.filtered_state.is_none()); - } - #[test] fn test_collection_edit_key() { test_edit_collection_key!(CollectionsHandler, ActiveRadarrBlock::Collections, None); @@ -1323,197 +400,6 @@ mod tests { assert!(!app.should_refresh); } - #[test] - fn test_search_collections_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.data.radarr_data.collections.search = Some("Test".into()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .search - .as_ref() - .unwrap() - .text, - "Tes" - ); - } - - #[test] - fn test_filter_collections_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.data.radarr_data.collections.filter = Some("Test".into()); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .filter - .as_ref() - .unwrap() - .text, - "Tes" - ); - } - - #[test] - fn test_search_collections_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::SearchCollection.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.data.radarr_data.collections.search = Some(HorizontallyScrollableText::default()); - - CollectionsHandler::with( - Key::Char('h'), - &mut app, - ActiveRadarrBlock::SearchCollection, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .search - .as_ref() - .unwrap() - .text, - "h" - ); - } - - #[test] - fn test_filter_collections_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - app.data.radarr_data.collections.filter = Some(HorizontallyScrollableText::default()); - - CollectionsHandler::with( - Key::Char('h'), - &mut app, - ActiveRadarrBlock::FilterCollections, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .collections - .filter - .as_ref() - .unwrap() - .text, - "h" - ); - } - - #[test] - fn test_sort_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::CollectionsSortPrompt.into() - ); - assert_eq!( - app - .data - .radarr_data - .collections - .sort - .as_ref() - .unwrap() - .items, - collections_sorting_options() - ); - assert!(!app.data.radarr_data.collections.sort_asc); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); - app - .data - .radarr_data - .collections - .set_items(vec![Collection::default()]); - - CollectionsHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::Collections, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::Collections.into() - ); - assert!(app.data.radarr_data.collections.sort.is_none()); - assert!(!app.data.radarr_data.collections.sort_asc); - } - #[test] fn test_update_all_collections_prompt_confirm_confirm() { let mut app = App::default(); @@ -1787,16 +673,4 @@ mod tests { }, ] } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| { - b.title - .text - .to_lowercase() - .cmp(&a.title.text.to_lowercase()) - }), - }] - } } diff --git a/src/handlers/radarr_handlers/collections/mod.rs b/src/handlers/radarr_handlers/collections/mod.rs index f0ee1ef..265a03d 100644 --- a/src/handlers/radarr_handlers/collections/mod.rs +++ b/src/handlers/radarr_handlers/collections/mod.rs @@ -5,14 +5,14 @@ use crate::handle_table_events; use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler; use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::radarr_models::Collection; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTIONS_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS, }; use crate::models::stateful_table::SortOption; -use crate::models::{BlockSelectionState, Scrollable}; +use crate::models::BlockSelectionState; use crate::network::radarr_network::RadarrEvent; mod collection_details_handler; @@ -40,8 +40,8 @@ impl<'a, 'b> CollectionsHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'a, 'b> { fn handle(&mut self) { - let collections_table_handling_props = - TableHandlingProps::new(ActiveRadarrBlock::Collections.into()) + let collections_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::Collections.into()) .sorting_block(ActiveRadarrBlock::CollectionsSortPrompt.into()) .sort_by_fn(|a: &Collection, b: &Collection| a.id.cmp(&b.id)) .sort_options(collections_sorting_options()) @@ -52,7 +52,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<' .filter_error_block(ActiveRadarrBlock::FilterCollectionsError.into()) .filter_field_fn(|collection| &collection.title.text); - if !self.handle_collections_table_events(collections_table_handling_props) { + if !self.handle_collections_table_events(collections_table_handling_config) { match self.active_radarr_block { _ if CollectionDetailsHandler::accepts(self.active_radarr_block) => { CollectionDetailsHandler::with( diff --git a/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs b/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs index f47a498..e5e75bc 100644 --- a/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs +++ b/src/handlers/radarr_handlers/downloads/downloads_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::assert_str_eq; use strum::IntoEnumIterator; use crate::app::key_binding::DEFAULT_KEYBINDINGS; @@ -11,111 +10,6 @@ mod tests { use crate::models::radarr_models::DownloadRecord; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; - mod test_handle_scroll_up_and_down { - use rstest::rstest; - - use crate::models::radarr_models::DownloadRecord; - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_downloads_scroll, - DownloadsHandler, - radarr_data, - downloads, - DownloadRecord, - ActiveRadarrBlock::Downloads, - None, - title - ); - - #[rstest] - fn test_downloads_scroll_no_op_when_not_ready( - #[values( - DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key - )] - key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .downloads - .set_items(simple_stateful_iterable_vec!(DownloadRecord)); - - DownloadsHandler::with(key, &mut app, ActiveRadarrBlock::Downloads, None).handle(); - - assert_str_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 1" - ); - - DownloadsHandler::with(key, &mut app, ActiveRadarrBlock::Downloads, None).handle(); - - assert_str_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 1" - ); - } - } - - mod test_handle_home_end { - use crate::models::radarr_models::DownloadRecord; - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_downloads_home_end, - DownloadsHandler, - radarr_data, - downloads, - DownloadRecord, - ActiveRadarrBlock::Downloads, - None, - title - ); - - #[test] - fn test_downloads_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .downloads - .set_items(extended_stateful_iterable_vec!(DownloadRecord)); - - DownloadsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Downloads, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 1" - ); - - DownloadsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Downloads, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 1" - ); - } - } - mod test_handle_delete { use pretty_assertions::assert_eq; diff --git a/src/handlers/radarr_handlers/downloads/mod.rs b/src/handlers/radarr_handlers/downloads/mod.rs index fa0756b..a09966f 100644 --- a/src/handlers/radarr_handlers/downloads/mod.rs +++ b/src/handlers/radarr_handlers/downloads/mod.rs @@ -3,11 +3,10 @@ use crate::app::App; use crate::event::Key; use crate::handle_table_events; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::radarr_models::DownloadRecord; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; -use crate::models::Scrollable; use crate::network::radarr_network::RadarrEvent; #[cfg(test)] @@ -32,10 +31,10 @@ impl<'a, 'b> DownloadsHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a, 'b> { fn handle(&mut self) { - let downloads_table_handling_props = - TableHandlingProps::new(ActiveRadarrBlock::Downloads.into()); + let downloads_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::Downloads.into()); - if !self.handle_downloads_table_events(downloads_table_handling_props) { + if !self.handle_downloads_table_events(downloads_table_handling_config) { self.handle_key_event(); } } diff --git a/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs b/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs index b0e9a43..5f070a7 100644 --- a/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs +++ b/src/handlers/radarr_handlers/indexers/indexers_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::{assert_eq, assert_str_eq}; use rstest::rstest; use strum::IntoEnumIterator; @@ -15,109 +14,6 @@ mod tests { use crate::models::servarr_models::Indexer; use crate::test_handler_delegation; - mod test_handle_scroll_up_and_down { - use rstest::rstest; - - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_indexers_scroll, - IndexersHandler, - radarr_data, - indexers, - simple_stateful_iterable_vec!(Indexer, String, protocol), - ActiveRadarrBlock::Indexers, - None, - protocol - ); - - #[rstest] - fn test_indexers_scroll_no_op_when_not_ready( - #[values( - DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key - )] - key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .indexers - .set_items(simple_stateful_iterable_vec!(Indexer, String, protocol)); - - IndexersHandler::with(key, &mut app, ActiveRadarrBlock::Indexers, None).handle(); - - assert_str_eq!( - app.data.radarr_data.indexers.current_selection().protocol, - "Test 1" - ); - - IndexersHandler::with(key, &mut app, ActiveRadarrBlock::Indexers, None).handle(); - - assert_str_eq!( - app.data.radarr_data.indexers.current_selection().protocol, - "Test 1" - ); - } - } - - mod test_handle_home_end { - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_indexers_home_end, - IndexersHandler, - radarr_data, - indexers, - extended_stateful_iterable_vec!(Indexer, String, protocol), - ActiveRadarrBlock::Indexers, - None, - protocol - ); - - #[test] - fn test_indexers_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .indexers - .set_items(extended_stateful_iterable_vec!(Indexer, String, protocol)); - - IndexersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Indexers, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.indexers.current_selection().protocol, - "Test 1" - ); - - IndexersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Indexers, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.indexers.current_selection().protocol, - "Test 1" - ); - } - } - mod test_handle_delete { use pretty_assertions::assert_eq; diff --git a/src/handlers/radarr_handlers/indexers/mod.rs b/src/handlers/radarr_handlers/indexers/mod.rs index e239fc5..282e80a 100644 --- a/src/handlers/radarr_handlers/indexers/mod.rs +++ b/src/handlers/radarr_handlers/indexers/mod.rs @@ -6,7 +6,7 @@ use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::indexers::edit_indexer_handler::EditIndexerHandler; use crate::handlers::radarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler; use crate::handlers::radarr_handlers::indexers::test_all_indexers_handler::TestAllIndexersHandler; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, EDIT_INDEXER_NZB_SELECTION_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, @@ -14,7 +14,6 @@ use crate::models::servarr_data::radarr::radarr_data::{ }; use crate::models::servarr_models::Indexer; use crate::models::BlockSelectionState; -use crate::models::Scrollable; use crate::network::radarr_network::RadarrEvent; mod edit_indexer_handler; @@ -38,9 +37,10 @@ impl<'a, 'b> IndexersHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a, 'b> { fn handle(&mut self) { - let indexer_table_handling_props = TableHandlingProps::new(ActiveRadarrBlock::Indexers.into()); + let indexer_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::Indexers.into()); - if !self.handle_indexers_table_events(indexer_table_handling_props) { + if !self.handle_indexers_table_events(indexer_table_handling_config) { match self.active_radarr_block { _ if EditIndexerHandler::accepts(self.active_radarr_block) => { EditIndexerHandler::with(self.key, self.app, self.active_radarr_block, self.context) diff --git a/src/handlers/radarr_handlers/indexers/test_all_indexers_handler.rs b/src/handlers/radarr_handlers/indexers/test_all_indexers_handler.rs index 50cac84..1b4297e 100644 --- a/src/handlers/radarr_handlers/indexers/test_all_indexers_handler.rs +++ b/src/handlers/radarr_handlers/indexers/test_all_indexers_handler.rs @@ -1,8 +1,10 @@ use crate::app::App; use crate::event::Key; +use crate::handle_table_events; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::KeyEventHandler; +use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; -use crate::models::Scrollable; #[cfg(test)] #[path = "test_all_indexers_handler_tests.rs"] @@ -15,7 +17,33 @@ pub(super) struct TestAllIndexersHandler<'a, 'b> { _context: Option, } +impl<'a, 'b> TestAllIndexersHandler<'a, 'b> { + handle_table_events!( + self, + indexer_test_all_results, + self + .app + .data + .radarr_data + .indexer_test_all_results + .as_mut() + .unwrap(), + IndexerTestResultModalItem + ); +} + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for TestAllIndexersHandler<'a, 'b> { + fn handle(&mut self) { + let test_all_indexers_test_results_table_handler_config = + TableHandlingConfig::new(ActiveRadarrBlock::TestAllIndexers.into()); + + if !self.handle_indexer_test_all_results_table_events( + test_all_indexers_test_results_table_handler_config, + ) { + self.handle_key_event(); + } + } + fn accepts(active_block: ActiveRadarrBlock) -> bool { active_block == ActiveRadarrBlock::TestAllIndexers } @@ -48,57 +76,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for TestAllIndexersHandl !self.app.is_loading && table_is_ready } - fn handle_scroll_up(&mut self) { - if self.active_radarr_block == ActiveRadarrBlock::TestAllIndexers { - self - .app - .data - .radarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_up() - } - } + fn handle_scroll_up(&mut self) {} - fn handle_scroll_down(&mut self) { - if self.active_radarr_block == ActiveRadarrBlock::TestAllIndexers { - self - .app - .data - .radarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_down() - } - } + fn handle_scroll_down(&mut self) {} - fn handle_home(&mut self) { - if self.active_radarr_block == ActiveRadarrBlock::TestAllIndexers { - self - .app - .data - .radarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_to_top() - } - } + fn handle_home(&mut self) {} - fn handle_end(&mut self) { - if self.active_radarr_block == ActiveRadarrBlock::TestAllIndexers { - self - .app - .data - .radarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_to_bottom() - } - } + fn handle_end(&mut self) {} fn handle_delete(&mut self) {} diff --git a/src/handlers/radarr_handlers/indexers/test_all_indexers_handler_tests.rs b/src/handlers/radarr_handlers/indexers/test_all_indexers_handler_tests.rs index 7e1a4f3..31a93d7 100644 --- a/src/handlers/radarr_handlers/indexers/test_all_indexers_handler_tests.rs +++ b/src/handlers/radarr_handlers/indexers/test_all_indexers_handler_tests.rs @@ -2,7 +2,6 @@ mod tests { use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; - use crate::event::Key; use crate::handlers::radarr_handlers::indexers::test_all_indexers_handler::TestAllIndexersHandler; use crate::handlers::KeyEventHandler; use crate::models::servarr_data::modals::IndexerTestResultModalItem; @@ -10,220 +9,6 @@ mod tests { use crate::models::stateful_table::StatefulTable; use strum::IntoEnumIterator; - mod test_handle_scroll_up_and_down { - use pretty_assertions::assert_str_eq; - use rstest::rstest; - - use crate::models::servarr_data::modals::IndexerTestResultModalItem; - use crate::models::stateful_table::StatefulTable; - use crate::simple_stateful_iterable_vec; - - use super::*; - - #[rstest] - fn test_test_all_indexers_results_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(simple_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with(key, &mut app, ActiveRadarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 2" - ); - - TestAllIndexersHandler::with(key, &mut app, ActiveRadarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - - #[rstest] - fn test_test_all_indexers_results_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(simple_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with(key, &mut app, ActiveRadarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - - TestAllIndexersHandler::with(key, &mut app, ActiveRadarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - } - - mod test_handle_home_end { - use crate::extended_stateful_iterable_vec; - use crate::models::servarr_data::modals::IndexerTestResultModalItem; - use crate::models::stateful_table::StatefulTable; - use pretty_assertions::assert_str_eq; - - use super::*; - - #[test] - fn test_test_all_indexers_results_home_end() { - let mut app = App::default(); - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(extended_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 3" - ); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - - #[test] - fn test_test_all_indexers_results_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(extended_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - } - mod test_handle_esc { use super::*; use crate::models::stateful_table::StatefulTable; diff --git a/src/handlers/radarr_handlers/library/add_movie_handler.rs b/src/handlers/radarr_handlers/library/add_movie_handler.rs index ed555f6..c6c11d5 100644 --- a/src/handlers/radarr_handlers/library/add_movie_handler.rs +++ b/src/handlers/radarr_handlers/library/add_movie_handler.rs @@ -1,11 +1,13 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; +use crate::models::radarr_models::AddMovieSearchResult; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, ADD_MOVIE_BLOCKS, ADD_MOVIE_SELECTION_BLOCKS, }; use crate::models::{BlockSelectionState, Scrollable}; use crate::network::radarr_network::RadarrEvent; -use crate::{handle_text_box_keys, handle_text_box_left_right_keys, App, Key}; +use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, App, Key}; #[cfg(test)] #[path = "add_movie_handler_tests.rs"] @@ -18,7 +20,31 @@ pub(super) struct AddMovieHandler<'a, 'b> { context: Option, } +impl<'a, 'b> AddMovieHandler<'a, 'b> { + handle_table_events!( + self, + add_movie_search_results, + self + .app + .data + .radarr_data + .add_searched_movies + .as_mut() + .unwrap(), + AddMovieSearchResult + ); +} + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, 'b> { + fn handle(&mut self) { + let add_movie_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::AddMovieSearchResults.into()); + + if !self.handle_add_movie_search_results_table_events(add_movie_table_handling_config) { + self.handle_key_event(); + } + } + fn accepts(active_block: ActiveRadarrBlock) -> bool { ADD_MOVIE_BLOCKS.contains(&active_block) } @@ -47,14 +73,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, fn handle_scroll_up(&mut self) { match self.active_radarr_block { - ActiveRadarrBlock::AddMovieSearchResults => self - .app - .data - .radarr_data - .add_searched_movies - .as_mut() - .unwrap() - .scroll_up(), ActiveRadarrBlock::AddMovieSelectMonitor => self .app .data @@ -98,14 +116,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, fn handle_scroll_down(&mut self) { match self.active_radarr_block { - ActiveRadarrBlock::AddMovieSearchResults => self - .app - .data - .radarr_data - .add_searched_movies - .as_mut() - .unwrap() - .scroll_down(), ActiveRadarrBlock::AddMovieSelectMonitor => self .app .data @@ -149,14 +159,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, fn handle_home(&mut self) { match self.active_radarr_block { - ActiveRadarrBlock::AddMovieSearchResults => self - .app - .data - .radarr_data - .add_searched_movies - .as_mut() - .unwrap() - .scroll_to_top(), ActiveRadarrBlock::AddMovieSelectMonitor => self .app .data @@ -216,14 +218,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a, fn handle_end(&mut self) { match self.active_radarr_block { - ActiveRadarrBlock::AddMovieSearchResults => self - .app - .data - .radarr_data - .add_searched_movies - .as_mut() - .unwrap() - .scroll_to_bottom(), ActiveRadarrBlock::AddMovieSelectMonitor => self .app .data diff --git a/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs b/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs index 18b4036..ebd98b5 100644 --- a/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/add_movie_handler_tests.rs @@ -20,123 +20,11 @@ mod tests { use crate::models::servarr_data::radarr::modals::AddMovieModal; use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS; - use crate::models::stateful_table::StatefulTable; use crate::models::BlockSelectionState; use crate::simple_stateful_iterable_vec; use super::*; - #[rstest] - fn test_add_movie_search_results_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - let mut add_searched_movies = StatefulTable::default(); - add_searched_movies.set_items(simple_stateful_iterable_vec!( - AddMovieSearchResult, - HorizontallyScrollableText - )); - app.data.radarr_data.add_searched_movies = Some(add_searched_movies); - - AddMovieHandler::with( - key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 2" - ); - - AddMovieHandler::with( - key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_add_movie_search_results_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - let mut add_searched_movies = StatefulTable::default(); - add_searched_movies.set_items(simple_stateful_iterable_vec!( - AddMovieSearchResult, - HorizontallyScrollableText - )); - app.data.radarr_data.add_searched_movies = Some(add_searched_movies); - - AddMovieHandler::with( - key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - - AddMovieHandler::with( - key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - #[rstest] fn test_add_movie_select_monitor_scroll( #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, @@ -421,117 +309,9 @@ mod tests { use crate::extended_stateful_iterable_vec; use crate::models::servarr_data::radarr::modals::AddMovieModal; - use crate::models::stateful_table::StatefulTable; use super::*; - #[test] - fn test_add_movie_search_results_home_end() { - let mut app = App::default(); - let mut add_searched_movies = StatefulTable::default(); - add_searched_movies.set_items(extended_stateful_iterable_vec!( - AddMovieSearchResult, - HorizontallyScrollableText - )); - app.data.radarr_data.add_searched_movies = Some(add_searched_movies); - - AddMovieHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 3" - ); - - AddMovieHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_add_movie_search_results_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - let mut add_searched_movies = StatefulTable::default(); - add_searched_movies.set_items(extended_stateful_iterable_vec!( - AddMovieSearchResult, - HorizontallyScrollableText - )); - app.data.radarr_data.add_searched_movies = Some(add_searched_movies); - - AddMovieHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - - AddMovieHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::AddMovieSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .add_searched_movies - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - #[test] fn test_add_movie_select_monitor_home_end() { let monitor_vec = Vec::from_iter(MovieMonitor::iter()); diff --git a/src/handlers/radarr_handlers/library/library_handler_tests.rs b/src/handlers/radarr_handlers/library/library_handler_tests.rs index e513af1..7999519 100644 --- a/src/handlers/radarr_handlers/library/library_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/library_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use core::sync::atomic::Ordering::SeqCst; use pretty_assertions::{assert_eq, assert_str_eq}; use rstest::rstest; use std::cmp::Ordering; @@ -17,341 +16,8 @@ mod tests { MOVIE_DETAILS_BLOCKS, }; use crate::models::servarr_models::Language; - use crate::models::stateful_table::SortOption; - use crate::models::HorizontallyScrollableText; use crate::test_handler_delegation; - mod test_handle_scroll_up_and_down { - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - use pretty_assertions::assert_eq; - - use super::*; - - test_iterable_scroll!( - test_movies_scroll, - LibraryHandler, - radarr_data, - movies, - simple_stateful_iterable_vec!(Movie, HorizontallyScrollableText), - ActiveRadarrBlock::Movies, - None, - title, - to_string - ); - - #[rstest] - fn test_movies_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .movies - .set_items(simple_stateful_iterable_vec!( - Movie, - HorizontallyScrollableText - )); - - LibraryHandler::with(key, &mut app, ActiveRadarrBlock::Movies, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - - LibraryHandler::with(key, &mut app, ActiveRadarrBlock::Movies, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_movies_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let movie_field_vec = sort_options(); - let mut app = App::default(); - app.data.radarr_data.movies.sorting(sort_options()); - - if key == Key::Up { - for i in (0..movie_field_vec.len()).rev() { - LibraryHandler::with(key, &mut app, ActiveRadarrBlock::MoviesSortPrompt, None).handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .sort - .as_ref() - .unwrap() - .current_selection(), - &movie_field_vec[i] - ); - } - } else { - for i in 0..movie_field_vec.len() { - LibraryHandler::with(key, &mut app, ActiveRadarrBlock::MoviesSortPrompt, None).handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .sort - .as_ref() - .unwrap() - .current_selection(), - &movie_field_vec[(i + 1) % movie_field_vec.len()] - ); - } - } - } - } - - mod test_handle_home_end { - use pretty_assertions::assert_eq; - - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_movies_home_end, - LibraryHandler, - radarr_data, - movies, - extended_stateful_iterable_vec!(Movie, HorizontallyScrollableText), - ActiveRadarrBlock::Movies, - None, - title, - to_string - ); - - #[test] - fn test_movies_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .movies - .set_items(extended_stateful_iterable_vec!( - Movie, - HorizontallyScrollableText - )); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movies - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_movie_search_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - app.data.radarr_data.movies.search = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::SearchMovie, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::SearchMovie, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_movie_filter_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - app.data.radarr_data.movies.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::FilterMovies, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::FilterMovies, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_movies_sort_home_end() { - let movie_field_vec = sort_options(); - let mut app = App::default(); - app.data.radarr_data.movies.sorting(sort_options()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::MoviesSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .sort - .as_ref() - .unwrap() - .current_selection(), - &movie_field_vec[movie_field_vec.len() - 1] - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::MoviesSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .sort - .as_ref() - .unwrap() - .current_selection(), - &movie_field_vec[0] - ); - } - } - mod test_handle_delete { use pretty_assertions::assert_eq; @@ -477,112 +143,11 @@ mod tests { assert!(!app.data.radarr_data.prompt_confirm); } - - #[test] - fn test_movie_search_box_left_right_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); - app.data.radarr_data.movies.set_items(vec![Movie::default()]); - app.data.radarr_data.movies.search = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveRadarrBlock::SearchMovie, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveRadarrBlock::SearchMovie, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_movie_filter_box_left_right_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); - app.data.radarr_data.movies.set_items(vec![Movie::default()]); - app.data.radarr_data.movies.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveRadarrBlock::FilterMovies, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveRadarrBlock::FilterMovies, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movies - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } } mod test_handle_submit { use pretty_assertions::assert_eq; - use crate::extended_stateful_iterable_vec; use crate::network::radarr_network::RadarrEvent; use super::*; @@ -622,148 +187,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); } - #[test] - fn test_search_movie_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); - app - .data - .radarr_data - .movies - .set_items(extended_stateful_iterable_vec!( - Movie, - HorizontallyScrollableText - )); - app.data.radarr_data.movies.search = Some("Test 2".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SearchMovie, None).handle(); - - assert_str_eq!( - app.data.radarr_data.movies.current_selection().title.text, - "Test 2" - ); - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - } - - #[test] - fn test_search_movie_submit_error_on_no_search_hits() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); - app - .data - .radarr_data - .movies - .set_items(extended_stateful_iterable_vec!( - Movie, - HorizontallyScrollableText - )); - app.data.radarr_data.movies.search = Some("Test 5".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SearchMovie, None).handle(); - - assert_str_eq!( - app.data.radarr_data.movies.current_selection().title.text, - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::SearchMovieError.into() - ); - } - - #[test] - fn test_search_filtered_movies_submit() { - let mut app = App::default(); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); - app - .data - .radarr_data - .movies - .set_filtered_items(extended_stateful_iterable_vec!( - Movie, - HorizontallyScrollableText - )); - app.data.radarr_data.movies.search = Some("Test 2".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SearchMovie, None).handle(); - - assert_str_eq!( - app.data.radarr_data.movies.current_selection().title.text, - "Test 2" - ); - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - } - - #[test] - fn test_filter_movies_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); - app - .data - .radarr_data - .movies - .set_items(extended_stateful_iterable_vec!( - Movie, - HorizontallyScrollableText - )); - app.data.radarr_data.movies.filter = Some("Test".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::FilterMovies, None).handle(); - - assert!(app.data.radarr_data.movies.filtered_items.is_some()); - assert!(!app.should_ignore_quit_key); - assert_eq!( - app - .data - .radarr_data - .movies - .filtered_items - .as_ref() - .unwrap() - .len(), - 3 - ); - assert_str_eq!( - app.data.radarr_data.movies.current_selection().title.text, - "Test 1" - ); - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - } - - #[test] - fn test_filter_movies_submit_error_on_no_filter_matches() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); - app - .data - .radarr_data - .movies - .set_items(extended_stateful_iterable_vec!( - Movie, - HorizontallyScrollableText - )); - app.data.radarr_data.movies.filter = Some("Test 5".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::FilterMovies, None).handle(); - - assert!(!app.should_ignore_quit_key); - assert!(app.data.radarr_data.movies.filtered_items.is_none()); - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::FilterMoviesError.into() - ); - } - #[test] fn test_update_all_movies_prompt_confirm_submit() { let mut app = App::default(); @@ -815,31 +238,6 @@ mod tests { assert_eq!(app.data.radarr_data.prompt_confirm_action, None); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); } - - #[test] - fn test_movies_sort_prompt_submit() { - let mut app = App::default(); - app.data.radarr_data.movies.sort_asc = true; - app.data.radarr_data.movies.sorting(sort_options()); - app.data.radarr_data.movies.set_items(movies_vec()); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::MoviesSortPrompt.into()); - - let mut expected_vec = movies_vec(); - expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); - expected_vec.reverse(); - - LibraryHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::MoviesSortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - assert_eq!(app.data.radarr_data.movies.items, expected_vec); - } } mod test_handle_esc { @@ -853,52 +251,6 @@ mod tests { const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; - #[rstest] - fn test_search_movie_block_esc( - #[values(ActiveRadarrBlock::SearchMovie, ActiveRadarrBlock::SearchMovieError)] - active_radarr_block: ActiveRadarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(active_radarr_block.into()); - app.data.radarr_data = create_test_radarr_data(); - app.data.radarr_data.movies.search = Some("Test".into()); - - LibraryHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.radarr_data.movies.search, None); - } - - #[rstest] - fn test_filter_movies_block_esc( - #[values(ActiveRadarrBlock::FilterMovies, ActiveRadarrBlock::FilterMoviesError)] - active_radarr_block: ActiveRadarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(active_radarr_block.into()); - app.data.radarr_data = create_test_radarr_data(); - app.data.radarr_data.movies = StatefulTable { - filter: Some("Test".into()), - filtered_items: Some(Vec::new()), - filtered_state: Some(TableState::default()), - ..StatefulTable::default() - }; - app.data.radarr_data.movies.set_items(vec![Movie::default()]); - - LibraryHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.radarr_data.movies.filter, None); - assert_eq!(app.data.radarr_data.movies.filtered_items, None); - assert_eq!(app.data.radarr_data.movies.filtered_state, None); - } - #[test] fn test_update_all_movies_prompt_blocks_esc() { let mut app = App::default(); @@ -918,18 +270,6 @@ mod tests { assert!(!app.data.radarr_data.prompt_confirm); } - #[test] - fn test_movies_sort_prompt_block_esc() { - let mut app = App::default(); - app.data.radarr_data.movies.set_items(movies_vec()); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::MoviesSortPrompt.into()); - - LibraryHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::MoviesSortPrompt, None).handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - } - #[rstest] fn test_default_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); @@ -970,141 +310,6 @@ mod tests { use super::*; - #[test] - fn test_search_movies_key() { - let mut app = App::default(); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::SearchMovie.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.radarr_data.movies.search, - Some(HorizontallyScrollableText::default()) - ); - } - - #[test] - fn test_search_movies_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.radarr_data.movies.search, None); - } - - #[test] - fn test_filter_movies_key() { - let mut app = App::default(); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::FilterMovies.into() - ); - assert!(app.should_ignore_quit_key); - assert!(app.data.radarr_data.movies.filter.is_some()); - } - - #[test] - fn test_filter_movies_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - assert!(!app.should_ignore_quit_key); - assert!(app.data.radarr_data.movies.filter.is_none()); - } - - #[test] - fn test_filter_movies_key_resets_previous_filter() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.data.radarr_data = create_test_radarr_data(); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - app.data.radarr_data.movies.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::FilterMovies.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.radarr_data.movies.filter, - Some(HorizontallyScrollableText::default()) - ); - assert!(app.data.radarr_data.movies.filtered_items.is_none()); - assert!(app.data.radarr_data.movies.filtered_state.is_none()); - } - #[test] fn test_movie_add_key() { let mut app = App::default(); @@ -1276,157 +481,6 @@ mod tests { assert!(!app.should_refresh); } - #[test] - fn test_search_movies_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); - app.data.radarr_data.movies.search = Some("Test".into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveRadarrBlock::SearchMovie, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.movies.search.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_filter_movies_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - app.data.radarr_data.movies.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveRadarrBlock::FilterMovies, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.movies.filter.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_search_movies_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - app.data.radarr_data.movies.search = Some(HorizontallyScrollableText::default()); - - LibraryHandler::with( - Key::Char('h'), - &mut app, - ActiveRadarrBlock::SearchMovie, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.movies.search.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_filter_movies_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - app.data.radarr_data.movies.filter = Some(HorizontallyScrollableText::default()); - - LibraryHandler::with( - Key::Char('h'), - &mut app, - ActiveRadarrBlock::FilterMovies, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.movies.filter.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_sort_key() { - let mut app = App::default(); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::MoviesSortPrompt.into() - ); - assert_eq!( - app.data.radarr_data.movies.sort.as_ref().unwrap().items, - movies_sorting_options() - ); - assert!(!app.data.radarr_data.movies.sort_asc); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::Movies, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - assert!(app.data.radarr_data.movies.sort.is_none()); - } - #[test] fn test_update_all_movies_prompt_confirm() { let mut app = App::default(); @@ -1828,16 +882,4 @@ mod tests { }, ] } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| { - b.title - .text - .to_lowercase() - .cmp(&a.title.text.to_lowercase()) - }), - }] - } } diff --git a/src/handlers/radarr_handlers/library/mod.rs b/src/handlers/radarr_handlers/library/mod.rs index b77c47c..d116e17 100644 --- a/src/handlers/radarr_handlers/library/mod.rs +++ b/src/handlers/radarr_handlers/library/mod.rs @@ -9,13 +9,13 @@ use crate::handlers::radarr_handlers::library::movie_details_handler::MovieDetai use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::handle_table_events; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::models::radarr_models::Movie; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, DELETE_MOVIE_SELECTION_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, LIBRARY_BLOCKS, }; use crate::models::stateful_table::SortOption; -use crate::models::{BlockSelectionState, HorizontallyScrollableText, Scrollable}; +use crate::models::{BlockSelectionState, HorizontallyScrollableText}; use crate::network::radarr_network::RadarrEvent; mod add_movie_handler; @@ -40,7 +40,7 @@ impl<'a, 'b> LibraryHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, 'b> { fn handle(&mut self) { - let movie_table_handling_props = TableHandlingProps::new(ActiveRadarrBlock::Movies.into()) + let movie_table_handling_config = TableHandlingConfig::new(ActiveRadarrBlock::Movies.into()) .sorting_block(ActiveRadarrBlock::MoviesSortPrompt.into()) .sort_by_fn(|a: &Movie, b: &Movie| a.id.cmp(&b.id)) .sort_options(movies_sorting_options()) @@ -51,7 +51,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, ' .filter_error_block(ActiveRadarrBlock::FilterMoviesError.into()) .filter_field_fn(|movie| &movie.title.text); - if !self.handle_movies_table_events(movie_table_handling_props) { + if !self.handle_movies_table_events(movie_table_handling_config) { match self.active_radarr_block { _ if AddMovieHandler::accepts(self.active_radarr_block) => { AddMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context) diff --git a/src/handlers/radarr_handlers/library/movie_details_handler.rs b/src/handlers/radarr_handlers/library/movie_details_handler.rs index 8e096a4..491d755 100644 --- a/src/handlers/radarr_handlers/library/movie_details_handler.rs +++ b/src/handlers/radarr_handlers/library/movie_details_handler.rs @@ -4,7 +4,7 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handle_table_events; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::models::radarr_models::{Credit, MovieHistoryItem, RadarrRelease}; use crate::models::servarr_data::radarr::radarr_data::{ @@ -83,19 +83,19 @@ impl<'a, 'b> MovieDetailsHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<'a, 'b> { fn handle(&mut self) { - let movie_history_table_handling_props = - TableHandlingProps::new(ActiveRadarrBlock::MovieHistory.into()); - let movie_releases_table_handling_props = - TableHandlingProps::new(ActiveRadarrBlock::ManualSearch.into()) + let movie_history_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::MovieHistory.into()); + let movie_releases_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::ManualSearch.into()) .sorting_block(ActiveRadarrBlock::ManualSearchSortPrompt.into()) .sort_options(releases_sorting_options()); - let movie_cast_table_handling_props = TableHandlingProps::new(ActiveRadarrBlock::Cast.into()); - let movie_crew_table_handling_props = TableHandlingProps::new(ActiveRadarrBlock::Crew.into()); + let movie_cast_table_handling_config = TableHandlingConfig::new(ActiveRadarrBlock::Cast.into()); + let movie_crew_table_handling_config = TableHandlingConfig::new(ActiveRadarrBlock::Crew.into()); - if !self.handle_movie_history_table_events(movie_history_table_handling_props) - && !self.handle_movie_releases_table_events(movie_releases_table_handling_props) - && !self.handle_movie_cast_table_events(movie_cast_table_handling_props) - && !self.handle_movie_crew_table_events(movie_crew_table_handling_props) + if !self.handle_movie_history_table_events(movie_history_table_handling_config) + && !self.handle_movie_releases_table_events(movie_releases_table_handling_config) + && !self.handle_movie_cast_table_events(movie_cast_table_handling_config) + && !self.handle_movie_crew_table_events(movie_crew_table_handling_config) { self.handle_key_event(); } diff --git a/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs b/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs index 319ced6..4f7e0ab 100644 --- a/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs +++ b/src/handlers/radarr_handlers/library/movie_details_handler_tests.rs @@ -19,15 +19,12 @@ mod tests { use crate::models::servarr_data::radarr::modals::MovieDetailsModal; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; use crate::models::servarr_models::{Language, Quality, QualityWrapper}; - use crate::models::stateful_table::SortOption; use crate::models::{HorizontallyScrollableText, ScrollableText}; mod test_handle_scroll_up_and_down { - use pretty_assertions::{assert_eq, assert_str_eq}; - use rstest::rstest; + use pretty_assertions::assert_eq; use crate::models::servarr_data::radarr::modals::MovieDetailsModal; - use crate::simple_stateful_iterable_vec; use super::*; @@ -129,439 +126,9 @@ mod tests { 0 ); } - - #[rstest] - fn test_movie_history_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::MovieHistory.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_history - .set_items(simple_stateful_iterable_vec!( - MovieHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::MovieHistory, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 2" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::MovieHistory, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_movie_history_scroll_no_op_if_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_history - .set_items(simple_stateful_iterable_vec!( - MovieHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::MovieHistory, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::MovieHistory, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_cast_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Cast.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_cast - .set_items(simple_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Cast, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 2" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Cast, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 1" - ); - } - - #[rstest] - fn test_cast_scroll_no_op_if_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_cast - .set_items(simple_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Cast, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 1" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Cast, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 1" - ); - } - - #[rstest] - fn test_crew_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Crew.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_crew - .set_items(simple_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Crew, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 2" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Crew, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 1" - ); - } - - #[rstest] - fn test_crew_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_crew - .set_items(simple_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Crew, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 1" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::Crew, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 1" - ); - } - - #[rstest] - fn test_manual_search_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_releases - .set_items(simple_stateful_iterable_vec!( - RadarrRelease, - HorizontallyScrollableText - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::ManualSearch, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 2" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::ManualSearch, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_manual_search_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_releases - .set_items(simple_stateful_iterable_vec!( - RadarrRelease, - HorizontallyScrollableText - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::ManualSearch, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 1" - ); - - MovieDetailsHandler::with(key, &mut app, ActiveRadarrBlock::ManualSearch, None).handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_manual_search_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let release_field_vec = sort_options(); - let mut app = App::default(); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal.movie_releases.sorting(sort_options()); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - if key == Key::Up { - for i in (0..release_field_vec.len()).rev() { - MovieDetailsHandler::with( - key, - &mut app, - ActiveRadarrBlock::ManualSearchSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .sort - .as_ref() - .unwrap() - .current_selection(), - &release_field_vec[i] - ); - } - } else { - for i in 0..release_field_vec.len() { - MovieDetailsHandler::with( - key, - &mut app, - ActiveRadarrBlock::ManualSearchSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .sort - .as_ref() - .unwrap() - .current_selection(), - &release_field_vec[(i + 1) % release_field_vec.len()] - ); - } - } - } } mod test_handle_home_end { - use crate::extended_stateful_iterable_vec; use crate::models::servarr_data::radarr::modals::MovieDetailsModal; use super::*; @@ -666,507 +233,6 @@ mod tests { 0 ); } - - #[test] - fn test_movie_history_home_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::MovieHistory.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_history - .set_items(extended_stateful_iterable_vec!( - MovieHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::MovieHistory, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 3" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::MovieHistory, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_movie_history_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_history - .set_items(extended_stateful_iterable_vec!( - MovieHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::MovieHistory, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::MovieHistory, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_cast_home_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Cast.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_cast - .set_items(extended_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Cast, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 3" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Cast, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 1" - ); - } - - #[test] - fn test_cast_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_cast - .set_items(extended_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Cast, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 1" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Cast, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_cast - .current_selection() - .person_name, - "Test 1" - ); - } - - #[test] - fn test_crew_home_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::Crew.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_crew - .set_items(extended_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Crew, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 3" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Crew, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 1" - ); - } - - #[test] - fn test_crew_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_crew - .set_items(extended_stateful_iterable_vec!(Credit, String, person_name)); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::Crew, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 1" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::Crew, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_crew - .current_selection() - .person_name, - "Test 1" - ); - } - - #[test] - fn test_manual_search_home_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into()); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_releases - .set_items(extended_stateful_iterable_vec!( - RadarrRelease, - HorizontallyScrollableText - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::ManualSearch, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 3" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::ManualSearch, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_manual_search_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal - .movie_releases - .set_items(extended_stateful_iterable_vec!( - RadarrRelease, - HorizontallyScrollableText - )); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::ManualSearch, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 1" - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::ManualSearch, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_manual_search_sort_home_end() { - let release_field_vec = sort_options(); - let mut app = App::default(); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal.movie_releases.sorting(sort_options()); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::ManualSearchSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .sort - .as_ref() - .unwrap() - .current_selection(), - &release_field_vec[release_field_vec.len() - 1] - ); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::ManualSearchSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .sort - .as_ref() - .unwrap() - .current_selection(), - &release_field_vec[0] - ); - } } mod test_handle_left_right_action { @@ -1355,45 +421,6 @@ mod tests { ); assert_eq!(app.data.radarr_data.prompt_confirm_action, None); } - - #[test] - fn test_manual_search_sort_prompt_submit() { - let mut app = App::default(); - let mut movie_details_modal = MovieDetailsModal::default(); - movie_details_modal.movie_releases.sort_asc = true; - movie_details_modal.movie_releases.sorting(sort_options()); - movie_details_modal.movie_releases.set_items(release_vec()); - app.data.radarr_data.movie_details_modal = Some(movie_details_modal); - app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into()); - app.push_navigation_stack(ActiveRadarrBlock::ManualSearchSortPrompt.into()); - - let mut expected_vec = release_vec(); - expected_vec.reverse(); - - MovieDetailsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveRadarrBlock::ManualSearchSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::ManualSearch.into() - ); - assert_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .items, - expected_vec - ); - } } mod test_handle_esc { @@ -1437,7 +464,7 @@ mod tests { #[values( ActiveRadarrBlock::AutomaticallySearchMoviePrompt, ActiveRadarrBlock::UpdateAndScanPrompt, - ActiveRadarrBlock::ManualSearchConfirmPrompt, + ActiveRadarrBlock::ManualSearchConfirmPrompt )] prompt_block: ActiveRadarrBlock, #[values(true, false)] is_ready: bool, @@ -1454,18 +481,6 @@ mod tests { assert!(!app.data.radarr_data.prompt_confirm); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); } - - #[rstest] - fn test_manual_search_sort_prompt_esc() { - let mut app = App::default(); - app.data.radarr_data = create_test_radarr_data(); - app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); - app.push_navigation_stack(ActiveRadarrBlock::ManualSearchSortPrompt.into()); - - MovieDetailsHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::ManualSearchSortPrompt, None).handle(); - - assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); - } } mod test_handle_key_char { @@ -1474,7 +489,6 @@ mod tests { use rstest::rstest; use strum::IntoEnumIterator; - use crate::handlers::radarr_handlers::library::movie_details_handler::releases_sorting_options; use crate::models::radarr_models::RadarrRelease; use crate::models::radarr_models::{MinimumAvailability, Movie}; use crate::models::servarr_data::radarr::modals::MovieDetailsModal; @@ -1559,76 +573,6 @@ mod tests { assert_eq!(app.get_current_route(), active_radarr_block.into()); } - #[test] - fn test_sort_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into()); - let mut modal = MovieDetailsModal::default(); - modal.movie_releases.set_items(release_vec()); - app.data.radarr_data.movie_details_modal = Some(modal); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::ManualSearch, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::ManualSearchSortPrompt.into() - ); - assert_eq!( - app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .sort - .as_ref() - .unwrap() - .items, - releases_sorting_options() - ); - assert!( - !app - .data - .radarr_data - .movie_details_modal - .as_ref() - .unwrap() - .movie_releases - .sort_asc - ); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into()); - app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { - movie_details: ScrollableText::with_string("test".to_owned()), - ..MovieDetailsModal::default() - }); - - MovieDetailsHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveRadarrBlock::ManualSearch, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveRadarrBlock::ManualSearch.into() - ); - } - #[rstest] fn test_edit_key( #[values( @@ -2249,11 +1193,4 @@ mod tests { vec![release_a, release_b, release_c] } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| a.age.cmp(&b.age)), - }] - } } diff --git a/src/handlers/radarr_handlers/root_folders/mod.rs b/src/handlers/radarr_handlers/root_folders/mod.rs index 841b762..6ffc3f0 100644 --- a/src/handlers/radarr_handlers/root_folders/mod.rs +++ b/src/handlers/radarr_handlers/root_folders/mod.rs @@ -2,11 +2,11 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; use crate::models::servarr_models::RootFolder; -use crate::models::{HorizontallyScrollableText, Scrollable}; +use crate::models::HorizontallyScrollableText; use crate::network::radarr_network::RadarrEvent; use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys}; @@ -32,10 +32,10 @@ impl<'a, 'b> RootFoldersHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'a, 'b> { fn handle(&mut self) { - let root_folder_table_handling_props = - TableHandlingProps::new(ActiveRadarrBlock::RootFolders.into()); + let root_folder_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::RootFolders.into()); - if !self.handle_root_folders_table_events(root_folder_table_handling_props) { + if !self.handle_root_folders_table_events(root_folder_table_handling_config) { self.handle_key_event(); } } diff --git a/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs b/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs index 670eb9e..420204a 100644 --- a/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs +++ b/src/handlers/radarr_handlers/root_folders/root_folders_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::assert_str_eq; use strum::IntoEnumIterator; use crate::app::key_binding::DEFAULT_KEYBINDINGS; @@ -12,110 +11,12 @@ mod tests { use crate::models::servarr_models::RootFolder; use crate::models::HorizontallyScrollableText; - mod test_handle_scroll_up_and_down { - use rstest::rstest; - - use crate::models::servarr_models::RootFolder; - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_root_folders_scroll, - RootFoldersHandler, - radarr_data, - root_folders, - simple_stateful_iterable_vec!(RootFolder, String, path), - ActiveRadarrBlock::RootFolders, - None, - path - ); - - #[rstest] - fn test_root_folders_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .root_folders - .set_items(simple_stateful_iterable_vec!(RootFolder, String, path)); - - RootFoldersHandler::with(key, &mut app, ActiveRadarrBlock::RootFolders, None).handle(); - - assert_str_eq!( - app.data.radarr_data.root_folders.current_selection().path, - "Test 1" - ); - - RootFoldersHandler::with(key, &mut app, ActiveRadarrBlock::RootFolders, None).handle(); - - assert_str_eq!( - app.data.radarr_data.root_folders.current_selection().path, - "Test 1" - ); - } - } - mod test_handle_home_end { + use pretty_assertions::assert_eq; use std::sync::atomic::Ordering; - use pretty_assertions::assert_eq; - - use crate::models::servarr_models::RootFolder; - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - use super::*; - - test_iterable_home_and_end!( - test_root_folders_home_end, - RootFoldersHandler, - radarr_data, - root_folders, - extended_stateful_iterable_vec!(RootFolder, String, path), - ActiveRadarrBlock::RootFolders, - None, - path - ); - - #[test] - fn test_root_folders_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .radarr_data - .root_folders - .set_items(extended_stateful_iterable_vec!(RootFolder, String, path)); - - RootFoldersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveRadarrBlock::RootFolders, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.root_folders.current_selection().path, - "Test 1" - ); - - RootFoldersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveRadarrBlock::RootFolders, - None, - ) - .handle(); - - assert_str_eq!( - app.data.radarr_data.root_folders.current_selection().path, - "Test 1" - ); - } + use crate::models::servarr_models::RootFolder; #[test] fn test_add_root_folder_prompt_home_end_keys() { diff --git a/src/handlers/radarr_handlers/system/system_handler_tests.rs b/src/handlers/radarr_handlers/system/system_handler_tests.rs index 8ee7065..46d3cba 100644 --- a/src/handlers/radarr_handlers/system/system_handler_tests.rs +++ b/src/handlers/radarr_handlers/system/system_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::assert_eq; use rstest::rstest; use strum::IntoEnumIterator; diff --git a/src/handlers/sonarr_handlers/blocklist/blocklist_handler_tests.rs b/src/handlers/sonarr_handlers/blocklist/blocklist_handler_tests.rs index 026f842..05a80e6 100644 --- a/src/handlers/sonarr_handlers/blocklist/blocklist_handler_tests.rs +++ b/src/handlers/sonarr_handlers/blocklist/blocklist_handler_tests.rs @@ -14,242 +14,6 @@ mod tests { use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, BLOCKLIST_BLOCKS}; use crate::models::servarr_models::{Language, Quality, QualityWrapper}; use crate::models::sonarr_models::BlocklistItem; - use crate::models::stateful_table::SortOption; - - mod test_handle_scroll_up_and_down { - use pretty_assertions::{assert_eq, assert_str_eq}; - use rstest::rstest; - - use crate::models::sonarr_models::BlocklistItem; - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_blocklist_scroll, - BlocklistHandler, - sonarr_data, - blocklist, - simple_stateful_iterable_vec!(BlocklistItem, String, source_title), - ActiveSonarrBlock::Blocklist, - None, - source_title, - to_string - ); - - #[rstest] - fn test_blocklist_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.is_loading = true; - app - .data - .sonarr_data - .blocklist - .set_items(simple_stateful_iterable_vec!( - BlocklistItem, - String, - source_title - )); - - BlocklistHandler::with(key, &mut app, ActiveSonarrBlock::Blocklist, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - BlocklistHandler::with(key, &mut app, ActiveSonarrBlock::Blocklist, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_blocklist_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let blocklist_field_vec = sort_options(); - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.data.sonarr_data.blocklist.sorting(sort_options()); - - if key == Key::Up { - for i in (0..blocklist_field_vec.len()).rev() { - BlocklistHandler::with(key, &mut app, ActiveSonarrBlock::BlocklistSortPrompt, None) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[i] - ); - } - } else { - for i in 0..blocklist_field_vec.len() { - BlocklistHandler::with(key, &mut app, ActiveSonarrBlock::BlocklistSortPrompt, None) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[(i + 1) % blocklist_field_vec.len()] - ); - } - } - } - } - - mod test_handle_home_end { - use pretty_assertions::{assert_eq, assert_str_eq}; - - use crate::models::sonarr_models::BlocklistItem; - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_blocklist_home_and_end, - BlocklistHandler, - sonarr_data, - blocklist, - extended_stateful_iterable_vec!(BlocklistItem, String, source_title), - ActiveSonarrBlock::Blocklist, - None, - source_title, - to_string - ); - - #[test] - fn test_blocklist_home_and_end_no_op_when_not_ready() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.is_loading = true; - app - .data - .sonarr_data - .blocklist - .set_items(extended_stateful_iterable_vec!( - BlocklistItem, - String, - source_title - )); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::Blocklist, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::Blocklist, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .blocklist - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_blocklist_sort_home_end() { - let blocklist_field_vec = sort_options(); - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.data.sonarr_data.blocklist.sorting(sort_options()); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[blocklist_field_vec.len() - 1] - ); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .blocklist - .sort - .as_ref() - .unwrap() - .current_selection(), - &blocklist_field_vec[0] - ); - } - } mod test_handle_delete { use pretty_assertions::assert_eq; @@ -444,31 +208,6 @@ mod tests { assert_eq!(app.data.sonarr_data.prompt_confirm_action, None); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); } - - #[test] - fn test_blocklist_sort_prompt_submit() { - let mut app = App::default(); - app.data.sonarr_data.blocklist.sort_asc = true; - app.data.sonarr_data.blocklist.sorting(sort_options()); - app.data.sonarr_data.blocklist.set_items(blocklist_vec()); - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.push_navigation_stack(ActiveSonarrBlock::BlocklistSortPrompt.into()); - - let mut expected_vec = blocklist_vec(); - expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); - expected_vec.reverse(); - - BlocklistHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); - assert_eq!(app.data.sonarr_data.blocklist.items, expected_vec); - } } mod test_handle_esc { @@ -520,23 +259,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); } - #[test] - fn test_blocklist_sort_prompt_block_esc() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.push_navigation_stack(ActiveSonarrBlock::BlocklistSortPrompt.into()); - - BlocklistHandler::with( - ESC_KEY, - &mut app, - ActiveSonarrBlock::BlocklistSortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); - } - #[rstest] fn test_default_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); @@ -635,51 +357,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); } - #[test] - fn test_sort_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.data.sonarr_data.blocklist.set_items(blocklist_vec()); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::Blocklist, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::BlocklistSortPrompt.into() - ); - assert_eq!( - app.data.sonarr_data.blocklist.sort.as_ref().unwrap().items, - blocklist_sorting_options() - ); - assert!(!app.data.sonarr_data.blocklist.sort_asc); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); - app.data.sonarr_data.blocklist.set_items(blocklist_vec()); - - BlocklistHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::Blocklist, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); - assert!(app.data.sonarr_data.blocklist.sort.is_none()); - assert!(!app.data.sonarr_data.blocklist.sort_asc); - } - #[rstest] #[case( ActiveSonarrBlock::Blocklist, @@ -931,15 +608,4 @@ mod tests { }, ] } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| { - b.source_title - .to_lowercase() - .cmp(&a.source_title.to_lowercase()) - }), - }] - } } diff --git a/src/handlers/sonarr_handlers/blocklist/mod.rs b/src/handlers/sonarr_handlers/blocklist/mod.rs index c227d4e..5a88c4f 100644 --- a/src/handlers/sonarr_handlers/blocklist/mod.rs +++ b/src/handlers/sonarr_handlers/blocklist/mod.rs @@ -3,12 +3,11 @@ use crate::app::App; use crate::event::Key; use crate::handle_table_events; use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, BLOCKLIST_BLOCKS}; use crate::models::sonarr_models::BlocklistItem; use crate::models::stateful_table::SortOption; -use crate::models::Scrollable; use crate::network::sonarr_network::SonarrEvent; #[cfg(test)] @@ -33,13 +32,13 @@ impl<'a, 'b> BlocklistHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a, 'b> { fn handle(&mut self) { - let blocklist_table_handling_props = - TableHandlingProps::new(ActiveSonarrBlock::Blocklist.into()) + let blocklist_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::Blocklist.into()) .sorting_block(ActiveSonarrBlock::BlocklistSortPrompt.into()) .sort_by_fn(|a: &BlocklistItem, b: &BlocklistItem| a.id.cmp(&b.id)) .sort_options(blocklist_sorting_options()); - if !self.handle_blocklist_table_events(blocklist_table_handling_props) { + if !self.handle_blocklist_table_events(blocklist_table_handling_config) { self.handle_key_event(); } } @@ -70,69 +69,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a, !self.app.is_loading && !self.app.data.sonarr_data.blocklist.is_empty() } - fn handle_scroll_up(&mut self) { - match self.active_sonarr_block { - ActiveSonarrBlock::Blocklist => self.app.data.sonarr_data.blocklist.scroll_up(), - ActiveSonarrBlock::BlocklistSortPrompt => self - .app - .data - .sonarr_data - .blocklist - .sort - .as_mut() - .unwrap() - .scroll_up(), - _ => (), - } - } + fn handle_scroll_up(&mut self) {} - fn handle_scroll_down(&mut self) { - match self.active_sonarr_block { - ActiveSonarrBlock::Blocklist => self.app.data.sonarr_data.blocklist.scroll_down(), - ActiveSonarrBlock::BlocklistSortPrompt => self - .app - .data - .sonarr_data - .blocklist - .sort - .as_mut() - .unwrap() - .scroll_down(), - _ => (), - } - } + fn handle_scroll_down(&mut self) {} - fn handle_home(&mut self) { - match self.active_sonarr_block { - ActiveSonarrBlock::Blocklist => self.app.data.sonarr_data.blocklist.scroll_to_top(), - ActiveSonarrBlock::BlocklistSortPrompt => self - .app - .data - .sonarr_data - .blocklist - .sort - .as_mut() - .unwrap() - .scroll_to_top(), - _ => (), - } - } + fn handle_home(&mut self) {} - fn handle_end(&mut self) { - match self.active_sonarr_block { - ActiveSonarrBlock::Blocklist => self.app.data.sonarr_data.blocklist.scroll_to_bottom(), - ActiveSonarrBlock::BlocklistSortPrompt => self - .app - .data - .sonarr_data - .blocklist - .sort - .as_mut() - .unwrap() - .scroll_to_bottom(), - _ => (), - } - } + fn handle_end(&mut self) {} fn handle_delete(&mut self) { if self.active_sonarr_block == ActiveSonarrBlock::Blocklist { @@ -168,18 +111,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a, self.app.pop_navigation_stack(); } - ActiveSonarrBlock::BlocklistSortPrompt => { - self - .app - .data - .sonarr_data - .blocklist - .items - .sort_by(|a, b| a.id.cmp(&b.id)); - self.app.data.sonarr_data.blocklist.apply_sorting(); - - self.app.pop_navigation_stack(); - } ActiveSonarrBlock::Blocklist => { self .app @@ -215,17 +146,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a, .app .push_navigation_stack(ActiveSonarrBlock::BlocklistClearAllItemsPrompt.into()); } - _ if key == DEFAULT_KEYBINDINGS.sort.key => { - self - .app - .data - .sonarr_data - .blocklist - .sorting(blocklist_sorting_options()); - self - .app - .push_navigation_stack(ActiveSonarrBlock::BlocklistSortPrompt.into()); - } _ => (), }, ActiveSonarrBlock::DeleteBlocklistItemPrompt => { diff --git a/src/handlers/sonarr_handlers/downloads/downloads_handler_tests.rs b/src/handlers/sonarr_handlers/downloads/downloads_handler_tests.rs index 6ed8032..dd2ac0f 100644 --- a/src/handlers/sonarr_handlers/downloads/downloads_handler_tests.rs +++ b/src/handlers/sonarr_handlers/downloads/downloads_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::assert_str_eq; use strum::IntoEnumIterator; use crate::app::key_binding::DEFAULT_KEYBINDINGS; @@ -11,113 +10,6 @@ mod tests { use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS}; use crate::models::sonarr_models::DownloadRecord; - mod test_handle_scroll_up_and_down { - use rstest::rstest; - - use crate::models::sonarr_models::DownloadRecord; - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_downloads_scroll, - DownloadsHandler, - sonarr_data, - downloads, - DownloadRecord, - ActiveSonarrBlock::Downloads, - None, - title - ); - - #[rstest] - fn test_downloads_scroll_no_op_when_not_ready( - #[values( - DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key - )] - key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); - app.is_loading = true; - app - .data - .sonarr_data - .downloads - .set_items(simple_stateful_iterable_vec!(DownloadRecord)); - - DownloadsHandler::with(key, &mut app, ActiveSonarrBlock::Downloads, None).handle(); - - assert_str_eq!( - app.data.sonarr_data.downloads.current_selection().title, - "Test 1" - ); - - DownloadsHandler::with(key, &mut app, ActiveSonarrBlock::Downloads, None).handle(); - - assert_str_eq!( - app.data.sonarr_data.downloads.current_selection().title, - "Test 1" - ); - } - } - - mod test_handle_home_end { - use crate::models::sonarr_models::DownloadRecord; - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_downloads_home_end, - DownloadsHandler, - sonarr_data, - downloads, - DownloadRecord, - ActiveSonarrBlock::Downloads, - None, - title - ); - - #[test] - fn test_downloads_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); - app.is_loading = true; - app - .data - .sonarr_data - .downloads - .set_items(extended_stateful_iterable_vec!(DownloadRecord)); - - DownloadsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::Downloads, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.downloads.current_selection().title, - "Test 1" - ); - - DownloadsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::Downloads, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.downloads.current_selection().title, - "Test 1" - ); - } - } - mod test_handle_delete { use pretty_assertions::assert_eq; diff --git a/src/handlers/sonarr_handlers/downloads/mod.rs b/src/handlers/sonarr_handlers/downloads/mod.rs index 2482d76..6b1fe51 100644 --- a/src/handlers/sonarr_handlers/downloads/mod.rs +++ b/src/handlers/sonarr_handlers/downloads/mod.rs @@ -3,11 +3,10 @@ use crate::app::App; use crate::event::Key; use crate::handle_table_events; use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS}; use crate::models::sonarr_models::DownloadRecord; -use crate::models::Scrollable; use crate::network::sonarr_network::SonarrEvent; #[cfg(test)] @@ -32,10 +31,10 @@ impl<'a, 'b> DownloadsHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for DownloadsHandler<'a, 'b> { fn handle(&mut self) { - let download_table_handling_props = - TableHandlingProps::new(ActiveSonarrBlock::Downloads.into()); + let download_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::Downloads.into()); - if !self.handle_downloads_table_events(download_table_handling_props) { + if !self.handle_downloads_table_events(download_table_handling_config) { self.handle_key_event(); } } diff --git a/src/handlers/sonarr_handlers/history/history_handler_tests.rs b/src/handlers/sonarr_handlers/history/history_handler_tests.rs index b037f37..67fe9df 100644 --- a/src/handlers/sonarr_handlers/history/history_handler_tests.rs +++ b/src/handlers/sonarr_handlers/history/history_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use core::sync::atomic::Ordering::SeqCst; use std::cmp::Ordering; use chrono::DateTime; @@ -15,349 +14,6 @@ mod tests { use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS}; use crate::models::servarr_models::{Language, Quality, QualityWrapper}; use crate::models::sonarr_models::{SonarrHistoryEventType, SonarrHistoryItem}; - use crate::models::stateful_table::SortOption; - use crate::models::HorizontallyScrollableText; - - mod test_handle_scroll_up_and_down { - use pretty_assertions::{assert_eq, assert_str_eq}; - use rstest::rstest; - - use crate::models::sonarr_models::SonarrHistoryItem; - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_history_scroll, - HistoryHandler, - sonarr_data, - history, - simple_stateful_iterable_vec!(SonarrHistoryItem, HorizontallyScrollableText, source_title), - ActiveSonarrBlock::History, - None, - source_title, - to_string - ); - - #[rstest] - fn test_history_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.is_loading = true; - app - .data - .sonarr_data - .history - .set_items(simple_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - - HistoryHandler::with(key, &mut app, ActiveSonarrBlock::History, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - HistoryHandler::with(key, &mut app, ActiveSonarrBlock::History, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_history_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let history_field_vec = sort_options(); - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.data.sonarr_data.history.sorting(sort_options()); - - if key == Key::Up { - for i in (0..history_field_vec.len()).rev() { - HistoryHandler::with(key, &mut app, ActiveSonarrBlock::HistorySortPrompt, None).handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .sort - .as_ref() - .unwrap() - .current_selection(), - &history_field_vec[i] - ); - } - } else { - for i in 0..history_field_vec.len() { - HistoryHandler::with(key, &mut app, ActiveSonarrBlock::HistorySortPrompt, None).handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .sort - .as_ref() - .unwrap() - .current_selection(), - &history_field_vec[(i + 1) % history_field_vec.len()] - ); - } - } - } - } - - mod test_handle_home_end { - use pretty_assertions::{assert_eq, assert_str_eq}; - - use crate::models::sonarr_models::SonarrHistoryItem; - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_history_home_and_end, - HistoryHandler, - sonarr_data, - history, - extended_stateful_iterable_vec!(SonarrHistoryItem, HorizontallyScrollableText, source_title), - ActiveSonarrBlock::History, - None, - source_title, - to_string - ); - - #[test] - fn test_history_home_and_end_no_op_when_not_ready() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.is_loading = true; - app - .data - .sonarr_data - .history - .set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_history_search_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchHistory.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.history.search = Some("Test".into()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SearchHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SearchHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_history_filter_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterHistory.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.history.filter = Some("Test".into()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::FilterHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::FilterHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_history_sort_home_end() { - let history_field_vec = sort_options(); - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.data.sonarr_data.history.sorting(sort_options()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::HistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .sort - .as_ref() - .unwrap() - .current_selection(), - &history_field_vec[history_field_vec.len() - 1] - ); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::HistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .sort - .as_ref() - .unwrap() - .current_selection(), - &history_field_vec[0] - ); - } - } mod test_handle_left_right_action { use pretty_assertions::assert_eq; @@ -411,113 +67,11 @@ mod tests { ActiveSonarrBlock::RootFolders.into() ); } - - #[test] - fn test_history_search_box_left_right_keys() { - let mut app = App::default(); - app.data.sonarr_data.history.set_items(vec![SonarrHistoryItem::default()]); - app.push_navigation_stack(ActiveSonarrBlock::SearchHistory.into()); - app.data.sonarr_data.history.search = Some("Test".into()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveSonarrBlock::SearchHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveSonarrBlock::SearchHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_history_filter_box_left_right_keys() { - let mut app = App::default(); - app.data.sonarr_data.history.set_items(vec![SonarrHistoryItem::default()]); - app.push_navigation_stack(ActiveSonarrBlock::FilterHistory.into()); - app.data.sonarr_data.history.filter = Some("Test".into()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveSonarrBlock::FilterHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveSonarrBlock::FilterHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .history - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } } mod test_handle_submit { use pretty_assertions::assert_eq; - use crate::extended_stateful_iterable_vec; - use super::*; const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key; @@ -547,74 +101,20 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); } + } + + mod test_handle_esc { + use pretty_assertions::assert_eq; + use rstest::rstest; + + use crate::models::servarr_data::sonarr::sonarr_data::sonarr_test_utils::utils::create_test_sonarr_data; + + use super::*; + + const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; #[test] - fn test_search_history_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchHistory.into()); - app - .data - .sonarr_data - .history - .set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.sonarr_data.history.search = Some("Test 2".into()); - - HistoryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchHistory, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .text, - "Test 2" - ); - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - } - - #[test] - fn test_search_history_submit_error_on_no_search_hits() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchHistory.into()); - app - .data - .sonarr_data - .history - .set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.sonarr_data.history.search = Some("Test 5".into()); - - HistoryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchHistory, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .text, - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchHistoryError.into() - ); - } - - #[test] - fn test_search_filtered_history_submit() { + fn test_esc_history_item_details() { let mut app = App::default(); app .data @@ -622,201 +122,6 @@ mod tests { .history .set_items(vec![SonarrHistoryItem::default()]); app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchHistory.into()); - app - .data - .sonarr_data - .history - .set_filtered_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.sonarr_data.history.search = Some("Test 2".into()); - - HistoryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchHistory, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .text, - "Test 2" - ); - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - } - - #[test] - fn test_filter_history_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterHistory.into()); - app - .data - .sonarr_data - .history - .set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.sonarr_data.history.filter = Some("Test".into()); - - HistoryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::FilterHistory, None).handle(); - - assert!(app.data.sonarr_data.history.filtered_items.is_some()); - assert!(!app.should_ignore_quit_key); - assert_eq!( - app - .data - .sonarr_data - .history - .filtered_items - .as_ref() - .unwrap() - .len(), - 3 - ); - assert_str_eq!( - app - .data - .sonarr_data - .history - .current_selection() - .source_title - .text, - "Test 1" - ); - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - } - - #[test] - fn test_filter_history_submit_error_on_no_filter_matches() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterHistory.into()); - app - .data - .sonarr_data - .history - .set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - app.data.sonarr_data.history.filter = Some("Test 5".into()); - - HistoryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::FilterHistory, None).handle(); - - assert!(!app.should_ignore_quit_key); - assert!(app.data.sonarr_data.history.filtered_items.is_none()); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterHistoryError.into() - ); - } - - #[test] - fn test_history_sort_prompt_submit() { - let mut app = App::default(); - app.data.sonarr_data.history.sort_asc = true; - app.data.sonarr_data.history.sorting(sort_options()); - app.data.sonarr_data.history.set_items(history_vec()); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(ActiveSonarrBlock::HistorySortPrompt.into()); - - let mut expected_vec = history_vec(); - expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); - expected_vec.reverse(); - - HistoryHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::HistorySortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - assert_eq!(app.data.sonarr_data.history.items, expected_vec); - } - } - - mod test_handle_esc { - use pretty_assertions::assert_eq; - use ratatui::widgets::TableState; - use rstest::rstest; - - use crate::models::{ - servarr_data::sonarr::sonarr_data::sonarr_test_utils::utils::create_test_sonarr_data, - stateful_table::StatefulTable, - }; - - use super::*; - - const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; - - #[rstest] - fn test_search_history_block_esc( - #[values( - ActiveSonarrBlock::SearchHistory, - ActiveSonarrBlock::SearchHistoryError - )] - active_sonarr_block: ActiveSonarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(active_sonarr_block.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.history.set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.history.search = Some("Test".into()); - - HistoryHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.history.search, None); - } - - #[rstest] - fn test_filter_history_block_esc( - #[values( - ActiveSonarrBlock::FilterHistory, - ActiveSonarrBlock::FilterHistoryError - )] - active_sonarr_block: ActiveSonarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(active_sonarr_block.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.history = StatefulTable { - filter: Some("Test".into()), - filtered_items: Some(Vec::new()), - filtered_state: Some(TableState::default()), - ..StatefulTable::default() - }; - app.data.sonarr_data.history.set_items(vec![SonarrHistoryItem::default()]); - - HistoryHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.history.filter, None); - assert_eq!(app.data.sonarr_data.history.filtered_items, None); - assert_eq!(app.data.sonarr_data.history.filtered_state, None); - } - - #[test] - fn test_esc_history_item_details() { - let mut app = App::default(); - app.data.sonarr_data.history.set_items(vec![SonarrHistoryItem::default()]); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::HistoryItemDetails.into()); HistoryHandler::with( @@ -830,24 +135,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); } - #[test] - fn test_history_sort_prompt_block_esc() { - let mut app = App::default(); - app.data.sonarr_data.history.set_items(vec![SonarrHistoryItem::default()]); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.push_navigation_stack(ActiveSonarrBlock::HistorySortPrompt.into()); - - HistoryHandler::with( - ESC_KEY, - &mut app, - ActiveSonarrBlock::HistorySortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - } - #[rstest] fn test_default_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); @@ -856,7 +143,11 @@ mod tests { app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.history.set_items(vec![SonarrHistoryItem::default()]); + app + .data + .sonarr_data + .history + .set_items(vec![SonarrHistoryItem::default()]); HistoryHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::History, None).handle(); @@ -868,147 +159,8 @@ mod tests { mod test_handle_key_char { use pretty_assertions::assert_eq; - use crate::models::servarr_data::sonarr::sonarr_data::sonarr_test_utils::utils::create_test_sonarr_data; - use super::*; - #[test] - fn test_search_history_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchHistory.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.history.search, - Some(HorizontallyScrollableText::default()) - ); - } - - #[test] - fn test_search_history_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.history.search, None); - } - - #[test] - fn test_filter_history_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterHistory.into() - ); - assert!(app.should_ignore_quit_key); - assert!(app.data.sonarr_data.history.filter.is_some()); - } - - #[test] - fn test_filter_history_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - assert!(!app.should_ignore_quit_key); - assert!(app.data.sonarr_data.history.filter.is_none()); - } - - #[test] - fn test_filter_history_key_resets_previous_filter() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.history.filter = Some("Test".into()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterHistory.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.history.filter, - Some(HorizontallyScrollableText::default()) - ); - assert!(app.data.sonarr_data.history.filtered_items.is_none()); - assert!(app.data.sonarr_data.history.filtered_state.is_none()); - } - #[test] fn test_refresh_history_key() { let mut app = App::default(); @@ -1045,151 +197,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); assert!(!app.should_refresh); } - - #[test] - fn test_search_history_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchHistory.into()); - app.data.sonarr_data.history.search = Some("Test".into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveSonarrBlock::SearchHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.history.search.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_filter_history_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterHistory.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.history.filter = Some("Test".into()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveSonarrBlock::FilterHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.history.filter.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_search_history_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchHistory.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.history.search = Some(HorizontallyScrollableText::default()); - - HistoryHandler::with( - Key::Char('h'), - &mut app, - ActiveSonarrBlock::SearchHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.history.search.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_filter_history_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterHistory.into()); - app - .data - .sonarr_data - .history - .set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.history.filter = Some(HorizontallyScrollableText::default()); - - HistoryHandler::with( - Key::Char('h'), - &mut app, - ActiveSonarrBlock::FilterHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.history.filter.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_sort_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.data.sonarr_data.history.set_items(history_vec()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::HistorySortPrompt.into() - ); - assert_eq!( - app.data.sonarr_data.history.sort.as_ref().unwrap().items, - history_sorting_options() - ); - assert!(!app.data.sonarr_data.history.sort_asc); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::History.into()); - app.data.sonarr_data.history.set_items(history_vec()); - - HistoryHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::History, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); - assert!(app.data.sonarr_data.history.sort.is_none()); - assert!(!app.data.sonarr_data.history.sort_asc); - } } #[test] @@ -1400,16 +407,4 @@ mod tests { }, ] } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| { - b.source_title - .text - .to_lowercase() - .cmp(&a.source_title.text.to_lowercase()) - }), - }] - } } diff --git a/src/handlers/sonarr_handlers/history/mod.rs b/src/handlers/sonarr_handlers/history/mod.rs index c374f23..65ec286 100644 --- a/src/handlers/sonarr_handlers/history/mod.rs +++ b/src/handlers/sonarr_handlers/history/mod.rs @@ -3,12 +3,11 @@ use crate::app::App; use crate::event::Key; use crate::handle_table_events; use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, KeyEventHandler}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS}; use crate::models::sonarr_models::SonarrHistoryItem; use crate::models::stateful_table::SortOption; -use crate::models::Scrollable; #[cfg(test)] #[path = "history_handler_tests.rs"] @@ -32,7 +31,7 @@ impl<'a, 'b> HistoryHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for HistoryHandler<'a, 'b> { fn handle(&mut self) { - let history_table_handling_props = TableHandlingProps::new(ActiveSonarrBlock::History.into()) + let history_table_handling_config = TableHandlingConfig::new(ActiveSonarrBlock::History.into()) .sorting_block(ActiveSonarrBlock::HistorySortPrompt.into()) .sort_by_fn(|a: &SonarrHistoryItem, b: &SonarrHistoryItem| a.id.cmp(&b.id)) .sort_options(history_sorting_options()) @@ -43,7 +42,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for HistoryHandler<'a, ' .filter_error_block(ActiveSonarrBlock::FilterHistoryError.into()) .filter_field_fn(|history| &history.source_title.text); - if !self.handle_history_table_events(history_table_handling_props) { + if !self.handle_history_table_events(history_table_handling_config) { self.handle_key_event(); } } diff --git a/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs b/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs index 826927e..9a4173d 100644 --- a/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs +++ b/src/handlers/sonarr_handlers/indexers/indexers_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::{assert_eq, assert_str_eq}; use rstest::rstest; use strum::IntoEnumIterator; @@ -15,111 +14,6 @@ mod tests { use crate::models::servarr_models::Indexer; use crate::test_handler_delegation; - mod test_handle_scroll_up_and_down { - use rstest::rstest; - - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_indexers_scroll, - IndexersHandler, - sonarr_data, - indexers, - simple_stateful_iterable_vec!(Indexer, String, protocol), - ActiveSonarrBlock::Indexers, - None, - protocol - ); - - #[rstest] - fn test_indexers_scroll_no_op_when_not_ready( - #[values( - DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key - )] - key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); - app.is_loading = true; - app - .data - .sonarr_data - .indexers - .set_items(simple_stateful_iterable_vec!(Indexer, String, protocol)); - - IndexersHandler::with(key, &mut app, ActiveSonarrBlock::Indexers, None).handle(); - - assert_str_eq!( - app.data.sonarr_data.indexers.current_selection().protocol, - "Test 1" - ); - - IndexersHandler::with(key, &mut app, ActiveSonarrBlock::Indexers, None).handle(); - - assert_str_eq!( - app.data.sonarr_data.indexers.current_selection().protocol, - "Test 1" - ); - } - } - - mod test_handle_home_end { - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_indexers_home_end, - IndexersHandler, - sonarr_data, - indexers, - extended_stateful_iterable_vec!(Indexer, String, protocol), - ActiveSonarrBlock::Indexers, - None, - protocol - ); - - #[test] - fn test_indexers_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); - app.is_loading = true; - app - .data - .sonarr_data - .indexers - .set_items(extended_stateful_iterable_vec!(Indexer, String, protocol)); - - IndexersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::Indexers, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.indexers.current_selection().protocol, - "Test 1" - ); - - IndexersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::Indexers, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.indexers.current_selection().protocol, - "Test 1" - ); - } - } - mod test_handle_delete { use pretty_assertions::assert_eq; @@ -515,7 +409,11 @@ mod tests { #[test] fn test_indexer_settings_key() { let mut app = App::default(); - app.data.sonarr_data.indexers.set_items(vec![Indexer::default()]); + app + .data + .sonarr_data + .indexers + .set_items(vec![Indexer::default()]); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app .data diff --git a/src/handlers/sonarr_handlers/indexers/mod.rs b/src/handlers/sonarr_handlers/indexers/mod.rs index 78baf98..72e6908 100644 --- a/src/handlers/sonarr_handlers/indexers/mod.rs +++ b/src/handlers/sonarr_handlers/indexers/mod.rs @@ -6,7 +6,7 @@ use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::sonarr_handlers::indexers::edit_indexer_handler::EditIndexerHandler; use crate::handlers::sonarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler; use crate::handlers::sonarr_handlers::indexers::test_all_indexers_handler::TestAllIndexersHandler; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, EDIT_INDEXER_NZB_SELECTION_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, @@ -14,7 +14,6 @@ use crate::models::servarr_data::sonarr::sonarr_data::{ }; use crate::models::servarr_models::Indexer; use crate::models::BlockSelectionState; -use crate::models::Scrollable; use crate::network::sonarr_network::SonarrEvent; mod edit_indexer_handler; @@ -38,9 +37,10 @@ impl<'a, 'b> IndexersHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for IndexersHandler<'a, 'b> { fn handle(&mut self) { - let indexers_table_handling_props = TableHandlingProps::new(ActiveSonarrBlock::Indexers.into()); + let indexers_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::Indexers.into()); - if !self.handle_indexers_table_events(indexers_table_handling_props) { + if !self.handle_indexers_table_events(indexers_table_handling_config) { match self.active_sonarr_block { _ if EditIndexerHandler::accepts(self.active_sonarr_block) => { EditIndexerHandler::with(self.key, self.app, self.active_sonarr_block, self.context) diff --git a/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler.rs b/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler.rs index cd97b9f..91ff186 100644 --- a/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler.rs +++ b/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler.rs @@ -1,8 +1,10 @@ use crate::app::App; use crate::event::Key; +use crate::handle_table_events; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::KeyEventHandler; +use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock; -use crate::models::Scrollable; #[cfg(test)] #[path = "test_all_indexers_handler_tests.rs"] @@ -15,7 +17,33 @@ pub(super) struct TestAllIndexersHandler<'a, 'b> { _context: Option, } +impl<'a, 'b> TestAllIndexersHandler<'a, 'b> { + handle_table_events!( + self, + indexer_test_all_results, + self + .app + .data + .sonarr_data + .indexer_test_all_results + .as_mut() + .unwrap(), + IndexerTestResultModalItem + ); +} + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for TestAllIndexersHandler<'a, 'b> { + fn handle(&mut self) { + let indexer_test_all_results_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::TestAllIndexers.into()); + + if !self + .handle_indexer_test_all_results_table_events(indexer_test_all_results_table_handling_config) + { + self.handle_key_event(); + } + } + fn accepts(active_block: ActiveSonarrBlock) -> bool { active_block == ActiveSonarrBlock::TestAllIndexers } @@ -48,57 +76,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for TestAllIndexersHandl !self.app.is_loading && table_is_ready } - fn handle_scroll_up(&mut self) { - if self.active_sonarr_block == ActiveSonarrBlock::TestAllIndexers { - self - .app - .data - .sonarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_up() - } - } + fn handle_scroll_up(&mut self) {} - fn handle_scroll_down(&mut self) { - if self.active_sonarr_block == ActiveSonarrBlock::TestAllIndexers { - self - .app - .data - .sonarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_down() - } - } + fn handle_scroll_down(&mut self) {} - fn handle_home(&mut self) { - if self.active_sonarr_block == ActiveSonarrBlock::TestAllIndexers { - self - .app - .data - .sonarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_to_top() - } - } + fn handle_home(&mut self) {} - fn handle_end(&mut self) { - if self.active_sonarr_block == ActiveSonarrBlock::TestAllIndexers { - self - .app - .data - .sonarr_data - .indexer_test_all_results - .as_mut() - .unwrap() - .scroll_to_bottom() - } - } + fn handle_end(&mut self) {} fn handle_delete(&mut self) {} diff --git a/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler_tests.rs b/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler_tests.rs index 7750b4d..be828d1 100644 --- a/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler_tests.rs +++ b/src/handlers/sonarr_handlers/indexers/test_all_indexers_handler_tests.rs @@ -2,7 +2,6 @@ mod tests { use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; - use crate::event::Key; use crate::handlers::sonarr_handlers::indexers::test_all_indexers_handler::TestAllIndexersHandler; use crate::handlers::KeyEventHandler; use crate::models::servarr_data::modals::IndexerTestResultModalItem; @@ -10,224 +9,6 @@ mod tests { use crate::models::stateful_table::StatefulTable; use strum::IntoEnumIterator; - mod test_handle_scroll_up_and_down { - use pretty_assertions::assert_str_eq; - use rstest::rstest; - - use crate::models::servarr_data::modals::IndexerTestResultModalItem; - use crate::models::stateful_table::StatefulTable; - use crate::simple_stateful_iterable_vec; - - use super::*; - - #[rstest] - fn test_test_all_indexers_results_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(simple_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.sonarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with(key, &mut app, ActiveSonarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 2" - ); - - TestAllIndexersHandler::with(key, &mut app, ActiveSonarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - - #[rstest] - fn test_test_all_indexers_results_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); - app.is_loading = true; - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(simple_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.sonarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with(key, &mut app, ActiveSonarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - - TestAllIndexersHandler::with(key, &mut app, ActiveSonarrBlock::TestAllIndexers, None) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - } - - mod test_handle_home_end { - use crate::extended_stateful_iterable_vec; - use crate::models::servarr_data::modals::IndexerTestResultModalItem; - use crate::models::stateful_table::StatefulTable; - use pretty_assertions::assert_str_eq; - - use super::*; - - #[test] - fn test_test_all_indexers_results_home_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(extended_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.sonarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 3" - ); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - - #[test] - fn test_test_all_indexers_results_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); - app.is_loading = true; - let mut indexer_test_results = StatefulTable::default(); - indexer_test_results.set_items(extended_stateful_iterable_vec!( - IndexerTestResultModalItem, - String, - name - )); - app.data.sonarr_data.indexer_test_all_results = Some(indexer_test_results); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - - TestAllIndexersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::TestAllIndexers, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .indexer_test_all_results - .as_ref() - .unwrap() - .current_selection() - .name, - "Test 1" - ); - } - } - mod test_handle_esc { use super::*; use crate::models::stateful_table::StatefulTable; diff --git a/src/handlers/sonarr_handlers/library/add_series_handler.rs b/src/handlers/sonarr_handlers/library/add_series_handler.rs index 03bce76..80d3c35 100644 --- a/src/handlers/sonarr_handlers/library/add_series_handler.rs +++ b/src/handlers/sonarr_handlers/library/add_series_handler.rs @@ -1,11 +1,13 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, ADD_SERIES_BLOCKS, ADD_SERIES_SELECTION_BLOCKS, }; +use crate::models::sonarr_models::AddSeriesSearchResult; use crate::models::{BlockSelectionState, Scrollable}; use crate::network::sonarr_network::SonarrEvent; -use crate::{handle_text_box_keys, handle_text_box_left_right_keys, App, Key}; +use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, App, Key}; #[cfg(test)] #[path = "add_series_handler_tests.rs"] @@ -18,7 +20,31 @@ pub(super) struct AddSeriesHandler<'a, 'b> { _context: Option, } +impl<'a, 'b> AddSeriesHandler<'a, 'b> { + handle_table_events!( + self, + add_searched_series, + self + .app + .data + .sonarr_data + .add_searched_series + .as_mut() + .unwrap(), + AddSeriesSearchResult + ); +} + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for AddSeriesHandler<'a, 'b> { + fn handle(&mut self) { + let add_series_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::AddSeriesSearchResults.into()); + + if !self.handle_add_searched_series_table_events(add_series_table_handling_config) { + self.handle_key_event(); + } + } + fn accepts(active_block: ActiveSonarrBlock) -> bool { ADD_SERIES_BLOCKS.contains(&active_block) } @@ -47,14 +73,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for AddSeriesHandler<'a, fn handle_scroll_up(&mut self) { match self.active_sonarr_block { - ActiveSonarrBlock::AddSeriesSearchResults => self - .app - .data - .sonarr_data - .add_searched_series - .as_mut() - .unwrap() - .scroll_up(), ActiveSonarrBlock::AddSeriesSelectMonitor => self .app .data @@ -107,14 +125,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for AddSeriesHandler<'a, fn handle_scroll_down(&mut self) { match self.active_sonarr_block { - ActiveSonarrBlock::AddSeriesSearchResults => self - .app - .data - .sonarr_data - .add_searched_series - .as_mut() - .unwrap() - .scroll_down(), ActiveSonarrBlock::AddSeriesSelectMonitor => self .app .data @@ -167,14 +177,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for AddSeriesHandler<'a, fn handle_home(&mut self) { match self.active_sonarr_block { - ActiveSonarrBlock::AddSeriesSearchResults => self - .app - .data - .sonarr_data - .add_searched_series - .as_mut() - .unwrap() - .scroll_to_top(), ActiveSonarrBlock::AddSeriesSelectMonitor => self .app .data @@ -243,14 +245,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for AddSeriesHandler<'a, fn handle_end(&mut self) { match self.active_sonarr_block { - ActiveSonarrBlock::AddSeriesSearchResults => self - .app - .data - .sonarr_data - .add_searched_series - .as_mut() - .unwrap() - .scroll_to_bottom(), ActiveSonarrBlock::AddSeriesSelectMonitor => self .app .data diff --git a/src/handlers/sonarr_handlers/library/add_series_handler_tests.rs b/src/handlers/sonarr_handlers/library/add_series_handler_tests.rs index 63d28b2..d00fdf1 100644 --- a/src/handlers/sonarr_handlers/library/add_series_handler_tests.rs +++ b/src/handlers/sonarr_handlers/library/add_series_handler_tests.rs @@ -20,125 +20,11 @@ mod tests { use crate::models::servarr_data::sonarr::modals::AddSeriesModal; use crate::models::servarr_data::sonarr::sonarr_data::ADD_SERIES_SELECTION_BLOCKS; - use crate::models::stateful_table::StatefulTable; use crate::models::BlockSelectionState; use crate::simple_stateful_iterable_vec; use super::*; - #[rstest] - fn test_add_series_search_results_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - let mut add_searched_series = StatefulTable::default(); - add_searched_series.set_items(simple_stateful_iterable_vec!( - AddSeriesSearchResult, - HorizontallyScrollableText - )); - app.data.sonarr_data.add_searched_series = Some(add_searched_series); - - AddSeriesHandler::with( - key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 2" - ); - - AddSeriesHandler::with( - key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_add_series_search_results_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.is_loading = true; - let mut add_searched_series = StatefulTable::default(); - add_searched_series.set_items(simple_stateful_iterable_vec!( - AddSeriesSearchResult, - HorizontallyScrollableText - )); - app.data.sonarr_data.add_searched_series = Some(add_searched_series); - - AddSeriesHandler::with( - key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - - AddSeriesHandler::with( - key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - #[rstest] fn test_add_series_select_monitor_scroll( #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, @@ -486,119 +372,9 @@ mod tests { use crate::extended_stateful_iterable_vec; use crate::models::servarr_data::sonarr::modals::AddSeriesModal; - use crate::models::stateful_table::StatefulTable; use super::*; - #[test] - fn test_add_series_search_results_home_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - let mut add_searched_series = StatefulTable::default(); - add_searched_series.set_items(extended_stateful_iterable_vec!( - AddSeriesSearchResult, - HorizontallyScrollableText - )); - app.data.sonarr_data.add_searched_series = Some(add_searched_series); - - AddSeriesHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 3" - ); - - AddSeriesHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_add_series_search_results_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.is_loading = true; - let mut add_searched_series = StatefulTable::default(); - add_searched_series.set_items(extended_stateful_iterable_vec!( - AddSeriesSearchResult, - HorizontallyScrollableText - )); - app.data.sonarr_data.add_searched_series = Some(add_searched_series); - - AddSeriesHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - - AddSeriesHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::AddSeriesSearchResults, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .add_searched_series - .as_ref() - .unwrap() - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - #[test] fn test_add_series_select_monitor_home_end() { let monitor_vec = Vec::from_iter(SeriesMonitor::iter()); diff --git a/src/handlers/sonarr_handlers/library/library_handler_tests.rs b/src/handlers/sonarr_handlers/library/library_handler_tests.rs index 2e193c2..39aea05 100644 --- a/src/handlers/sonarr_handlers/library/library_handler_tests.rs +++ b/src/handlers/sonarr_handlers/library/library_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use core::sync::atomic::Ordering::SeqCst; use pretty_assertions::{assert_eq, assert_str_eq}; use rstest::rstest; use std::cmp::Ordering; @@ -11,343 +10,13 @@ mod tests { use crate::event::Key; use crate::handlers::sonarr_handlers::library::{series_sorting_options, LibraryHandler}; use crate::handlers::KeyEventHandler; - use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ADD_SERIES_BLOCKS, DELETE_SERIES_BLOCKS, EDIT_SERIES_BLOCKS, LIBRARY_BLOCKS, SERIES_DETAILS_BLOCKS}; + use crate::models::servarr_data::sonarr::sonarr_data::{ + ActiveSonarrBlock, ADD_SERIES_BLOCKS, DELETE_SERIES_BLOCKS, EDIT_SERIES_BLOCKS, LIBRARY_BLOCKS, + SERIES_DETAILS_BLOCKS, + }; use crate::models::sonarr_models::{Series, SeriesStatus, SeriesType}; - use crate::models::stateful_table::SortOption; - use crate::models::HorizontallyScrollableText; use crate::test_handler_delegation; - mod test_handle_scroll_up_and_down { - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - use pretty_assertions::assert_eq; - - use super::*; - - test_iterable_scroll!( - test_series_scroll, - LibraryHandler, - sonarr_data, - series, - simple_stateful_iterable_vec!(Series, HorizontallyScrollableText), - ActiveSonarrBlock::Series, - None, - title, - to_string - ); - - #[rstest] - fn test_series_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.is_loading = true; - app - .data - .sonarr_data - .series - .set_items(simple_stateful_iterable_vec!( - Series, - HorizontallyScrollableText - )); - - LibraryHandler::with(key, &mut app, ActiveSonarrBlock::Series, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series - .current_selection() - .title - .to_string(), - "Test 1" - ); - - LibraryHandler::with(key, &mut app, ActiveSonarrBlock::Series, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[rstest] - fn test_series_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let series_field_vec = sort_options(); - let mut app = App::default(); - app.data.sonarr_data.series.sorting(sort_options()); - - if key == Key::Up { - for i in (0..series_field_vec.len()).rev() { - LibraryHandler::with(key, &mut app, ActiveSonarrBlock::SeriesSortPrompt, None).handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_field_vec[i] - ); - } - } else { - for i in 0..series_field_vec.len() { - LibraryHandler::with(key, &mut app, ActiveSonarrBlock::SeriesSortPrompt, None).handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_field_vec[(i + 1) % series_field_vec.len()] - ); - } - } - } - } - - mod test_handle_home_end { - use pretty_assertions::assert_eq; - - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - - use super::*; - - test_iterable_home_and_end!( - test_series_home_end, - LibraryHandler, - sonarr_data, - series, - extended_stateful_iterable_vec!(Series, HorizontallyScrollableText), - ActiveSonarrBlock::Series, - None, - title, - to_string - ); - - #[test] - fn test_series_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app - .data - .sonarr_data - .series - .set_items(extended_stateful_iterable_vec!( - Series, - HorizontallyScrollableText - )); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series - .current_selection() - .title - .to_string(), - "Test 1" - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series - .current_selection() - .title - .to_string(), - "Test 1" - ); - } - - #[test] - fn test_series_search_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeries.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - app.data.sonarr_data.series.search = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SearchSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SearchSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_series_filter_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeries.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - app.data.sonarr_data.series.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::FilterSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::FilterSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_series_sort_home_end() { - let series_field_vec = sort_options(); - let mut app = App::default(); - app.data.sonarr_data.series.sorting(sort_options()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SeriesSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_field_vec[series_field_vec.len() - 1] - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SeriesSortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_field_vec[0] - ); - } - } - mod test_handle_delete { use pretty_assertions::assert_eq; @@ -471,112 +140,11 @@ mod tests { assert!(!app.data.sonarr_data.prompt_confirm); } - - #[test] - fn test_series_search_box_left_right_keys() { - let mut app = App::default(); - app.data.sonarr_data.series.set_items(vec![Series::default()]); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeries.into()); - app.data.sonarr_data.series.search = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveSonarrBlock::SearchSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveSonarrBlock::SearchSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_series_filter_box_left_right_keys() { - let mut app = App::default(); - app.data.sonarr_data.series.set_items(vec![Series::default()]); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeries.into()); - app.data.sonarr_data.series.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.left.key, - &mut app, - ActiveSonarrBlock::FilterSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 1 - ); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.right.key, - &mut app, - ActiveSonarrBlock::FilterSeries, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } } mod test_handle_submit { use pretty_assertions::assert_eq; - use crate::extended_stateful_iterable_vec; use crate::network::sonarr_network::SonarrEvent; use super::*; @@ -616,156 +184,6 @@ mod tests { assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); } - #[test] - fn test_search_series_submit() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeries.into()); - app - .data - .sonarr_data - .series - .set_items(extended_stateful_iterable_vec!( - Series, - HorizontallyScrollableText - )); - app.data.sonarr_data.series.search = Some("Test 2".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchSeries, None).handle(); - - assert!(!app.should_ignore_quit_key); - assert_str_eq!( - app.data.sonarr_data.series.current_selection().title.text, - "Test 2" - ); - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - } - - #[test] - fn test_search_series_submit_error_on_no_search_hits() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeries.into()); - app - .data - .sonarr_data - .series - .set_items(extended_stateful_iterable_vec!( - Series, - HorizontallyScrollableText - )); - app.data.sonarr_data.series.search = Some("Test 5".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchSeries, None).handle(); - - assert!(!app.should_ignore_quit_key); - assert_str_eq!( - app.data.sonarr_data.series.current_selection().title.text, - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchSeriesError.into() - ); - } - - #[test] - fn test_search_filtered_series_submit() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeries.into()); - app - .data - .sonarr_data - .series - .set_filtered_items(extended_stateful_iterable_vec!( - Series, - HorizontallyScrollableText - )); - app.data.sonarr_data.series.search = Some("Test 2".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchSeries, None).handle(); - - assert!(!app.should_ignore_quit_key); - assert_str_eq!( - app.data.sonarr_data.series.current_selection().title.text, - "Test 2" - ); - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - } - - #[test] - fn test_filter_series_submit() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeries.into()); - app - .data - .sonarr_data - .series - .set_items(extended_stateful_iterable_vec!( - Series, - HorizontallyScrollableText - )); - app.data.sonarr_data.series.filter = Some("Test".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::FilterSeries, None).handle(); - - assert!(app.data.sonarr_data.series.filtered_items.is_some()); - assert!(!app.should_ignore_quit_key); - assert_eq!( - app - .data - .sonarr_data - .series - .filtered_items - .as_ref() - .unwrap() - .len(), - 3 - ); - assert_str_eq!( - app.data.sonarr_data.series.current_selection().title.text, - "Test 1" - ); - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - } - - #[test] - fn test_filter_series_submit_error_on_no_filter_matches() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeries.into()); - app - .data - .sonarr_data - .series - .set_items(extended_stateful_iterable_vec!( - Series, - HorizontallyScrollableText - )); - app.data.sonarr_data.series.filter = Some("Test 5".into()); - - LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::FilterSeries, None).handle(); - - assert!(!app.should_ignore_quit_key); - assert!(app.data.sonarr_data.series.filtered_items.is_none()); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterSeriesError.into() - ); - } - #[test] fn test_update_all_series_prompt_confirm_submit() { let mut app = App::default(); @@ -817,109 +235,17 @@ mod tests { assert_eq!(app.data.sonarr_data.prompt_confirm_action, None); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); } - - #[test] - fn test_series_sort_prompt_submit() { - let mut app = App::default(); - app.data.sonarr_data.series.sort_asc = true; - app.data.sonarr_data.series.sorting(sort_options()); - app.data.sonarr_data.series.set_items(series_vec()); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::SeriesSortPrompt.into()); - - let mut expected_vec = series_vec(); - expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); - expected_vec.reverse(); - - LibraryHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::SeriesSortPrompt, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - assert_eq!(app.data.sonarr_data.series.items, expected_vec); - } } mod test_handle_esc { use pretty_assertions::assert_eq; - use ratatui::widgets::TableState; use crate::models::servarr_data::sonarr::sonarr_data::sonarr_test_utils::utils::create_test_sonarr_data; - use crate::models::stateful_table::StatefulTable; use super::*; const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; - #[rstest] - fn test_search_series_block_esc( - #[values(ActiveSonarrBlock::SearchSeries, ActiveSonarrBlock::SearchSeriesError)] - active_sonarr_block: ActiveSonarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(active_sonarr_block.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.series.search = Some("Test".into()); - app.data.sonarr_data.series.set_items(vec![Series::default()]); - - LibraryHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.series.search, None); - } - - #[test] - fn test_series_block_esc_resets_filter_if_already_set() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.series = StatefulTable { - filter: Some("Test".into()), - filtered_items: Some(Vec::new()), - filtered_state: Some(TableState::default()), - ..StatefulTable::default() - }; - app.data.sonarr_data.series.set_items(vec![Series::default()]); - - LibraryHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::Series, None).handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - assert_eq!(app.data.sonarr_data.series.filter, None); - assert_eq!(app.data.sonarr_data.series.filtered_items, None); - assert_eq!(app.data.sonarr_data.series.filtered_state, None); - } - - #[test] - fn test_filter_series_error_block_esc() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeriesError.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.series = StatefulTable { - filter: Some("Test".into()), - filtered_items: Some(Vec::new()), - filtered_state: Some(TableState::default()), - ..StatefulTable::default() - }; - app.data.sonarr_data.series.set_items(vec![Series::default()]); - - LibraryHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::FilterSeriesError, None).handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.series.filter, None); - assert_eq!(app.data.sonarr_data.series.filtered_items, None); - assert_eq!(app.data.sonarr_data.series.filtered_state, None); - } - #[test] fn test_update_all_series_prompt_blocks_esc() { let mut app = App::default(); @@ -939,18 +265,6 @@ mod tests { assert!(!app.data.sonarr_data.prompt_confirm); } - #[test] - fn test_series_sort_prompt_block_esc() { - let mut app = App::default(); - app.data.sonarr_data.series.set_items(vec![Series::default()]); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.push_navigation_stack(ActiveSonarrBlock::SeriesSortPrompt.into()); - - LibraryHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::SeriesSortPrompt, None).handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - } - #[rstest] fn test_default_esc(#[values(true, false)] is_ready: bool) { let mut app = App::default(); @@ -981,143 +295,6 @@ mod tests { use super::*; - #[test] - fn test_search_series_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchSeries.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.series.search, - Some(HorizontallyScrollableText::default()) - ); - } - - #[test] - fn test_search_series_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.series.search, None); - } - - #[test] - fn test_filter_series_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterSeries.into() - ); - assert!(app.should_ignore_quit_key); - assert!(app.data.sonarr_data.series.filter.is_some()); - } - - #[test] - fn test_filter_series_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - assert!(!app.should_ignore_quit_key); - assert!(app.data.sonarr_data.series.filter.is_none()); - } - - #[test] - fn test_filter_series_key_resets_previous_filter() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - app.data.sonarr_data.series.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterSeries.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.series.filter, - Some(HorizontallyScrollableText::default()) - ); - assert!(app.data.sonarr_data.series.filtered_items.is_none()); - assert!(app.data.sonarr_data.series.filtered_state.is_none()); - } - #[test] fn test_series_add_key() { let mut app = App::default(); @@ -1289,158 +466,6 @@ mod tests { assert!(!app.should_refresh); } - #[test] - fn test_search_series_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeries.into()); - app.data.sonarr_data.series.search = Some("Test".into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveSonarrBlock::SearchSeries, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series.search.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_filter_series_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeries.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - app.data.sonarr_data.series.filter = Some("Test".into()); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveSonarrBlock::FilterSeries, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series.filter.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_search_series_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeries.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - app.data.sonarr_data.series.search = Some(HorizontallyScrollableText::default()); - - LibraryHandler::with( - Key::Char('h'), - &mut app, - ActiveSonarrBlock::SearchSeries, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series.search.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_filter_series_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeries.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - app.data.sonarr_data.series.filter = Some(HorizontallyScrollableText::default()); - - LibraryHandler::with( - Key::Char('h'), - &mut app, - ActiveSonarrBlock::FilterSeries, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series.filter.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_sort_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesSortPrompt.into() - ); - assert_eq!( - app.data.sonarr_data.series.sort.as_ref().unwrap().items, - series_sorting_options() - ); - assert!(!app.data.sonarr_data.series.sort_asc); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::Series.into()); - app - .data - .sonarr_data - .series - .set_items(vec![Series::default()]); - - LibraryHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::Series, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::Series.into()); - assert!(app.data.sonarr_data.series.sort.is_none()); - } - #[test] fn test_update_all_series_prompt_confirm() { let mut app = App::default(); @@ -1852,16 +877,4 @@ mod tests { }, ] } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| { - b.title - .text - .to_lowercase() - .cmp(&a.title.text.to_lowercase()) - }), - }] - } } diff --git a/src/handlers/sonarr_handlers/library/mod.rs b/src/handlers/sonarr_handlers/library/mod.rs index a5ff91e..969ed25 100644 --- a/src/handlers/sonarr_handlers/library/mod.rs +++ b/src/handlers/sonarr_handlers/library/mod.rs @@ -15,7 +15,7 @@ use crate::{ }, sonarr_models::Series, stateful_table::SortOption, - BlockSelectionState, HorizontallyScrollableText, Scrollable, + BlockSelectionState, HorizontallyScrollableText, }, network::sonarr_network::SonarrEvent, }; @@ -23,7 +23,7 @@ use crate::{ use super::handle_change_tab_left_right_keys; use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::handlers::sonarr_handlers::library::series_details_handler::SeriesDetailsHandler; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; mod add_series_handler; mod delete_series_handler; @@ -46,7 +46,7 @@ impl<'a, 'b> LibraryHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for LibraryHandler<'a, 'b> { fn handle(&mut self) { - let series_table_handling_props = TableHandlingProps::new(ActiveSonarrBlock::Series.into()) + let series_table_handling_config = TableHandlingConfig::new(ActiveSonarrBlock::Series.into()) .sorting_block(ActiveSonarrBlock::SeriesSortPrompt.into()) .sort_by_fn(|a: &Series, b: &Series| a.id.cmp(&b.id)) .sort_options(series_sorting_options()) @@ -57,7 +57,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for LibraryHandler<'a, ' .filter_error_block(ActiveSonarrBlock::FilterSeriesError.into()) .filter_field_fn(|series| &series.title.text); - if !self.handle_series_table_events(series_table_handling_props) { + if !self.handle_series_table_events(series_table_handling_config) { match self.active_sonarr_block { _ if AddSeriesHandler::accepts(self.active_sonarr_block) => { AddSeriesHandler::with(self.key, self.app, self.active_sonarr_block, self.context) diff --git a/src/handlers/sonarr_handlers/library/series_details_handler.rs b/src/handlers/sonarr_handlers/library/series_details_handler.rs index 7365481..66bc3c8 100644 --- a/src/handlers/sonarr_handlers/library/series_details_handler.rs +++ b/src/handlers/sonarr_handlers/library/series_details_handler.rs @@ -3,13 +3,13 @@ use crate::app::App; use crate::event::Key; use crate::handle_table_events; use crate::handlers::sonarr_handlers::history::history_sorting_options; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, EDIT_SERIES_SELECTION_BLOCKS, SERIES_DETAILS_BLOCKS, }; use crate::models::sonarr_models::{Season, SonarrHistoryItem}; -use crate::models::{BlockSelectionState, Scrollable}; +use crate::models::BlockSelectionState; use crate::network::sonarr_network::SonarrEvent; #[cfg(test)] @@ -41,8 +41,8 @@ impl<'a, 'b> SeriesDetailsHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SeriesDetailsHandler<'a, 'b> { fn handle(&mut self) { - let season_table_handling_props = - TableHandlingProps::new(ActiveSonarrBlock::SeriesDetails.into()) + let season_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::SeriesDetails.into()) .searching_block(ActiveSonarrBlock::SearchSeason.into()) .search_error_block(ActiveSonarrBlock::SearchSeasonError.into()) .search_field_fn(|season: &Season| { @@ -51,8 +51,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SeriesDetailsHandler .as_ref() .expect("Season was not populated with title in handlers") }); - let series_history_table_handling_props = - TableHandlingProps::new(ActiveSonarrBlock::SeriesHistory.into()) + let series_history_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::SeriesHistory.into()) .sorting_block(ActiveSonarrBlock::SeriesHistorySortPrompt.into()) .sort_options(history_sorting_options()) .sort_by_fn(|a: &SonarrHistoryItem, b: &SonarrHistoryItem| a.id.cmp(&b.id)) @@ -63,8 +63,8 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for SeriesDetailsHandler .filter_error_block(ActiveSonarrBlock::FilterSeriesHistoryError.into()) .filter_field_fn(|history_item: &SonarrHistoryItem| &history_item.source_title.text); - if !self.handle_season_table_events(season_table_handling_props) - && !self.handle_series_history_table_events(series_history_table_handling_props) + if !self.handle_season_table_events(season_table_handling_config) + && !self.handle_series_history_table_events(series_history_table_handling_config) { self.handle_key_event(); } diff --git a/src/handlers/sonarr_handlers/library/series_details_handler_tests.rs b/src/handlers/sonarr_handlers/library/series_details_handler_tests.rs index a5d9a43..76e4244 100644 --- a/src/handlers/sonarr_handlers/library/series_details_handler_tests.rs +++ b/src/handlers/sonarr_handlers/library/series_details_handler_tests.rs @@ -10,522 +10,10 @@ mod tests { }; use crate::models::sonarr_models::Season; use crate::models::sonarr_models::SonarrHistoryItem; - use crate::models::stateful_table::{SortOption, StatefulTable}; - use core::sync::atomic::Ordering::SeqCst; - use pretty_assertions::assert_str_eq; + use crate::models::stateful_table::StatefulTable; use rstest::rstest; use strum::IntoEnumIterator; - mod test_handle_scroll_up_and_down { - use super::*; - use pretty_assertions::assert_eq; - - #[rstest] - fn test_seasons_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app.data.sonarr_data.seasons.set_items(vec![ - Season { - season_number: 1, - ..Season::default() - }, - Season { - season_number: 2, - ..Season::default() - }, - ]); - - SeriesDetailsHandler::with(key, &mut app, ActiveSonarrBlock::SeriesDetails, None).handle(); - - assert_eq!( - app - .data - .sonarr_data - .seasons - .current_selection() - .season_number, - 2 - ); - - SeriesDetailsHandler::with(key, &mut app, ActiveSonarrBlock::SeriesDetails, None).handle(); - - assert_eq!( - app - .data - .sonarr_data - .seasons - .current_selection() - .season_number, - 1 - ); - } - - #[rstest] - fn test_series_history_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![ - SonarrHistoryItem { - source_title: "Test 1".into(), - ..SonarrHistoryItem::default() - }, - SonarrHistoryItem { - source_title: "Test 2".into(), - ..SonarrHistoryItem::default() - }, - ]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with(key, &mut app, ActiveSonarrBlock::SeriesHistory, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .current_selection() - .source_title - .text, - "Test 2" - ); - - SeriesDetailsHandler::with(key, &mut app, ActiveSonarrBlock::SeriesHistory, None).handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .current_selection() - .source_title - .text, - "Test 1" - ); - } - - #[rstest] - fn test_series_history_sort_scroll( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let series_history_item_field_vec = sort_options(); - let mut app = App::default(); - app.data.sonarr_data.series_history = Some(StatefulTable::default()); - app - .data - .sonarr_data - .series_history - .as_mut() - .unwrap() - .sorting(sort_options()); - - if key == Key::Up { - for i in (0..series_history_item_field_vec.len()).rev() { - SeriesDetailsHandler::with( - key, - &mut app, - ActiveSonarrBlock::SeriesHistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_history_item_field_vec[i] - ); - } - } else { - for i in 0..series_history_item_field_vec.len() { - SeriesDetailsHandler::with( - key, - &mut app, - ActiveSonarrBlock::SeriesHistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_history_item_field_vec[(i + 1) % series_history_item_field_vec.len()] - ); - } - } - } - } - - mod test_handle_home_end { - use super::*; - use pretty_assertions::{assert_eq, assert_str_eq}; - - #[test] - fn test_seasons_home_and_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app.data.sonarr_data.seasons.set_items(vec![ - Season { - season_number: 1, - ..Season::default() - }, - Season { - season_number: 2, - ..Season::default() - }, - Season { - season_number: 3, - ..Season::default() - }, - ]); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SeriesDetails, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .seasons - .current_selection() - .season_number, - 3 - ); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SeriesDetails, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .seasons - .current_selection() - .season_number, - 1 - ); - } - - #[test] - fn test_series_history_home_and_end() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![ - SonarrHistoryItem { - source_title: "Test 1".into(), - ..SonarrHistoryItem::default() - }, - SonarrHistoryItem { - source_title: "Test 2".into(), - ..SonarrHistoryItem::default() - }, - SonarrHistoryItem { - source_title: "Test 3".into(), - ..SonarrHistoryItem::default() - }, - ]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .current_selection() - .source_title - .text, - "Test 3" - ); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .current_selection() - .source_title - .text, - "Test 1" - ); - } - - #[test] - fn test_season_search_box_home_end_keys() { - let mut app = App::default(); - app - .data - .sonarr_data - .seasons - .set_items(vec![Season::default()]); - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeason.into()); - app.data.sonarr_data.seasons.search = Some("Test".into()); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SearchSeason, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .seasons - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SearchSeason, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .seasons - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_series_history_search_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - series_history.search = Some("Test".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SearchSeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SearchSeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .search - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_series_history_filter_box_home_end_keys() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - series_history.filter = Some("Test".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::FilterSeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 4 - ); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::FilterSeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filter - .as_ref() - .unwrap() - .offset - .load(SeqCst), - 0 - ); - } - - #[test] - fn test_series_history_sort_home_end() { - let series_history_item_field_vec = sort_options(); - let mut app = App::default(); - let mut series_history = StatefulTable::default(); - series_history.sorting(sort_options()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::SeriesHistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_history_item_field_vec[series_history_item_field_vec.len() - 1] - ); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::SeriesHistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .sort - .as_ref() - .unwrap() - .current_selection(), - &series_history_item_field_vec[0] - ); - } - } - mod test_handle_left_right_actions { use super::*; use pretty_assertions::assert_eq; @@ -597,7 +85,6 @@ mod tests { use pretty_assertions::assert_eq; use crate::extended_stateful_iterable_vec; - use crate::models::HorizontallyScrollableText; use crate::network::sonarr_network::SonarrEvent; use super::*; @@ -743,441 +230,16 @@ mod tests { ); assert_eq!(app.data.sonarr_data.prompt_confirm_action, None); } - - #[test] - fn test_search_seasons_submit() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeason.into()); - app - .data - .sonarr_data - .seasons - .set_items(extended_stateful_iterable_vec!(Season, Option)); - app.data.sonarr_data.seasons.search = Some("Test 2".into()); - - SeriesDetailsHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchSeason, None) - .handle(); - - assert_str_eq!( - app - .data - .sonarr_data - .seasons - .current_selection() - .title - .as_ref() - .unwrap(), - "Test 2" - ); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesDetails.into() - ); - } - - #[test] - fn test_search_seasons_submit_error_on_no_search_hits() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeason.into()); - app - .data - .sonarr_data - .seasons - .set_items(extended_stateful_iterable_vec!(Season, Option)); - app.data.sonarr_data.seasons.search = Some("Test 5".into()); - - SeriesDetailsHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::SearchSeason, None) - .handle(); - - assert!(!app.should_ignore_quit_key); - assert_str_eq!( - app - .data - .sonarr_data - .seasons - .current_selection() - .title - .as_ref() - .unwrap(), - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchSeasonError.into() - ); - } - - #[test] - fn test_search_series_history_submit() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - series_history.search = Some("Test 2".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::SearchSeriesHistory, - None, - ) - .handle(); - - assert!(!app.should_ignore_quit_key); - assert_str_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .current_selection() - .source_title - .text, - "Test 2" - ); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - } - - #[test] - fn test_search_series_history_submit_error_on_no_search_hits() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - series_history.search = Some("Test 5".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::SearchSeriesHistory, - None, - ) - .handle(); - - assert!(!app.should_ignore_quit_key); - assert_str_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .current_selection() - .source_title - .text, - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchSeriesHistoryError.into() - ); - } - - #[test] - fn test_filter_series_history_submit() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - series_history.filter = Some("Test".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::FilterSeriesHistory, - None, - ) - .handle(); - - assert!(app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filtered_items - .is_some()); - assert!(!app.should_ignore_quit_key); - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filtered_items - .as_ref() - .unwrap() - .len(), - 3 - ); - assert_str_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .current_selection() - .source_title - .text, - "Test 1" - ); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - } - - #[test] - fn test_filter_series_history_submit_error_on_no_filter_matches() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(extended_stateful_iterable_vec!( - SonarrHistoryItem, - HorizontallyScrollableText, - source_title - )); - series_history.filter = Some("Test 5".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::FilterSeriesHistory, - None, - ) - .handle(); - - assert!(!app.should_ignore_quit_key); - assert!(app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filtered_items - .is_none()); - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterSeriesHistoryError.into() - ); - } - - #[test] - fn test_series_history_sort_prompt_submit() { - let mut app = App::default(); - let mut series_history = StatefulTable::default(); - let series_history_vec = vec![ - SonarrHistoryItem { - id: 3, - source_title: "Test 1".into(), - ..SonarrHistoryItem::default() - }, - SonarrHistoryItem { - id: 2, - source_title: "Test 2".into(), - ..SonarrHistoryItem::default() - }, - SonarrHistoryItem { - id: 1, - source_title: "Test 3".into(), - ..SonarrHistoryItem::default() - }, - ]; - series_history.set_items(series_history_vec.clone()); - series_history.sorting(sort_options()); - series_history.sort_asc = true; - app.data.sonarr_data.series_history = Some(series_history); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistorySortPrompt.into()); - - let mut expected_vec = series_history_vec; - expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); - expected_vec.reverse(); - - SeriesDetailsHandler::with( - SUBMIT_KEY, - &mut app, - ActiveSonarrBlock::SeriesHistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - assert_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().items, - expected_vec - ); - } } mod test_handle_esc { use super::*; - use crate::models::servarr_data::sonarr::sonarr_data::sonarr_test_utils::utils::create_test_sonarr_data; use crate::models::stateful_table::StatefulTable; use pretty_assertions::assert_eq; use ratatui::widgets::TableState; const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; - #[rstest] - fn test_search_season_block_esc( - #[values(ActiveSonarrBlock::SearchSeason, ActiveSonarrBlock::SearchSeasonError)] - active_sonarr_block: ActiveSonarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app.push_navigation_stack(active_sonarr_block.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.seasons.search = Some("Test".into()); - - SeriesDetailsHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesDetails.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.seasons.search, None); - } - - #[rstest] - fn test_search_series_history_block_esc( - #[values( - ActiveSonarrBlock::SearchSeriesHistory, - ActiveSonarrBlock::SearchSeriesHistoryError - )] - active_sonarr_block: ActiveSonarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(active_sonarr_block.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.series_history.as_mut().unwrap().search = Some("Test".into()); - - SeriesDetailsHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().search, - None - ); - } - - #[rstest] - fn test_filter_series_history_block_esc( - #[values( - ActiveSonarrBlock::FilterSeriesHistory, - ActiveSonarrBlock::FilterSeriesHistoryError - )] - active_sonarr_block: ActiveSonarrBlock, - ) { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(active_sonarr_block.into()); - app.data.sonarr_data = create_test_sonarr_data(); - app.data.sonarr_data.series_history = Some(StatefulTable { - filter: Some("Test".into()), - filtered_items: Some(Vec::new()), - filtered_state: Some(TableState::default()), - ..StatefulTable::default() - }); - - SeriesDetailsHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().filter, - None - ); - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filtered_items, - None - ); - assert_eq!( - app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filtered_state, - None - ); - } - - #[test] - fn test_series_history_sort_prompt_block_esc() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistorySortPrompt.into()); - - SeriesDetailsHandler::with( - ESC_KEY, - &mut app, - ActiveSonarrBlock::SeriesHistorySortPrompt, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - } - #[test] fn test_series_history_details_block_esc() { let mut app = App::default(); @@ -1271,224 +333,14 @@ mod tests { mod test_handle_key_char { use super::*; - use crate::handlers::sonarr_handlers::history::history_sorting_options; use crate::models::servarr_data::sonarr::sonarr_data::sonarr_test_utils::utils::create_test_sonarr_data; use crate::models::servarr_data::sonarr::sonarr_data::SonarrData; use crate::models::sonarr_models::{Series, SeriesType}; - use crate::models::HorizontallyScrollableText; + use crate::network::sonarr_network::SonarrEvent; use crate::test_edit_series_key; use pretty_assertions::{assert_eq, assert_str_eq}; - use ratatui::widgets::TableState; use serde_json::Number; use strum::IntoEnumIterator; - use crate::network::sonarr_network::SonarrEvent; - - #[test] - fn test_search_season_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app - .data - .sonarr_data - .seasons - .set_items(vec![Season::default()]); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::SeriesDetails, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchSeason.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.seasons.search, - Some(HorizontallyScrollableText::default()) - ); - } - - #[test] - fn test_search_season_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); - app - .data - .sonarr_data - .seasons - .set_items(vec![Season::default()]); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::SeriesDetails, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesDetails.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.seasons.search, None); - } - - #[test] - fn test_search_series_history_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SearchSeriesHistory.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().search, - Some(HorizontallyScrollableText::default()) - ); - } - - #[test] - fn test_search_series_history_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.search.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.seasons.search, None); - } - - #[test] - fn test_filter_series_history_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterSeriesHistory.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().filter, - Some(HorizontallyScrollableText::default()) - ); - } - - #[test] - fn test_filter_series_history_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistory.into() - ); - assert!(!app.should_ignore_quit_key); - assert_eq!(app.data.sonarr_data.seasons.filter, None); - } - - #[test] - fn test_filter_series_history_key_resets_previous_filter() { - let mut app = App::default(); - app.should_ignore_quit_key = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - series_history.filter = Some("Test".into()); - series_history.filtered_items = Some(vec![SonarrHistoryItem::default()]); - series_history.filtered_state = Some(TableState::default()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.filter.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::FilterSeriesHistory.into() - ); - assert!(app.should_ignore_quit_key); - assert_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().filter, - Some(HorizontallyScrollableText::default()) - ); - assert!(app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filtered_items - .is_none()); - assert!(app - .data - .sonarr_data - .series_history - .as_ref() - .unwrap() - .filtered_state - .is_none()); - } #[rstest] fn test_series_details_edit_key( @@ -1563,12 +415,9 @@ mod tests { active_sonarr_block, None, ) - .handle(); + .handle(); - assert_eq!( - app.get_current_route(), - active_sonarr_block.into() - ); + assert_eq!(app.get_current_route(), active_sonarr_block.into()); } #[rstest] @@ -1588,7 +437,7 @@ mod tests { active_sonarr_block, None, ) - .handle(); + .handle(); assert_eq!( app.get_current_route(), @@ -1611,12 +460,9 @@ mod tests { active_sonarr_block, None, ) - .handle(); + .handle(); - assert_eq!( - app.get_current_route(), - active_sonarr_block.into() - ); + assert_eq!(app.get_current_route(), active_sonarr_block.into()); } #[rstest] @@ -1637,12 +483,9 @@ mod tests { active_sonarr_block, None, ) - .handle(); + .handle(); - assert_eq!( - app.get_current_route(), - active_sonarr_block.into() - ); + assert_eq!(app.get_current_route(), active_sonarr_block.into()); assert!(app.is_routing); } @@ -1662,208 +505,12 @@ mod tests { active_sonarr_block, None, ) - .handle(); + .handle(); - assert_eq!( - app.get_current_route(), - active_sonarr_block.into() - ); + assert_eq!(app.get_current_route(), active_sonarr_block.into()); assert!(!app.is_routing); } - #[test] - fn test_sort_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_eq!( - app.get_current_route(), - ActiveSonarrBlock::SeriesHistorySortPrompt.into() - ); - assert_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().sort.as_ref().unwrap().items, - history_sorting_options() - ); - assert!(!app.data.sonarr_data.series_history.as_ref().unwrap().sort_asc); - } - - #[test] - fn test_sort_key_no_op_when_not_ready() { - let mut app = App::default(); - app.is_loading = true; - app.push_navigation_stack(ActiveSonarrBlock::SeriesHistory.into()); - app.is_routing = false; - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.sort.key, - &mut app, - ActiveSonarrBlock::SeriesHistory, - None, - ) - .handle(); - - assert_eq!(app.get_current_route(), ActiveSonarrBlock::SeriesHistory.into()); - assert!(app.data.sonarr_data.series_history.as_ref().unwrap().sort.is_none()); - assert!(!app.data.sonarr_data.series_history.as_ref().unwrap().sort_asc); - assert!(!app.is_routing); - } - - #[test] - fn test_search_season_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeason.into()); - app.data.sonarr_data.seasons.search = Some("Test".into()); - app - .data - .sonarr_data - .seasons - .set_items(vec![Season::default()]); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveSonarrBlock::SearchSeason, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.seasons.search.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_search_series_history_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - series_history.search = Some("Test".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveSonarrBlock::SearchSeriesHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().search.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_filter_series_history_box_backspace_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - series_history.filter = Some("Test".into()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - DEFAULT_KEYBINDINGS.backspace.key, - &mut app, - ActiveSonarrBlock::FilterSeriesHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().filter.as_ref().unwrap().text, - "Tes" - ); - } - - #[test] - fn test_search_season_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeason.into()); - app - .data - .sonarr_data - .seasons - .set_items(vec![Season::default()]); - app.data.sonarr_data.seasons.search = Some(HorizontallyScrollableText::default()); - - SeriesDetailsHandler::with( - Key::Char('h'), - &mut app, - ActiveSonarrBlock::SearchSeason, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.seasons.search.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_search_series_history_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::SearchSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - series_history.search = Some(HorizontallyScrollableText::default()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - Key::Char('h'), - &mut app, - ActiveSonarrBlock::SearchSeriesHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().search.as_ref().unwrap().text, - "h" - ); - } - - #[test] - fn test_filter_series_history_box_char_key() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::FilterSeriesHistory.into()); - let mut series_history = StatefulTable::default(); - series_history.set_items(vec![SonarrHistoryItem::default()]); - series_history.filter = Some(HorizontallyScrollableText::default()); - app.data.sonarr_data.series_history = Some(series_history); - - SeriesDetailsHandler::with( - Key::Char('h'), - &mut app, - ActiveSonarrBlock::FilterSeriesHistory, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.series_history.as_ref().unwrap().filter.as_ref().unwrap().text, - "h" - ); - } - #[rstest] #[case( ActiveSonarrBlock::AutomaticallySearchSeriesPrompt, @@ -1876,20 +523,24 @@ mod tests { fn test_series_details_prompt_confirm_confirm_key( #[case] prompt_block: ActiveSonarrBlock, #[case] expected_action: SonarrEvent, - #[values(ActiveSonarrBlock::SeriesDetails, ActiveSonarrBlock::SeriesHistory)] active_sonarr_block: ActiveSonarrBlock, + #[values(ActiveSonarrBlock::SeriesDetails, ActiveSonarrBlock::SeriesHistory)] + active_sonarr_block: ActiveSonarrBlock, ) { let mut app = App::default(); app.data.sonarr_data.prompt_confirm = true; app.push_navigation_stack(active_sonarr_block.into()); app.push_navigation_stack(prompt_block.into()); - SeriesDetailsHandler::with(DEFAULT_KEYBINDINGS.confirm.key, &mut app, prompt_block, None).handle(); + SeriesDetailsHandler::with( + DEFAULT_KEYBINDINGS.confirm.key, + &mut app, + prompt_block, + None, + ) + .handle(); assert!(app.data.sonarr_data.prompt_confirm); - assert_eq!( - app.get_current_route(), - active_sonarr_block.into() - ); + assert_eq!(app.get_current_route(), active_sonarr_block.into()); assert_eq!( app.data.sonarr_data.prompt_confirm_action, Some(expected_action) @@ -1969,16 +620,4 @@ mod tests { assert!(handler.is_ready()); } - - fn sort_options() -> Vec> { - vec![SortOption { - name: "Test 1", - cmp_fn: Some(|a, b| { - b.source_title - .text - .to_lowercase() - .cmp(&a.source_title.text.to_lowercase()) - }), - }] - } } diff --git a/src/handlers/sonarr_handlers/root_folders/mod.rs b/src/handlers/sonarr_handlers/root_folders/mod.rs index 3cb8950..6e1d850 100644 --- a/src/handlers/sonarr_handlers/root_folders/mod.rs +++ b/src/handlers/sonarr_handlers/root_folders/mod.rs @@ -2,11 +2,11 @@ use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::App; use crate::event::Key; use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; -use crate::handlers::table_handler::TableHandlingProps; +use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ROOT_FOLDERS_BLOCKS}; use crate::models::servarr_models::RootFolder; -use crate::models::{HorizontallyScrollableText, Scrollable}; +use crate::models::HorizontallyScrollableText; use crate::network::sonarr_network::SonarrEvent; use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys}; @@ -32,10 +32,10 @@ impl<'a, 'b> RootFoldersHandler<'a, 'b> { impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for RootFoldersHandler<'a, 'b> { fn handle(&mut self) { - let root_folders_table_handling_props = - TableHandlingProps::new(ActiveSonarrBlock::RootFolders.into()); + let root_folders_table_handling_config = + TableHandlingConfig::new(ActiveSonarrBlock::RootFolders.into()); - if !self.handle_root_folders_table_events(root_folders_table_handling_props) { + if !self.handle_root_folders_table_events(root_folders_table_handling_config) { self.handle_key_event(); } } diff --git a/src/handlers/sonarr_handlers/root_folders/root_folders_handler_tests.rs b/src/handlers/sonarr_handlers/root_folders/root_folders_handler_tests.rs index b83da4e..1578234 100644 --- a/src/handlers/sonarr_handlers/root_folders/root_folders_handler_tests.rs +++ b/src/handlers/sonarr_handlers/root_folders/root_folders_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::assert_str_eq; use strum::IntoEnumIterator; use crate::app::key_binding::DEFAULT_KEYBINDINGS; @@ -12,113 +11,13 @@ mod tests { use crate::models::servarr_models::RootFolder; use crate::models::HorizontallyScrollableText; - mod test_handle_scroll_up_and_down { - use rstest::rstest; - - use crate::models::servarr_models::RootFolder; - use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; - - use super::*; - - test_iterable_scroll!( - test_root_folders_scroll, - RootFoldersHandler, - sonarr_data, - root_folders, - simple_stateful_iterable_vec!(RootFolder, String, path), - ActiveSonarrBlock::RootFolders, - None, - path - ); - - #[rstest] - fn test_root_folders_scroll_no_op_when_not_ready( - #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, - ) { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::RootFolders.into()); - app.is_loading = true; - app - .data - .sonarr_data - .root_folders - .set_items(simple_stateful_iterable_vec!(RootFolder, String, path)); - - RootFoldersHandler::with(key, &mut app, ActiveSonarrBlock::RootFolders, None).handle(); - - assert_str_eq!( - app.data.sonarr_data.root_folders.current_selection().path, - "Test 1" - ); - - RootFoldersHandler::with(key, &mut app, ActiveSonarrBlock::RootFolders, None).handle(); - - assert_str_eq!( - app.data.sonarr_data.root_folders.current_selection().path, - "Test 1" - ); - } - } - mod test_handle_home_end { + use crate::models::servarr_models::RootFolder; + use pretty_assertions::assert_eq; use std::sync::atomic::Ordering; - use pretty_assertions::assert_eq; - - use crate::models::servarr_models::RootFolder; - use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; - use super::*; - test_iterable_home_and_end!( - test_root_folders_home_end, - RootFoldersHandler, - sonarr_data, - root_folders, - extended_stateful_iterable_vec!(RootFolder, String, path), - ActiveSonarrBlock::RootFolders, - None, - path - ); - - #[test] - fn test_root_folders_home_end_no_op_when_not_ready() { - let mut app = App::default(); - app.push_navigation_stack(ActiveSonarrBlock::RootFolders.into()); - app.is_loading = true; - app - .data - .sonarr_data - .root_folders - .set_items(extended_stateful_iterable_vec!(RootFolder, String, path)); - - RootFoldersHandler::with( - DEFAULT_KEYBINDINGS.end.key, - &mut app, - ActiveSonarrBlock::RootFolders, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.root_folders.current_selection().path, - "Test 1" - ); - - RootFoldersHandler::with( - DEFAULT_KEYBINDINGS.home.key, - &mut app, - ActiveSonarrBlock::RootFolders, - None, - ) - .handle(); - - assert_str_eq!( - app.data.sonarr_data.root_folders.current_selection().path, - "Test 1" - ); - } - #[test] fn test_add_root_folder_prompt_home_end_keys() { let mut app = App::default(); diff --git a/src/handlers/sonarr_handlers/system/system_handler_tests.rs b/src/handlers/sonarr_handlers/system/system_handler_tests.rs index 3f62287..6843b5e 100644 --- a/src/handlers/sonarr_handlers/system/system_handler_tests.rs +++ b/src/handlers/sonarr_handlers/system/system_handler_tests.rs @@ -1,6 +1,5 @@ #[cfg(test)] mod tests { - use pretty_assertions::assert_eq; use rstest::rstest; use strum::IntoEnumIterator; diff --git a/src/handlers/table_handler.rs b/src/handlers/table_handler.rs index 5a144ee..abe26fe 100644 --- a/src/handlers/table_handler.rs +++ b/src/handlers/table_handler.rs @@ -4,8 +4,12 @@ use derive_setters::Setters; use std::cmp::Ordering; use std::fmt::Debug; +#[cfg(test)] +#[path = "table_handler_tests.rs"] +mod table_handler_tests; + #[derive(Setters)] -pub struct TableHandlingProps +pub struct TableHandlingConfig where T: Clone + PartialEq + Eq + Debug + Default, { @@ -35,36 +39,36 @@ where macro_rules! handle_table_events { ($self:expr, $name:ty, $table:expr, $row:ident) => { paste::paste! { - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { if $self.is_ready() { match $self.key { - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.up.key => $self.[](props), - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.down.key => $self.[](props), - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.home.key => $self.[](props), - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.end.key => $self.[](props), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.up.key => $self.[](config), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.down.key => $self.[](config), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.home.key => $self.[](config), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.end.key => $self.[](config), _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.left.key || $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.right.key => { - $self.[](props) + $self.[](config) } - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.submit.key => $self.[](props), - _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.esc.key => $self.[](props), - _ if props.searching_block.is_some() - && $self.app.get_current_route() == *props.searching_block.as_ref().unwrap() => + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.submit.key => $self.[](config), + _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.esc.key => $self.[](config), + _ if config.searching_block.is_some() + && $self.app.get_current_route() == *config.searching_block.as_ref().unwrap() => { $self.[]() } - _ if props.filtering_block.is_some() - && $self.app.get_current_route() == *props.filtering_block.as_ref().unwrap() => + _ if config.filtering_block.is_some() + && $self.app.get_current_route() == *config.filtering_block.as_ref().unwrap() => { $self.[]() } _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.filter.key - && props.filtering_block.is_some() => $self.[](props), + && config.filtering_block.is_some() => $self.[](config), _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.search.key - && props.searching_block.is_some() => $self.[](props), + && config.searching_block.is_some() => $self.[](config), _ if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.sort.key - && props.sorting_block.is_some() => $self.[](props), + && config.sorting_block.is_some() => $self.[](config), _ => false, } } else { @@ -72,14 +76,16 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { + use $crate::models::Scrollable; + match $self.app.get_current_route() { - _ if props.table_block == $self.app.get_current_route() => { + _ if config.table_block == $self.app.get_current_route() => { $table.scroll_up(); true } - _ if props.sorting_block.is_some() - && $self.app.get_current_route() == *props.sorting_block.as_ref().unwrap() => + _ if config.sorting_block.is_some() + && $self.app.get_current_route() == *config.sorting_block.as_ref().unwrap() => { $table.sort.as_mut().unwrap().scroll_up(); true @@ -88,14 +94,16 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { + use $crate::models::Scrollable; + match $self.app.get_current_route() { - _ if props.table_block == $self.app.get_current_route() => { + _ if config.table_block == $self.app.get_current_route() => { $table.scroll_down(); true } - _ if props.sorting_block.is_some() - && $self.app.get_current_route() == *props.sorting_block.as_ref().unwrap() => + _ if config.sorting_block.is_some() + && $self.app.get_current_route() == *config.sorting_block.as_ref().unwrap() => { $table .sort @@ -108,14 +116,16 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { + use $crate::models::Scrollable; + match $self.app.get_current_route() { - _ if props.table_block == $self.app.get_current_route() => { + _ if config.table_block == $self.app.get_current_route() => { $table.scroll_to_top(); true } - _ if props.sorting_block.is_some() - && $self.app.get_current_route() == *props.sorting_block.as_ref().unwrap() => + _ if config.sorting_block.is_some() + && $self.app.get_current_route() == *config.sorting_block.as_ref().unwrap() => { $table .sort @@ -124,8 +134,8 @@ macro_rules! handle_table_events { .scroll_to_top(); true } - _ if props.searching_block.is_some() - && $self.app.get_current_route() == *props.searching_block.as_ref().unwrap() => + _ if config.searching_block.is_some() + && $self.app.get_current_route() == *config.searching_block.as_ref().unwrap() => { $table .search @@ -134,8 +144,8 @@ macro_rules! handle_table_events { .scroll_home(); true } - _ if props.filtering_block.is_some() - && $self.app.get_current_route() == *props.filtering_block.as_ref().unwrap() => + _ if config.filtering_block.is_some() + && $self.app.get_current_route() == *config.filtering_block.as_ref().unwrap() => { $table .filter @@ -148,14 +158,16 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { + use $crate::models::Scrollable; + match $self.app.get_current_route() { - _ if props.table_block == $self.app.get_current_route() => { + _ if config.table_block == $self.app.get_current_route() => { $table.scroll_to_bottom(); true } - _ if props.sorting_block.is_some() - && $self.app.get_current_route() == *props.sorting_block.as_ref().unwrap() => + _ if config.sorting_block.is_some() + && $self.app.get_current_route() == *config.sorting_block.as_ref().unwrap() => { $table .sort @@ -164,8 +176,8 @@ macro_rules! handle_table_events { .scroll_to_bottom(); true } - _ if props.searching_block.is_some() - && $self.app.get_current_route() == *props.searching_block.as_ref().unwrap() => + _ if config.searching_block.is_some() + && $self.app.get_current_route() == *config.searching_block.as_ref().unwrap() => { $table .search @@ -174,8 +186,8 @@ macro_rules! handle_table_events { .reset_offset(); true } - _ if props.filtering_block.is_some() - && $self.app.get_current_route() == *props.filtering_block.as_ref().unwrap() => + _ if config.filtering_block.is_some() + && $self.app.get_current_route() == *config.filtering_block.as_ref().unwrap() => { $table .filter @@ -188,10 +200,10 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { match $self.app.get_current_route() { - _ if props.searching_block.is_some() - && $self.app.get_current_route() == *props.searching_block.as_ref().unwrap() => + _ if config.searching_block.is_some() + && $self.app.get_current_route() == *config.searching_block.as_ref().unwrap() => { $crate::handle_text_box_left_right_keys!( $self, @@ -200,8 +212,8 @@ macro_rules! handle_table_events { ); true } - _ if props.filtering_block.is_some() - && $self.app.get_current_route() == *props.filtering_block.as_ref().unwrap() => + _ if config.filtering_block.is_some() + && $self.app.get_current_route() == *config.filtering_block.as_ref().unwrap() => { $crate::handle_text_box_left_right_keys!( $self, @@ -214,12 +226,12 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { match $self.app.get_current_route() { - _ if props.sorting_block.is_some() - && $self.app.get_current_route() == *props.sorting_block.as_ref().unwrap() => + _ if config.sorting_block.is_some() + && $self.app.get_current_route() == *config.sorting_block.as_ref().unwrap() => { - if let Some(sort_by_fn) = props.sort_by_fn { + if let Some(sort_by_fn) = config.sort_by_fn { $table.items.sort_by(sort_by_fn); } @@ -228,21 +240,21 @@ macro_rules! handle_table_events { true } - _ if props.searching_block.is_some() - && $self.app.get_current_route() == *props.searching_block.as_ref().unwrap() => + _ if config.searching_block.is_some() + && $self.app.get_current_route() == *config.searching_block.as_ref().unwrap() => { $self.app.pop_navigation_stack(); $self.app.should_ignore_quit_key = false; if $table.search.is_some() { - let search_field_fn = props + let search_field_fn = config .search_field_fn .expect("Search field function is required"); let has_match = $table.apply_search(search_field_fn); if !has_match { $self.app.push_navigation_stack( - props + config .search_error_block .expect("Search error block is undefined"), ); @@ -251,21 +263,21 @@ macro_rules! handle_table_events { true } - _ if props.filtering_block.is_some() - && $self.app.get_current_route() == *props.filtering_block.as_ref().unwrap() => + _ if config.filtering_block.is_some() + && $self.app.get_current_route() == *config.filtering_block.as_ref().unwrap() => { $self.app.pop_navigation_stack(); $self.app.should_ignore_quit_key = false; if $table.filter.is_some() { - let filter_field_fn = props + let filter_field_fn = config .filter_field_fn .expect("Search field function is required"); let has_match = $table.apply_filter(filter_field_fn); if !has_match { $self.app.push_navigation_stack( - props + config .filter_error_block .expect("Search error block is undefined"), ); @@ -278,35 +290,35 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { match $self.app.get_current_route() { - _ if props.sorting_block.is_some() - && $self.app.get_current_route() == *props.sorting_block.as_ref().unwrap() => + _ if config.sorting_block.is_some() + && $self.app.get_current_route() == *config.sorting_block.as_ref().unwrap() => { $self.app.pop_navigation_stack(); true } - _ if (props.searching_block.is_some() - && $self.app.get_current_route() == *props.searching_block.as_ref().unwrap()) - || (props.search_error_block.is_some() - && $self.app.get_current_route() == *props.search_error_block.as_ref().unwrap()) => + _ if (config.searching_block.is_some() + && $self.app.get_current_route() == *config.searching_block.as_ref().unwrap()) + || (config.search_error_block.is_some() + && $self.app.get_current_route() == *config.search_error_block.as_ref().unwrap()) => { $self.app.pop_navigation_stack(); $table.reset_search(); $self.app.should_ignore_quit_key = false; true } - _ if (props.filtering_block.is_some() - && $self.app.get_current_route() == *props.filtering_block.as_ref().unwrap()) - || (props.filter_error_block.is_some() - && $self.app.get_current_route() == *props.filter_error_block.as_ref().unwrap()) => + _ if (config.filtering_block.is_some() + && $self.app.get_current_route() == *config.filtering_block.as_ref().unwrap()) + || (config.filter_error_block.is_some() + && $self.app.get_current_route() == *config.filter_error_block.as_ref().unwrap()) => { $self.app.pop_navigation_stack(); $table.reset_filter(); $self.app.should_ignore_quit_key = false; true } - _ if props.table_block == $self.app.get_current_route() + _ if config.table_block == $self.app.get_current_route() && $table.filtered_items.is_some() => { $table.reset_filter(); @@ -316,11 +328,11 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { - if matches!($self.app.get_current_route(), _ if props.table_block == $self.app.get_current_route()) { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { + if matches!($self.app.get_current_route(), _ if config.table_block == $self.app.get_current_route()) { $self .app - .push_navigation_stack(props.filtering_block.expect("Filtering block is undefined").into()); + .push_navigation_stack(config.filtering_block.expect("Filtering block is undefined").into()); $table.reset_filter(); $table.filter = Some($crate::models::HorizontallyScrollableText::default()); $self.app.should_ignore_quit_key = true; @@ -331,11 +343,11 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { - if matches!($self.app.get_current_route(), _ if props.table_block == $self.app.get_current_route()) { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { + if matches!($self.app.get_current_route(), _ if config.table_block == $self.app.get_current_route()) { $self .app - .push_navigation_stack(props.searching_block.expect("Searching block is undefined")); + .push_navigation_stack(config.searching_block.expect("Searching block is undefined")); $table.search = Some($crate::models::HorizontallyScrollableText::default()); $self.app.should_ignore_quit_key = true; @@ -345,10 +357,10 @@ macro_rules! handle_table_events { } } - fn [](&mut $self, props: $crate::handlers::table_handler::TableHandlingProps<$row>) -> bool { - if matches!($self.app.get_current_route(), _ if props.table_block == $self.app.get_current_route()) { + fn [](&mut $self, config: $crate::handlers::table_handler::TableHandlingConfig<$row>) -> bool { + if matches!($self.app.get_current_route(), _ if config.table_block == $self.app.get_current_route()) { $table.sorting( - props + config .sort_options .as_ref() .expect("Sort options are undefined") @@ -356,7 +368,7 @@ macro_rules! handle_table_events { ); $self .app - .push_navigation_stack(props.sorting_block.expect("Sorting block is undefined")); + .push_navigation_stack(config.sorting_block.expect("Sorting block is undefined")); true } else { false @@ -384,12 +396,12 @@ macro_rules! handle_table_events { }; } -impl TableHandlingProps +impl TableHandlingConfig where T: Clone + PartialEq + Eq + Debug + Default, { pub fn new(table_block: Route) -> Self { - TableHandlingProps { + TableHandlingConfig { sorting_block: None, sort_options: None, sort_by_fn: None, diff --git a/src/handlers/table_handler_tests.rs b/src/handlers/table_handler_tests.rs new file mode 100644 index 0000000..c908454 --- /dev/null +++ b/src/handlers/table_handler_tests.rs @@ -0,0 +1,1221 @@ +#[cfg(test)] +mod tests { + use crate::app::key_binding::DEFAULT_KEYBINDINGS; + use crate::app::App; + use crate::event::Key; + use crate::handle_table_events; + use crate::handlers::table_handler::TableHandlingConfig; + use crate::handlers::KeyEventHandler; + use crate::models::radarr_models::Movie; + use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; + use crate::models::servarr_models::Language; + use crate::models::stateful_table::SortOption; + use rstest::rstest; + + struct TableHandlerUnit<'a, 'b> { + key: Key, + app: &'a mut App<'b>, + active_radarr_block: ActiveRadarrBlock, + _context: Option, + } + + impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for TableHandlerUnit<'a, 'b> { + fn handle(&mut self) { + let movie_table_handling_config = TableHandlingConfig::new(ActiveRadarrBlock::Movies.into()) + .sorting_block(ActiveRadarrBlock::MoviesSortPrompt.into()) + .sort_by_fn(|a: &Movie, b: &Movie| a.id.cmp(&b.id)) + .sort_options(sort_options()) + .searching_block(ActiveRadarrBlock::SearchMovie.into()) + .search_error_block(ActiveRadarrBlock::SearchMovieError.into()) + .search_field_fn(|movie| &movie.title.text) + .filtering_block(ActiveRadarrBlock::FilterMovies.into()) + .filter_error_block(ActiveRadarrBlock::FilterMoviesError.into()) + .filter_field_fn(|movie| &movie.title.text); + let minimal_movie_table_handling_config = + TableHandlingConfig::new(ActiveRadarrBlock::Movies.into()); + + match self.active_radarr_block { + ActiveRadarrBlock::MovieDetails => { + self.handle_movies_table_events(minimal_movie_table_handling_config); + } + _ => { + self.handle_movies_table_events(movie_table_handling_config); + }, + } + } + + fn accepts(_: ActiveRadarrBlock) -> bool { + true + } + + fn with( + key: Key, + app: &'a mut App<'b>, + active_block: ActiveRadarrBlock, + _context: Option, + ) -> Self { + Self { + key, + app, + active_radarr_block: active_block, + _context, + } + } + + fn get_key(&self) -> Key { + self.key + } + + fn is_ready(&self) -> bool { + !self.app.is_loading + } + + fn handle_scroll_up(&mut self) {} + + fn handle_scroll_down(&mut self) {} + + fn handle_home(&mut self) {} + + fn handle_end(&mut self) {} + + fn handle_delete(&mut self) {} + + fn handle_left_right_action(&mut self) {} + + fn handle_submit(&mut self) {} + + fn handle_esc(&mut self) {} + + fn handle_char_key_event(&mut self) {} + } + + impl<'a, 'b> TableHandlerUnit<'a, 'b> { + handle_table_events!(self, movies, self.app.data.radarr_data.movies, Movie); + } + + mod test_handle_scroll_up_and_down { + use super::*; + use crate::models::HorizontallyScrollableText; + use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; + use pretty_assertions::assert_str_eq; + + test_iterable_scroll!( + test_table_scroll, + TableHandlerUnit, + radarr_data, + movies, + simple_stateful_iterable_vec!(Movie, HorizontallyScrollableText), + ActiveRadarrBlock::Movies, + None, + title, + to_string + ); + + #[rstest] + fn test_table_scroll_no_op_when_not_ready( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let mut app = App::default(); + app.is_loading = true; + app + .data + .radarr_data + .movies + .set_items(simple_stateful_iterable_vec!( + Movie, + HorizontallyScrollableText + )); + + TableHandlerUnit::with(key, &mut app, ActiveRadarrBlock::Movies, None).handle(); + + assert_str_eq!( + app + .data + .radarr_data + .movies + .current_selection() + .title + .to_string(), + "Test 1" + ); + + TableHandlerUnit::with(key, &mut app, ActiveRadarrBlock::Movies, None).handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .current_selection() + .title + .to_string(), + "Test 1" + ); + } + + #[rstest] + fn test_table_sort_scroll( + #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, + ) { + let movie_field_vec = sort_options(); + let mut app = App::default(); + app.data.radarr_data.movies.sorting(sort_options()); + + if key == Key::Up { + for i in (0..movie_field_vec.len()).rev() { + TableHandlerUnit::with(key, &mut app, ActiveRadarrBlock::MoviesSortPrompt, None).handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .sort + .as_ref() + .unwrap() + .current_selection(), + &movie_field_vec[i] + ); + } + } else { + for i in 0..movie_field_vec.len() { + TableHandlerUnit::with(key, &mut app, ActiveRadarrBlock::MoviesSortPrompt, None).handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .sort + .as_ref() + .unwrap() + .current_selection(), + &movie_field_vec[(i + 1) % movie_field_vec.len()] + ); + } + } + } + } + + mod test_handle_home_end { + use pretty_assertions::{assert_eq, assert_str_eq}; + use std::sync::atomic::Ordering::SeqCst; + + use super::*; + use crate::models::HorizontallyScrollableText; + use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; + + test_iterable_home_and_end!( + test_table_home_end, + TableHandlerUnit, + radarr_data, + movies, + extended_stateful_iterable_vec!(Movie, HorizontallyScrollableText), + ActiveRadarrBlock::Movies, + None, + title, + to_string + ); + + #[test] + fn test_table_home_end_no_op_when_not_ready() { + let mut app = App::default(); + app.is_loading = true; + app + .data + .radarr_data + .movies + .set_items(extended_stateful_iterable_vec!( + Movie, + HorizontallyScrollableText + )); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.end.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .movies + .current_selection() + .title + .to_string(), + "Test 1" + ); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.home.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_str_eq!( + app + .data + .radarr_data + .movies + .current_selection() + .title + .to_string(), + "Test 1" + ); + } + + #[test] + fn test_movie_search_box_home_end_keys() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.search = Some("Test".into()); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.home.key, + &mut app, + ActiveRadarrBlock::SearchMovie, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .search + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 4 + ); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.end.key, + &mut app, + ActiveRadarrBlock::SearchMovie, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .search + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 0 + ); + } + + #[test] + fn test_movie_filter_box_home_end_keys() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.filter = Some("Test".into()); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.home.key, + &mut app, + ActiveRadarrBlock::FilterMovies, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .filter + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 4 + ); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.end.key, + &mut app, + ActiveRadarrBlock::FilterMovies, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .filter + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 0 + ); + } + + #[test] + fn test_table_sort_home_end() { + let movie_field_vec = sort_options(); + let mut app = App::default(); + app.data.radarr_data.movies.sorting(sort_options()); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.end.key, + &mut app, + ActiveRadarrBlock::MoviesSortPrompt, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .sort + .as_ref() + .unwrap() + .current_selection(), + &movie_field_vec[movie_field_vec.len() - 1] + ); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.home.key, + &mut app, + ActiveRadarrBlock::MoviesSortPrompt, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .sort + .as_ref() + .unwrap() + .current_selection(), + &movie_field_vec[0] + ); + } + } + + mod test_handle_left_right_action { + use pretty_assertions::assert_eq; + use std::sync::atomic::Ordering::SeqCst; + + use super::*; + + #[test] + fn test_movie_search_box_left_right_keys() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.search = Some("Test".into()); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.left.key, + &mut app, + ActiveRadarrBlock::SearchMovie, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .search + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 1 + ); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.right.key, + &mut app, + ActiveRadarrBlock::SearchMovie, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .search + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 0 + ); + } + + #[test] + fn test_movie_filter_box_left_right_keys() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.filter = Some("Test".into()); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.left.key, + &mut app, + ActiveRadarrBlock::FilterMovies, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .filter + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 1 + ); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.right.key, + &mut app, + ActiveRadarrBlock::FilterMovies, + None, + ) + .handle(); + + assert_eq!( + app + .data + .radarr_data + .movies + .filter + .as_ref() + .unwrap() + .offset + .load(SeqCst), + 0 + ); + } + } + + mod test_handle_submit { + use pretty_assertions::{assert_eq, assert_str_eq}; + + use crate::extended_stateful_iterable_vec; + use crate::models::HorizontallyScrollableText; + + use super::*; + + const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key; + + #[test] + fn test_search_movie_submit() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + app + .data + .radarr_data + .movies + .set_items(extended_stateful_iterable_vec!( + Movie, + HorizontallyScrollableText + )); + app.data.radarr_data.movies.search = Some("Test 2".into()); + + TableHandlerUnit::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SearchMovie, None).handle(); + + assert_str_eq!( + app.data.radarr_data.movies.current_selection().title.text, + "Test 2" + ); + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + } + + #[test] + fn test_search_movie_submit_error_on_no_search_hits() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + app + .data + .radarr_data + .movies + .set_items(extended_stateful_iterable_vec!( + Movie, + HorizontallyScrollableText + )); + app.data.radarr_data.movies.search = Some("Test 5".into()); + + TableHandlerUnit::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SearchMovie, None).handle(); + + assert_str_eq!( + app.data.radarr_data.movies.current_selection().title.text, + "Test 1" + ); + assert_eq!( + app.get_current_route(), + ActiveRadarrBlock::SearchMovieError.into() + ); + } + + #[test] + fn test_search_filtered_table_submit() { + let mut app = App::default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + app + .data + .radarr_data + .movies + .set_filtered_items(extended_stateful_iterable_vec!( + Movie, + HorizontallyScrollableText + )); + app.data.radarr_data.movies.search = Some("Test 2".into()); + + TableHandlerUnit::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SearchMovie, None).handle(); + + assert_str_eq!( + app.data.radarr_data.movies.current_selection().title.text, + "Test 2" + ); + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + } + + #[test] + fn test_filter_table_submit() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); + app + .data + .radarr_data + .movies + .set_items(extended_stateful_iterable_vec!( + Movie, + HorizontallyScrollableText + )); + app.data.radarr_data.movies.filter = Some("Test".into()); + + TableHandlerUnit::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::FilterMovies, None).handle(); + + assert!(app.data.radarr_data.movies.filtered_items.is_some()); + assert!(!app.should_ignore_quit_key); + assert_eq!( + app + .data + .radarr_data + .movies + .filtered_items + .as_ref() + .unwrap() + .len(), + 3 + ); + assert_str_eq!( + app.data.radarr_data.movies.current_selection().title.text, + "Test 1" + ); + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + } + + #[test] + fn test_filter_table_submit_error_on_no_filter_matches() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); + app + .data + .radarr_data + .movies + .set_items(extended_stateful_iterable_vec!( + Movie, + HorizontallyScrollableText + )); + app.data.radarr_data.movies.filter = Some("Test 5".into()); + + TableHandlerUnit::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::FilterMovies, None).handle(); + + assert!(!app.should_ignore_quit_key); + assert!(app.data.radarr_data.movies.filtered_items.is_none()); + assert_eq!( + app.get_current_route(), + ActiveRadarrBlock::FilterMoviesError.into() + ); + } + + #[test] + fn test_table_sort_prompt_submit() { + let mut app = App::default(); + app.data.radarr_data.movies.sort_asc = true; + app.data.radarr_data.movies.sorting(sort_options()); + app.data.radarr_data.movies.set_items(movies_vec()); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::MoviesSortPrompt.into()); + + let mut expected_vec = movies_vec(); + expected_vec.sort_by(|a, b| a.id.cmp(&b.id)); + expected_vec.reverse(); + + TableHandlerUnit::with( + SUBMIT_KEY, + &mut app, + ActiveRadarrBlock::MoviesSortPrompt, + None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert_eq!(app.data.radarr_data.movies.items, expected_vec); + } + } + + mod test_handle_esc { + use pretty_assertions::assert_eq; + use ratatui::widgets::TableState; + + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::stateful_table::StatefulTable; + + use super::*; + + const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; + + #[rstest] + fn test_search_movie_block_esc( + #[values(ActiveRadarrBlock::SearchMovie, ActiveRadarrBlock::SearchMovieError)] + active_radarr_block: ActiveRadarrBlock, + ) { + let mut app = App::default(); + app.should_ignore_quit_key = true; + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(active_radarr_block.into()); + app.data.radarr_data = create_test_radarr_data(); + app.data.radarr_data.movies.search = Some("Test".into()); + + TableHandlerUnit::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(!app.should_ignore_quit_key); + assert_eq!(app.data.radarr_data.movies.search, None); + } + + #[rstest] + fn test_filter_table_block_esc( + #[values(ActiveRadarrBlock::FilterMovies, ActiveRadarrBlock::FilterMoviesError)] + active_radarr_block: ActiveRadarrBlock, + ) { + let mut app = App::default(); + app.should_ignore_quit_key = true; + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(active_radarr_block.into()); + app.data.radarr_data = create_test_radarr_data(); + app.data.radarr_data.movies = StatefulTable { + filter: Some("Test".into()), + filtered_items: Some(Vec::new()), + filtered_state: Some(TableState::default()), + ..StatefulTable::default() + }; + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(!app.should_ignore_quit_key); + assert_eq!(app.data.radarr_data.movies.filter, None); + assert_eq!(app.data.radarr_data.movies.filtered_items, None); + assert_eq!(app.data.radarr_data.movies.filtered_state, None); + } + + #[test] + fn test_table_sort_prompt_block_esc() { + let mut app = App::default(); + app.data.radarr_data.movies.set_items(movies_vec()); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::MoviesSortPrompt.into()); + + TableHandlerUnit::with(ESC_KEY, &mut app, ActiveRadarrBlock::MoviesSortPrompt, None).handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + } + } + + mod test_handle_key_char { + use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; + use crate::models::HorizontallyScrollableText; + use pretty_assertions::{assert_eq, assert_str_eq}; + + use super::*; + + #[test] + fn test_search_table_key() { + let mut app = App::default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_eq!( + app.get_current_route(), + ActiveRadarrBlock::SearchMovie.into() + ); + assert!(app.should_ignore_quit_key); + assert_eq!( + app.data.radarr_data.movies.search, + Some(HorizontallyScrollableText::default()) + ); + } + + #[test] + fn test_search_table_key_no_op_when_not_ready() { + let mut app = App::default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(!app.should_ignore_quit_key); + assert_eq!(app.data.radarr_data.movies.search, None); + } + + #[test] + fn test_search_table_key_no_op_when_search_table_block_is_not_defined() { + let mut app = App::default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveRadarrBlock::MovieDetails, + None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(!app.should_ignore_quit_key); + assert_eq!(app.data.radarr_data.movies.search, None); + } + + #[test] + fn test_filter_table_key() { + let mut app = App::default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.filter.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_eq!( + app.get_current_route(), + ActiveRadarrBlock::FilterMovies.into() + ); + assert!(app.should_ignore_quit_key); + assert!(app.data.radarr_data.movies.filter.is_some()); + } + + #[test] + fn test_filter_table_key_no_op_when_not_ready() { + let mut app = App::default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.filter.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(!app.should_ignore_quit_key); + assert!(app.data.radarr_data.movies.filter.is_none()); + } + + #[test] + fn test_filter_table_key_resets_previous_filter() { + let mut app = App::default(); + app.should_ignore_quit_key = true; + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.data.radarr_data = create_test_radarr_data(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.filter = Some("Test".into()); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.filter.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_eq!( + app.get_current_route(), + ActiveRadarrBlock::FilterMovies.into() + ); + assert!(app.should_ignore_quit_key); + assert_eq!( + app.data.radarr_data.movies.filter, + Some(HorizontallyScrollableText::default()) + ); + assert!(app.data.radarr_data.movies.filtered_items.is_none()); + assert!(app.data.radarr_data.movies.filtered_state.is_none()); + } + + #[test] + fn test_filter_table_key_no_op_when_filter_table_block_is_not_defined() { + let mut app = App::default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.filter.key, + &mut app, + ActiveRadarrBlock::MovieDetails, + None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(!app.should_ignore_quit_key); + assert_eq!(app.data.radarr_data.movies.filter, None); + } + + #[test] + fn test_search_table_box_backspace_key() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + app.data.radarr_data.movies.search = Some("Test".into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.backspace.key, + &mut app, + ActiveRadarrBlock::SearchMovie, + None, + ) + .handle(); + + assert_str_eq!( + app.data.radarr_data.movies.search.as_ref().unwrap().text, + "Tes" + ); + } + + #[test] + fn test_filter_table_box_backspace_key() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.filter = Some("Test".into()); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.backspace.key, + &mut app, + ActiveRadarrBlock::FilterMovies, + None, + ) + .handle(); + + assert_str_eq!( + app.data.radarr_data.movies.filter.as_ref().unwrap().text, + "Tes" + ); + } + + #[test] + fn test_search_table_box_char_key() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.search = Some(HorizontallyScrollableText::default()); + + TableHandlerUnit::with( + Key::Char('h'), + &mut app, + ActiveRadarrBlock::SearchMovie, + None, + ) + .handle(); + + assert_str_eq!( + app.data.radarr_data.movies.search.as_ref().unwrap().text, + "h" + ); + } + + #[test] + fn test_filter_table_box_char_key() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.data.radarr_data.movies.filter = Some(HorizontallyScrollableText::default()); + + TableHandlerUnit::with( + Key::Char('h'), + &mut app, + ActiveRadarrBlock::FilterMovies, + None, + ) + .handle(); + + assert_str_eq!( + app.data.radarr_data.movies.filter.as_ref().unwrap().text, + "h" + ); + } + + #[test] + fn test_sort_key() { + let mut app = App::default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.sort.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_eq!( + app.get_current_route(), + ActiveRadarrBlock::MoviesSortPrompt.into() + ); + assert_eq!( + app.data.radarr_data.movies.sort.as_ref().unwrap().items, + sort_options() + ); + assert!(!app.data.radarr_data.movies.sort_asc); + } + + #[test] + fn test_sort_key_no_op_when_not_ready() { + let mut app = App::default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.sort.key, + &mut app, + ActiveRadarrBlock::Movies, + None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(app.data.radarr_data.movies.sort.is_none()); + } + + #[test] + fn test_sort_key_no_op_when_sort_table_block_is_undefined() { + let mut app = App::default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + + TableHandlerUnit::with( + DEFAULT_KEYBINDINGS.sort.key, + &mut app, + ActiveRadarrBlock::MovieDetails, + None, + ) + .handle(); + + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + assert!(app.data.radarr_data.movies.sort.is_none()); + } + } + + fn movies_vec() -> Vec { + vec![ + Movie { + id: 3, + title: "test 1".into(), + original_language: Language { + id: 1, + name: "English".to_owned(), + }, + size_on_disk: 1024, + studio: "Studio 1".to_owned(), + year: 2024, + monitored: false, + runtime: 12.into(), + quality_profile_id: 1, + certification: Some("PG-13".to_owned()), + tags: vec![1.into(), 2.into()], + ..Movie::default() + }, + Movie { + id: 2, + title: "test 2".into(), + original_language: Language { + id: 2, + name: "Chinese".to_owned(), + }, + size_on_disk: 2048, + studio: "Studio 2".to_owned(), + year: 1998, + monitored: false, + runtime: 60.into(), + quality_profile_id: 2, + certification: Some("R".to_owned()), + tags: vec![1.into(), 3.into()], + ..Movie::default() + }, + Movie { + id: 1, + title: "test 3".into(), + original_language: Language { + id: 3, + name: "Japanese".to_owned(), + }, + size_on_disk: 512, + studio: "studio 3".to_owned(), + year: 1954, + monitored: true, + runtime: 120.into(), + quality_profile_id: 3, + certification: Some("G".to_owned()), + tags: vec![2.into(), 3.into()], + ..Movie::default() + }, + ] + } + + fn sort_options() -> Vec> { + vec![SortOption { + name: "Test 1", + cmp_fn: Some(|a, b| { + b.title + .text + .to_lowercase() + .cmp(&a.title.text.to_lowercase()) + }), + }] + } +}