From 52739f4da082795e5dd373e1c1745cb5db98f156 Mon Sep 17 00:00:00 2001 From: Dark-Alex-17 Date: Tue, 8 Aug 2023 10:50:05 -0600 Subject: [PATCH] Added unit tests for the add_movie_handler and added an additional test to radarr handles to ensure proper delegation. Also added a few macros for testing scrolling and home/end in all handlers to make life easier for those tests. --- src/app/mod.rs | 2 +- src/app/radarr.rs | 2 +- src/handlers/mod.rs | 273 ++++++++++- .../radarr_handlers/add_movie_handler.rs | 452 +++++++++++++++++ src/handlers/radarr_handlers/mod.rs | 459 ++++++------------ 5 files changed, 876 insertions(+), 312 deletions(-) diff --git a/src/app/mod.rs b/src/app/mod.rs index d9df804..9fbb6cf 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -66,7 +66,7 @@ impl App { pub fn handle_error(&mut self, error: anyhow::Error) { if self.error.text.is_empty() { - self.error = HorizontallyScrollableText::new(error.to_string()); + self.error = error.to_string().into(); } } diff --git a/src/app/radarr.rs b/src/app/radarr.rs index 28e509f..5caf7ad 100644 --- a/src/app/radarr.rs +++ b/src/app/radarr.rs @@ -413,7 +413,7 @@ mod radarr_data_tests { } #[test] - fn test_rest_search() { + fn test_reset_search() { let mut radarr_data = RadarrData { is_searching: true, search: "test search".to_owned(), diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 5fb6332..312ae4a 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -81,13 +81,8 @@ macro_rules! handle_text_box_keys { } #[cfg(test)] -mod tests { - use rstest::rstest; - - use crate::app::App; - use crate::event::Key; - use crate::handlers::{handle_clear_errors, handle_prompt_toggle}; - +#[macro_use] +mod test_utils { #[macro_export] macro_rules! simple_stateful_iterable_vec { ($name:ident) => { @@ -102,6 +97,18 @@ mod tests { }, ] }; + ($name:ident, $title_ident:ident) => { + vec![ + $name { + title: $title_ident::from("Test 1".to_owned()), + ..$name::default() + }, + $name { + title: $title_ident::from("Test 2".to_owned()), + ..$name::default() + }, + ] + }; } #[macro_export] @@ -122,8 +129,260 @@ mod tests { }, ] }; + ($name:ident, $title_ident:ident) => { + vec![ + $name { + title: $title_ident::from("Test 1".to_owned()), + ..$name::default() + }, + $name { + title: $title_ident::from("Test 2".to_owned()), + ..$name::default() + }, + $name { + title: $title_ident::from("Test 3".to_owned()), + ..$name::default() + }, + ] + }; } + #[macro_export] + macro_rules! test_iterable_scroll { + ($func:ident, $handler:ident, $data_ref:ident, $block:expr) => { + #[rstest] + fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { + let mut app = App::default(); + app + .data + .radarr_data + .$data_ref + .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); + + $handler::with(&key, &mut app, &$block).handle(); + + assert_str_eq!(app.data.radarr_data.$data_ref.current_selection(), "Test 2"); + + $handler::with(&key, &mut app, &$block).handle(); + + assert_str_eq!(app.data.radarr_data.$data_ref.current_selection(), "Test 1"); + } + }; + ($func:ident, $handler:ident, $data_ref:ident, $items:ident, $block:expr, $field:ident) => { + #[rstest] + fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { + let mut app = App::default(); + app + .data + .radarr_data + .$data_ref + .set_items(simple_stateful_iterable_vec!($items)); + + $handler::with(&key, &mut app, &$block).handle(); + + assert_str_eq!( + app.data.radarr_data.$data_ref.current_selection().$field, + "Test 2" + ); + + $handler::with(&key, &mut app, &$block).handle(); + + assert_str_eq!( + app.data.radarr_data.$data_ref.current_selection().$field, + "Test 1" + ); + } + }; + ($func:ident, $handler:ident, $data_ref:ident, $items:expr, $block:expr, $field:ident, $conversion_fn:ident) => { + #[rstest] + fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { + let mut app = App::default(); + app.data.radarr_data.$data_ref.set_items($items); + + $handler::with(&key, &mut app, &$block).handle(); + + assert_str_eq!( + app + .data + .radarr_data + .$data_ref + .current_selection() + .$field + .$conversion_fn(), + "Test 2" + ); + + $handler::with(&key, &mut app, &$block).handle(); + + assert_str_eq!( + app + .data + .radarr_data + .$data_ref + .current_selection() + .$field + .$conversion_fn(), + "Test 1" + ); + } + }; + } + + #[macro_export] + macro_rules! test_enum_scroll { + ($func:ident, $handler:ident, $name:ident, $data_ref:ident, $block:expr) => { + #[rstest] + fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { + let reference_vec = Vec::from_iter($name::iter()); + let mut app = App::default(); + app + .data + .radarr_data + .$data_ref + .set_items(reference_vec.clone()); + + if key == Key::Up { + for i in (0..reference_vec.len()).rev() { + $handler::with(&key, &mut app, &$block).handle(); + + assert_eq!( + app.data.radarr_data.$data_ref.current_selection(), + &reference_vec[i] + ); + } + } else { + for i in 0..reference_vec.len() { + $handler::with(&key, &mut app, &$block).handle(); + + assert_eq!( + app.data.radarr_data.$data_ref.current_selection(), + &reference_vec[(i + 1) % reference_vec.len()] + ); + } + } + } + }; + } + + #[macro_export] + macro_rules! test_iterable_home_and_end { + ($func:ident, $handler:ident, $data_ref:ident, $block:expr) => { + #[test] + fn $func() { + let mut app = App::default(); + app.data.radarr_data.$data_ref.set_items(vec![ + "Test 1".to_owned(), + "Test 2".to_owned(), + "Test 3".to_owned(), + ]); + + $handler::with(&DEFAULT_KEYBINDINGS.end.key, &mut app, &$block).handle(); + + assert_str_eq!(app.data.radarr_data.$data_ref.current_selection(), "Test 3"); + + $handler::with(&DEFAULT_KEYBINDINGS.home.key, &mut app, &$block).handle(); + + assert_str_eq!(app.data.radarr_data.$data_ref.current_selection(), "Test 1"); + } + }; + ($func:ident, $handler:ident, $data_ref:ident, $items:ident, $block:expr, $field:ident) => { + #[test] + fn $func() { + let mut app = App::default(); + app + .data + .radarr_data + .$data_ref + .set_items(extended_stateful_iterable_vec!($items)); + + $handler::with(&DEFAULT_KEYBINDINGS.end.key, &mut app, &$block).handle(); + + assert_str_eq!( + app.data.radarr_data.$data_ref.current_selection().$field, + "Test 3" + ); + + $handler::with(&DEFAULT_KEYBINDINGS.home.key, &mut app, &$block).handle(); + + assert_str_eq!( + app.data.radarr_data.$data_ref.current_selection().$field, + "Test 1" + ); + } + }; + ($func:ident, $handler:ident, $data_ref:ident, $items:expr, $block:expr, $field:ident, $conversion_fn:ident) => { + #[test] + fn $func() { + let mut app = App::default(); + app.data.radarr_data.$data_ref.set_items($items); + + $handler::with(&DEFAULT_KEYBINDINGS.end.key, &mut app, &$block).handle(); + + assert_str_eq!( + app + .data + .radarr_data + .$data_ref + .current_selection() + .$field + .$conversion_fn(), + "Test 3" + ); + + $handler::with(&DEFAULT_KEYBINDINGS.home.key, &mut app, &$block).handle(); + + assert_str_eq!( + app + .data + .radarr_data + .$data_ref + .current_selection() + .$field + .$conversion_fn(), + "Test 1" + ); + } + }; + } + + #[macro_export] + macro_rules! test_enum_home_and_end { + ($func:ident, $handler:ident, $name:ident, $data_ref:ident, $block:expr) => { + #[test] + fn $func() { + let reference_vec = Vec::from_iter($name::iter()); + let mut app = App::default(); + app + .data + .radarr_data + .$data_ref + .set_items(reference_vec.clone()); + + $handler::with(&DEFAULT_KEYBINDINGS.end.key, &mut app, &$block).handle(); + + assert_eq!( + app.data.radarr_data.$data_ref.current_selection(), + &reference_vec[reference_vec.len() - 1] + ); + + $handler::with(&DEFAULT_KEYBINDINGS.home.key, &mut app, &$block).handle(); + + assert_eq!( + app.data.radarr_data.$data_ref.current_selection(), + &reference_vec[0] + ); + } + }; + } +} +#[cfg(test)] +mod tests { + use rstest::rstest; + + use crate::app::App; + use crate::event::Key; + use crate::handlers::{handle_clear_errors, handle_prompt_toggle}; + #[test] fn test_handle_clear_errors() { let mut app = App::default(); diff --git a/src/handlers/radarr_handlers/add_movie_handler.rs b/src/handlers/radarr_handlers/add_movie_handler.rs index 7ddcda9..281e609 100644 --- a/src/handlers/radarr_handlers/add_movie_handler.rs +++ b/src/handlers/radarr_handlers/add_movie_handler.rs @@ -265,3 +265,455 @@ impl<'a> KeyEventHandler<'a, ActiveRadarrBlock> for AddMovieHandler<'a> { } } } + +#[cfg(test)] +mod tests { + use pretty_assertions::assert_str_eq; + + use crate::app::key_binding::DEFAULT_KEYBINDINGS; + use crate::app::radarr::ActiveRadarrBlock; + use crate::app::App; + use crate::event::Key; + use crate::handlers::radarr_handlers::add_movie_handler::AddMovieHandler; + use crate::handlers::KeyEventHandler; + use crate::models::radarr_models::{AddMovieSearchResult, MinimumAvailability, Monitor}; + use crate::models::HorizontallyScrollableText; + + mod test_handle_scroll_up_and_down { + use pretty_assertions::assert_eq; + use rstest::rstest; + use strum::IntoEnumIterator; + + use crate::{simple_stateful_iterable_vec, test_enum_scroll, test_iterable_scroll}; + + use super::*; + + test_iterable_scroll!( + test_add_movie_search_results_scroll, + AddMovieHandler, + add_searched_movies, + simple_stateful_iterable_vec!(AddMovieSearchResult, HorizontallyScrollableText), + ActiveRadarrBlock::AddMovieSearchResults, + title, + stationary_style + ); + + test_enum_scroll!( + test_add_movie_select_monitor_scroll, + AddMovieHandler, + Monitor, + add_movie_monitor_list, + ActiveRadarrBlock::AddMovieSelectMonitor + ); + + test_enum_scroll!( + test_add_movie_select_minimuum_availability_scroll, + AddMovieHandler, + MinimumAvailability, + add_movie_minimum_availability_list, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability + ); + + test_iterable_scroll!( + test_add_movie_select_quality_profile_scroll, + AddMovieHandler, + add_movie_quality_profile_list, + ActiveRadarrBlock::AddMovieSelectQualityProfile + ); + + #[rstest] + fn test_add_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { + let mut app = App::default(); + app.data.radarr_data.selected_block = ActiveRadarrBlock::AddMovieSelectMinimumAvailability; + + AddMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + if key == Key::Up { + assert_eq!( + app.data.radarr_data.selected_block, + ActiveRadarrBlock::AddMovieSelectMonitor + ); + } else { + assert_eq!( + app.data.radarr_data.selected_block, + ActiveRadarrBlock::AddMovieSelectQualityProfile + ); + } + } + } + + mod test_handle_home_end { + use strum::IntoEnumIterator; + + use crate::{ + extended_stateful_iterable_vec, test_enum_home_and_end, test_iterable_home_and_end, + }; + + use super::*; + + test_iterable_home_and_end!( + test_add_movie_search_results_home_end, + AddMovieHandler, + add_searched_movies, + extended_stateful_iterable_vec!(AddMovieSearchResult, HorizontallyScrollableText), + ActiveRadarrBlock::AddMovieSearchResults, + title, + stationary_style + ); + + test_enum_home_and_end!( + test_add_movie_select_monitor_home_end, + AddMovieHandler, + Monitor, + add_movie_monitor_list, + ActiveRadarrBlock::AddMovieSelectMonitor + ); + + test_enum_home_and_end!( + test_add_movie_select_minimuum_availability_home_end, + AddMovieHandler, + MinimumAvailability, + add_movie_minimum_availability_list, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability + ); + + test_iterable_home_and_end!( + test_add_movie_select_quality_profile_scroll, + AddMovieHandler, + add_movie_quality_profile_list, + ActiveRadarrBlock::AddMovieSelectQualityProfile + ); + } + + mod test_left_right_action { + use rstest::rstest; + + use super::*; + + #[rstest] + fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { + let mut app = App::default(); + + AddMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + assert!(app.data.radarr_data.prompt_confirm); + + AddMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + assert!(!app.data.radarr_data.prompt_confirm); + } + } + + mod test_submit { + use std::collections::HashMap; + + use pretty_assertions::{assert_eq, assert_str_eq}; + use rstest::rstest; + + use crate::app::key_binding::DEFAULT_KEYBINDINGS; + use crate::network::radarr_network::RadarrEvent; + + use super::*; + + const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key; + + #[test] + fn test_add_movie_search_input_submit() { + let mut app = App::default(); + app.should_ignore_quit_key = true; + + AddMovieHandler::with( + &SUBMIT_KEY, + &mut app, + &ActiveRadarrBlock::AddMovieSearchInput, + ) + .handle(); + + assert!(!app.should_ignore_quit_key); + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::AddMovieSearchResults.into() + ); + } + + #[test] + fn test_add_movie_search_results_submit() { + let mut app = App::default(); + app.data.radarr_data.quality_profile_map = + HashMap::from([(1, "B - Test 2".to_owned()), (0, "A - Test 1".to_owned())]); + + AddMovieHandler::with( + &SUBMIT_KEY, + &mut app, + &ActiveRadarrBlock::AddMovieSearchResults, + ) + .handle(); + + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::AddMoviePrompt.into() + ); + assert!(!app.data.radarr_data.add_movie_monitor_list.items.is_empty()); + assert!(!app + .data + .radarr_data + .add_movie_minimum_availability_list + .items + .is_empty()); + assert!(!app + .data + .radarr_data + .add_movie_quality_profile_list + .items + .is_empty()); + assert_str_eq!( + app + .data + .radarr_data + .add_movie_quality_profile_list + .current_selection(), + "A - Test 1" + ); + } + + #[test] + fn test_add_movie_prompt_prompt_decline() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); + app.data.radarr_data.selected_block = ActiveRadarrBlock::AddMovieConfirmPrompt; + + AddMovieHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); + assert_eq!(app.data.radarr_data.prompt_confirm_action, None); + } + + #[test] + fn test_add_movie_confirm_prompt_prompt_confirmation() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); + app.data.radarr_data.prompt_confirm = true; + app.data.radarr_data.selected_block = ActiveRadarrBlock::AddMovieConfirmPrompt; + + AddMovieHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); + assert_eq!( + app.data.radarr_data.prompt_confirm_action, + Some(RadarrEvent::AddMovie) + ); + } + + #[rstest] + fn test_add_movie_prompt_selected_block( + #[values( + ActiveRadarrBlock::AddMovieSelectMonitor, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + ActiveRadarrBlock::AddMovieSelectQualityProfile + )] + selected_block: ActiveRadarrBlock, + ) { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); + app.data.radarr_data.selected_block = selected_block.clone(); + + AddMovieHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + assert_eq!(app.get_current_route(), &selected_block.into()); + assert_eq!(app.data.radarr_data.prompt_confirm_action, None); + } + + #[rstest] + fn test_add_movie_prompt_selecting_preferences_blocks( + #[values( + ActiveRadarrBlock::AddMovieSelectMonitor, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + ActiveRadarrBlock::AddMovieSelectQualityProfile + )] + active_radarr_block: ActiveRadarrBlock, + ) { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); + app.push_navigation_stack(active_radarr_block.clone().into()); + + AddMovieHandler::with(&SUBMIT_KEY, &mut app, &active_radarr_block).handle(); + + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::AddMoviePrompt.into() + ); + } + } + + mod test_esc { + use pretty_assertions::assert_eq; + use rstest::rstest; + + use crate::app::radarr::RadarrData; + use crate::models::radarr_models::{Collection, Movie}; + use crate::simple_stateful_iterable_vec; + + use super::*; + + const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; + + #[test] + fn test_esc_add_movie_search_input() { + let mut radarr_data = RadarrData { + is_searching: true, + search: "test search".to_owned(), + filter: "test filter".to_owned(), + ..RadarrData::default() + }; + radarr_data + .filtered_movies + .set_items(vec![Movie::default()]); + radarr_data + .filtered_collections + .set_items(vec![Collection::default()]); + radarr_data + .add_searched_movies + .set_items(vec![AddMovieSearchResult::default()]); + let mut app = App::default(); + app.data.radarr_data = radarr_data; + app.should_ignore_quit_key = true; + app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); + + AddMovieHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::AddMovieSearchInput).handle(); + + assert!(!app.should_ignore_quit_key); + assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); + assert!(!app.data.radarr_data.is_searching); + assert!(app.data.radarr_data.search.is_empty()); + assert!(app.data.radarr_data.filter.is_empty()); + assert!(app.data.radarr_data.filtered_movies.items.is_empty()); + assert!(app.data.radarr_data.filtered_collections.items.is_empty()); + assert!(app.data.radarr_data.add_searched_movies.items.is_empty()); + } + + #[test] + fn test_esc_add_movie_search_results() { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); + app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); + app + .data + .radarr_data + .add_searched_movies + .set_items(simple_stateful_iterable_vec!( + AddMovieSearchResult, + HorizontallyScrollableText + )); + + AddMovieHandler::with( + &ESC_KEY, + &mut app, + &ActiveRadarrBlock::AddMovieSearchResults, + ) + .handle(); + + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::AddMovieSearchInput.into() + ); + assert!(app.data.radarr_data.add_searched_movies.items.is_empty()); + assert!(app.should_ignore_quit_key); + } + + #[test] + fn test_esc_add_movie_prompt() { + let mut radarr_data = RadarrData::default(); + radarr_data + .add_movie_monitor_list + .set_items(vec![Monitor::default()]); + radarr_data + .add_movie_minimum_availability_list + .set_items(vec![MinimumAvailability::default()]); + radarr_data + .add_movie_quality_profile_list + .set_items(vec![String::default()]); + radarr_data.prompt_confirm = true; + let mut app = App::default(); + app.data.radarr_data = radarr_data; + app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); + app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); + + AddMovieHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + assert!(!app.data.radarr_data.prompt_confirm); + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::AddMovieSearchResults.into() + ); + assert!(app.data.radarr_data.add_movie_monitor_list.items.is_empty()); + assert!(app + .data + .radarr_data + .add_movie_minimum_availability_list + .items + .is_empty()); + assert!(app + .data + .radarr_data + .add_movie_quality_profile_list + .items + .is_empty()); + } + + #[rstest] + fn test_esc_selecting_preferences_blocks( + #[values( + ActiveRadarrBlock::AddMovieSelectMonitor, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + ActiveRadarrBlock::AddMovieSelectQualityProfile + )] + active_radarr_block: ActiveRadarrBlock, + ) { + let mut app = App::default(); + app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); + app.push_navigation_stack(active_radarr_block.into()); + + AddMovieHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::AddMoviePrompt).handle(); + + assert_eq!( + app.get_current_route(), + &ActiveRadarrBlock::AddMoviePrompt.into() + ); + } + } + + mod test_key_char { + use super::*; + + #[test] + fn test_backspace_add_movie_search_input() { + let mut app = App::default(); + app.data.radarr_data.search = "Test".to_owned(); + + AddMovieHandler::with( + &DEFAULT_KEYBINDINGS.backspace.key, + &mut app, + &ActiveRadarrBlock::AddMovieSearchInput, + ) + .handle(); + + assert_str_eq!(app.data.radarr_data.search, "Tes"); + } + + #[test] + fn test_char_key_add_movie_search_input() { + let mut app = App::default(); + + AddMovieHandler::with( + &Key::Char('h'), + &mut app, + &ActiveRadarrBlock::AddMovieSearchInput, + ) + .handle(); + + assert_str_eq!(app.data.radarr_data.search, "h"); + } + } +} diff --git a/src/handlers/radarr_handlers/mod.rs b/src/handlers/radarr_handlers/mod.rs index 39d7860..8b95005 100644 --- a/src/handlers/radarr_handlers/mod.rs +++ b/src/handlers/radarr_handlers/mod.rs @@ -496,8 +496,10 @@ impl RadarrHandler<'_> { #[cfg(test)] mod tests { - use pretty_assertions::assert_eq; + use pretty_assertions::{assert_eq, assert_str_eq}; + use rstest::rstest; + use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::radarr::ActiveRadarrBlock; use crate::app::App; use crate::event::Key; @@ -507,302 +509,109 @@ mod tests { use crate::models::radarr_models::{Collection, Movie}; mod test_handle_scroll_up_and_down { - use pretty_assertions::assert_eq; use rstest::rstest; use crate::models::radarr_models::DownloadRecord; - use crate::simple_stateful_iterable_vec; + use crate::{simple_stateful_iterable_vec, test_iterable_scroll}; use super::*; - #[rstest] - fn test_collections_scroll(#[values(Key::Up, Key::Down)] key: Key) { - let mut app = App::default(); - app - .data - .radarr_data - .collections - .set_items(simple_stateful_iterable_vec!(Collection)); + test_iterable_scroll!( + test_collections_scroll, + RadarrHandler, + collections, + Collection, + ActiveRadarrBlock::Collections, + title + ); - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections).handle(); + test_iterable_scroll!( + test_filtered_collections_scroll, + RadarrHandler, + filtered_collections, + Collection, + ActiveRadarrBlock::Collections, + title + ); - assert_eq!( - app.data.radarr_data.collections.current_selection().title, - "Test 2".to_owned() - ); + test_iterable_scroll!( + test_movies_scroll, + RadarrHandler, + movies, + Movie, + ActiveRadarrBlock::Movies, + title + ); - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections).handle(); + test_iterable_scroll!( + test_filtered_movies_scroll, + RadarrHandler, + filtered_movies, + Movie, + ActiveRadarrBlock::Movies, + title + ); - assert_eq!( - app.data.radarr_data.collections.current_selection().title, - "Test 1".to_owned() - ); - } - - #[rstest] - fn test_filtered_collections_scroll(#[values(Key::Up, Key::Down)] key: Key) { - let mut app = App::default(); - app - .data - .radarr_data - .filtered_collections - .set_items(simple_stateful_iterable_vec!(Collection)); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_collections - .current_selection() - .title, - "Test 2".to_owned() - ); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_collections - .current_selection() - .title, - "Test 1".to_owned() - ); - } - - #[rstest] - fn test_movies_scroll(#[values(Key::Up, Key::Down)] key: Key) { - let mut app = App::default(); - app - .data - .radarr_data - .movies - .set_items(simple_stateful_iterable_vec!(Movie)); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app.data.radarr_data.movies.current_selection().title, - "Test 2".to_owned() - ); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app.data.radarr_data.movies.current_selection().title, - "Test 1".to_owned() - ); - } - - #[rstest] - fn test_filtered_movies_scroll(#[values(Key::Up, Key::Down)] key: Key) { - let mut app = App::default(); - app - .data - .radarr_data - .filtered_movies - .set_items(simple_stateful_iterable_vec!(Movie)); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_movies - .current_selection() - .title, - "Test 2".to_owned() - ); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_movies - .current_selection() - .title, - "Test 1".to_owned() - ); - } - - #[rstest] - fn test_downloads_scroll(#[values(Key::Up, Key::Down)] key: Key) { - let mut app = App::default(); - app - .data - .radarr_data - .downloads - .set_items(simple_stateful_iterable_vec!(DownloadRecord)); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Downloads).handle(); - - assert_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 2".to_owned() - ); - - RadarrHandler::with(&key, &mut app, &ActiveRadarrBlock::Downloads).handle(); - - assert_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 1".to_owned() - ); - } + test_iterable_scroll!( + test_downloads_scroll, + RadarrHandler, + downloads, + DownloadRecord, + ActiveRadarrBlock::Downloads, + title + ); } mod test_handle_home_end { - use pretty_assertions::assert_eq; - - use crate::extended_stateful_iterable_vec; use crate::models::radarr_models::DownloadRecord; + use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end}; use super::*; - #[test] - fn test_collections_home_end() { - let mut app = App::default(); - app - .data - .radarr_data - .collections - .set_items(extended_stateful_iterable_vec!(Collection)); + test_iterable_home_and_end!( + test_collections_home_end, + RadarrHandler, + collections, + Collection, + ActiveRadarrBlock::Collections, + title + ); - RadarrHandler::with(&Key::End, &mut app, &ActiveRadarrBlock::Collections).handle(); + test_iterable_home_and_end!( + test_filtered_collections_home_end, + RadarrHandler, + filtered_collections, + Collection, + ActiveRadarrBlock::Collections, + title + ); - assert_eq!( - app.data.radarr_data.collections.current_selection().title, - "Test 3".to_owned() - ); + test_iterable_home_and_end!( + test_movies_home_end, + RadarrHandler, + movies, + Movie, + ActiveRadarrBlock::Movies, + title + ); - RadarrHandler::with(&Key::Home, &mut app, &ActiveRadarrBlock::Collections).handle(); + test_iterable_home_and_end!( + test_filtered_movies_home_end, + RadarrHandler, + filtered_movies, + Movie, + ActiveRadarrBlock::Movies, + title + ); - assert_eq!( - app.data.radarr_data.collections.current_selection().title, - "Test 1".to_owned() - ); - } - - #[test] - fn test_filtered_collections_home_end() { - let mut app = App::default(); - app - .data - .radarr_data - .filtered_collections - .set_items(extended_stateful_iterable_vec!(Collection)); - - RadarrHandler::with(&Key::End, &mut app, &ActiveRadarrBlock::Collections).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_collections - .current_selection() - .title, - "Test 3".to_owned() - ); - - RadarrHandler::with(&Key::Home, &mut app, &ActiveRadarrBlock::Collections).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_collections - .current_selection() - .title, - "Test 1".to_owned() - ); - } - - #[test] - fn test_movies_home_end() { - let mut app = App::default(); - app - .data - .radarr_data - .movies - .set_items(extended_stateful_iterable_vec!(Movie)); - - RadarrHandler::with(&Key::End, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app.data.radarr_data.movies.current_selection().title, - "Test 3".to_owned() - ); - - RadarrHandler::with(&Key::Home, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app.data.radarr_data.movies.current_selection().title, - "Test 1".to_owned() - ); - } - - #[test] - fn test_filtered_movies_home_end() { - let mut app = App::default(); - app - .data - .radarr_data - .filtered_movies - .set_items(extended_stateful_iterable_vec!(Movie)); - - RadarrHandler::with(&Key::End, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_movies - .current_selection() - .title, - "Test 3".to_owned() - ); - - RadarrHandler::with(&Key::Home, &mut app, &ActiveRadarrBlock::Movies).handle(); - - assert_eq!( - app - .data - .radarr_data - .filtered_movies - .current_selection() - .title, - "Test 1".to_owned() - ); - } - - #[test] - fn test_downloads_home_end() { - let mut app = App::default(); - app - .data - .radarr_data - .downloads - .set_items(extended_stateful_iterable_vec!(DownloadRecord)); - - RadarrHandler::with(&Key::End, &mut app, &ActiveRadarrBlock::Downloads).handle(); - - assert_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 3".to_owned() - ); - - RadarrHandler::with(&Key::Home, &mut app, &ActiveRadarrBlock::Downloads).handle(); - - assert_eq!( - app.data.radarr_data.downloads.current_selection().title, - "Test 1".to_owned() - ); - } + test_iterable_home_and_end!( + test_downloads_home_end, + RadarrHandler, + downloads, + DownloadRecord, + ActiveRadarrBlock::Downloads, + title + ); } mod test_delete { @@ -810,7 +619,7 @@ mod tests { use super::*; - const DELETE_KEY: Key = Key::Delete; + const DELETE_KEY: Key = DEFAULT_KEYBINDINGS.delete.key; #[test] fn test_movies_delete() { @@ -855,7 +664,12 @@ mod tests { let mut app = App::default(); app.data.radarr_data.main_tabs.set_index(index); - RadarrHandler::with(&Key::Left, &mut app, &active_radarr_block).handle(); + RadarrHandler::with( + &DEFAULT_KEYBINDINGS.left.key, + &mut app, + &active_radarr_block, + ) + .handle(); assert_eq!( app.data.radarr_data.main_tabs.get_active_route(), @@ -876,7 +690,12 @@ mod tests { let mut app = App::default(); app.data.radarr_data.main_tabs.set_index(index); - RadarrHandler::with(&Key::Right, &mut app, &active_radarr_block).handle(); + RadarrHandler::with( + &DEFAULT_KEYBINDINGS.right.key, + &mut app, + &active_radarr_block, + ) + .handle(); assert_eq!( app.data.radarr_data.main_tabs.get_active_route(), @@ -895,7 +714,7 @@ mod tests { ActiveRadarrBlock::RefreshDownloadsPrompt )] active_radarr_block: ActiveRadarrBlock, - #[values(Key::Left, Key::Right)] key: Key, + #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, ) { let mut app = App::default(); @@ -917,7 +736,7 @@ mod tests { use super::*; - const SUBMIT_KEY: Key = Key::Enter; + const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key; #[rstest] #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::MovieDetails)] @@ -945,9 +764,9 @@ mod tests { RadarrHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::SearchMovie).handle(); - assert_eq!( + assert_str_eq!( app.data.radarr_data.movies.current_selection().title, - "Test 2".to_owned() + "Test 2" ); } @@ -963,9 +782,9 @@ mod tests { RadarrHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::SearchCollection).handle(); - assert_eq!( + assert_str_eq!( app.data.radarr_data.collections.current_selection().title, - "Test 2".to_owned() + "Test 2" ); } @@ -982,7 +801,7 @@ mod tests { RadarrHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::FilterMovies).handle(); assert_eq!(app.data.radarr_data.filtered_movies.items.len(), 3); - assert_eq!( + assert_str_eq!( app .data .radarr_data @@ -1006,7 +825,7 @@ mod tests { RadarrHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::FilterCollections).handle(); assert_eq!(app.data.radarr_data.filtered_collections.items.len(), 3); - assert_eq!( + assert_str_eq!( app .data .radarr_data @@ -1100,7 +919,7 @@ mod tests { use super::*; - const ESC_KEY: Key = Key::Esc; + const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key; #[rstest] #[case(ActiveRadarrBlock::Movies, ActiveRadarrBlock::SearchMovie)] @@ -1319,7 +1138,7 @@ mod tests { ) .handle(); - assert_eq!(app.data.radarr_data.search, "Tes".to_owned()); + assert_str_eq!(app.data.radarr_data.search, "Tes"); } #[rstest] @@ -1337,7 +1156,7 @@ mod tests { ) .handle(); - assert_eq!(app.data.radarr_data.filter, "Tes".to_owned()); + assert_str_eq!(app.data.radarr_data.filter, "Tes"); } #[rstest] @@ -1349,7 +1168,7 @@ mod tests { RadarrHandler::with(&Key::Char('h'), &mut app, &active_radarr_block).handle(); - assert_eq!(app.data.radarr_data.search, "h".to_owned()); + assert_str_eq!(app.data.radarr_data.search, "h"); } #[rstest] @@ -1361,7 +1180,7 @@ mod tests { RadarrHandler::with(&Key::Char('h'), &mut app, &active_radarr_block).handle(); - assert_eq!(app.data.radarr_data.filter, "h".to_owned()); + assert_str_eq!(app.data.radarr_data.filter, "h"); } } @@ -1380,8 +1199,12 @@ mod tests { let movies = &app.data.radarr_data.movies.items.clone(); - let index = RadarrHandler::with(&Key::Enter, &mut app, &ActiveRadarrBlock::SearchMovie) - .search_table(movies, |movie| &movie.title); + let index = RadarrHandler::with( + &DEFAULT_KEYBINDINGS.submit.key, + &mut app, + &ActiveRadarrBlock::SearchMovie, + ) + .search_table(movies, |movie| &movie.title); assert_eq!(index, Some(1)); assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); @@ -1405,8 +1228,12 @@ mod tests { let movies = &app.data.radarr_data.movies.items.clone(); - let index = RadarrHandler::with(&Key::Enter, &mut app, &ActiveRadarrBlock::SearchMovie) - .search_table(movies, |movie| &movie.title); + let index = RadarrHandler::with( + &DEFAULT_KEYBINDINGS.submit.key, + &mut app, + &ActiveRadarrBlock::SearchMovie, + ) + .search_table(movies, |movie| &movie.title); assert_eq!(index, None); assert_eq!( @@ -1433,12 +1260,15 @@ mod tests { let movies = &app.data.radarr_data.movies.items.clone(); - let filter_matches = - RadarrHandler::with(&Key::Enter, &mut app, &ActiveRadarrBlock::FilterMovies) - .filter_table(movies, |movie| &movie.title); + let filter_matches = RadarrHandler::with( + &DEFAULT_KEYBINDINGS.submit.key, + &mut app, + &ActiveRadarrBlock::FilterMovies, + ) + .filter_table(movies, |movie| &movie.title); assert_eq!(filter_matches.len(), 1); - assert_eq!(filter_matches[0].title, "Test 2"); + assert_str_eq!(filter_matches[0].title, "Test 2"); assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); assert!(!app.data.radarr_data.is_searching); assert!(!app.should_ignore_quit_key); @@ -1460,9 +1290,12 @@ mod tests { let movies = &app.data.radarr_data.movies.items.clone(); - let filter_matches = - RadarrHandler::with(&Key::Enter, &mut app, &ActiveRadarrBlock::FilterMovies) - .filter_table(movies, |movie| &movie.title); + let filter_matches = RadarrHandler::with( + &DEFAULT_KEYBINDINGS.submit.key, + &mut app, + &ActiveRadarrBlock::FilterMovies, + ) + .filter_table(movies, |movie| &movie.title); assert!(filter_matches.is_empty()); assert_eq!( @@ -1473,4 +1306,24 @@ mod tests { assert!(!app.should_ignore_quit_key); assert!(app.data.radarr_data.filter.is_empty()); } + + #[rstest] + fn test_delegates_add_movie_blocks_to_add_movie_handler( + #[values( + ActiveRadarrBlock::AddMovieSearchInput, + ActiveRadarrBlock::AddMovieSearchResults, + ActiveRadarrBlock::AddMoviePrompt, + ActiveRadarrBlock::AddMovieSelectMonitor, + ActiveRadarrBlock::AddMovieSelectMinimumAvailability, + ActiveRadarrBlock::AddMovieSelectQualityProfile + )] + active_radarr_block: ActiveRadarrBlock, + ) { + let mut app = App::default(); + app.push_navigation_stack(active_radarr_block.clone().into()); + + RadarrHandler::with(&DEFAULT_KEYBINDINGS.esc.key, &mut app, &active_radarr_block).handle(); + + assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into()); + } }