Refactored the filter and search logic to follow the established modal logic and added some refactored functions to the UI module as well to clean up the UI code too

This commit is contained in:
2023-08-10 16:43:57 -06:00
parent ce12ebd301
commit f7cb832095
15 changed files with 695 additions and 463 deletions
@@ -370,6 +370,8 @@ 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
@@ -398,11 +400,56 @@ mod tests {
.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.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
@@ -431,11 +478,17 @@ mod tests {
.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
@@ -465,6 +518,40 @@ mod tests {
.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.filter = Some("Test 5".into());
CollectionsHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::FilterCollections,
&None,
)
.handle();
assert!(app.data.radarr_data.filtered_collections.items.is_empty());
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterCollectionsError.into()
);
}
#[test]
@@ -526,21 +613,21 @@ mod tests {
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_search_collection_block_esc() {
#[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(ActiveRadarrBlock::SearchCollection.into());
app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data = create_test_radarr_data();
CollectionsHandler::with(
&ESC_KEY,
&mut app,
&ActiveRadarrBlock::SearchCollection,
&None,
)
.handle();
CollectionsHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
assert_eq!(
app.get_current_route(),
@@ -550,21 +637,21 @@ mod tests {
assert_search_reset!(app.data.radarr_data);
}
#[test]
fn test_filter_collections_block_esc() {
#[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(ActiveRadarrBlock::FilterCollections.into());
app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data = create_test_radarr_data();
CollectionsHandler::with(
&ESC_KEY,
&mut app,
&ActiveRadarrBlock::FilterCollections,
&None,
)
.handle();
CollectionsHandler::with(&ESC_KEY, &mut app, &active_radarr_block, &None).handle();
assert_eq!(
app.get_current_route(),
@@ -675,6 +762,31 @@ mod tests {
assert!(app.data.radarr_data.filter.is_some());
}
#[test]
fn test_filter_collections_key_resets_previous_filter() {
let mut app = App::default();
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.data.radarr_data = create_test_radarr_data();
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.filter.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterCollections.into()
);
assert!(app.data.radarr_data.is_filtering);
assert!(app.should_ignore_quit_key);
assert!(app.data.radarr_data.filter.is_some());
assert!(app.data.radarr_data.filtered_collections.items.is_empty());
}
#[test]
fn test_collection_edit_key() {
test_edit_collection_key!(
+16 -36
View File
@@ -3,16 +3,15 @@ use crate::app::App;
use crate::event::Key;
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::{
filter_table, handle_change_tab_left_right_keys, search_table,
};
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, COLLECTIONS_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS,
};
use crate::models::{BlockSelectionState, HorizontallyScrollableText, Scrollable};
use crate::network::radarr_network::RadarrEvent;
use crate::{handle_text_box_keys, handle_text_box_left_right_keys};
use crate::utils::strip_non_search_characters;
use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table};
mod collection_details_handler;
mod edit_collection_handler;
@@ -221,46 +220,26 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
.items
.is_empty()
{
let selected_index = search_table(
search_table!(
self.app,
&self.app.data.radarr_data.collections.items.clone(),
|collection| &collection.title.text,
collections,
ActiveRadarrBlock::SearchCollectionError
);
self
.app
.data
.radarr_data
.collections
.select_index(selected_index);
} else {
let selected_index = search_table(
search_table!(
self.app,
&self.app.data.radarr_data.filtered_collections.items.clone(),
|collection| &collection.title.text,
filtered_collections,
ActiveRadarrBlock::SearchCollectionError
);
self
.app
.data
.radarr_data
.filtered_collections
.select_index(selected_index);
}
}
ActiveRadarrBlock::FilterCollections => {
let filtered_collections = filter_table(
filter_table!(
self.app,
&self.app.data.radarr_data.collections.items.clone(),
|collection| &collection.title.text,
collections,
filtered_collections,
ActiveRadarrBlock::FilterCollectionsError
);
if !filtered_collections.is_empty() {
self
.app
.data
.radarr_data
.filtered_collections
.set_items(filtered_collections);
}
}
ActiveRadarrBlock::UpdateAllCollectionsPrompt => {
if self.app.data.radarr_data.prompt_confirm {
@@ -275,12 +254,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
fn handle_esc(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::FilterCollections => {
ActiveRadarrBlock::FilterCollections | ActiveRadarrBlock::FilterCollectionsError => {
self.app.pop_navigation_stack();
self.app.data.radarr_data.reset_filter();
self.app.should_ignore_quit_key = false;
}
ActiveRadarrBlock::SearchCollection => {
ActiveRadarrBlock::SearchCollection | ActiveRadarrBlock::SearchCollectionError => {
self.app.pop_navigation_stack();
self.app.data.radarr_data.reset_search();
self.app.should_ignore_quit_key = false;
@@ -313,6 +292,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
self
.app
.push_navigation_stack(ActiveRadarrBlock::FilterCollections.into());
self.app.data.radarr_data.reset_filter();
self.app.data.radarr_data.filter = Some(HorizontallyScrollableText::default());
self.app.data.radarr_data.is_filtering = true;
self.app.should_ignore_quit_key = true;
@@ -388,6 +388,8 @@ mod tests {
#[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
@@ -410,11 +412,47 @@ mod tests {
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.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.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
app
.data
.radarr_data
@@ -443,11 +481,14 @@ mod tests {
.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
@@ -477,6 +518,37 @@ mod tests {
.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.filter = Some("Test 5".into());
LibraryHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::FilterMovies,
&None,
)
.handle();
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterMoviesError.into()
);
}
#[test]
@@ -532,30 +604,36 @@ mod tests {
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_search_movie_block_esc() {
#[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(ActiveRadarrBlock::SearchMovie.into());
app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data = create_test_radarr_data();
LibraryHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::SearchMovie, &None).handle();
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_search_reset!(app.data.radarr_data);
}
#[test]
fn test_filter_movies_block_esc() {
#[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(ActiveRadarrBlock::FilterMovies.into());
app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data = create_test_radarr_data();
LibraryHandler::with(&ESC_KEY, &mut app, &ActiveRadarrBlock::FilterMovies, &None).handle();
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);
@@ -657,6 +735,31 @@ mod tests {
assert!(app.data.radarr_data.filter.is_some());
}
#[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();
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.filter.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterMovies.into()
);
assert!(app.data.radarr_data.is_filtering);
assert!(app.should_ignore_quit_key);
assert!(app.data.radarr_data.filter.is_some());
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
}
#[test]
fn test_movie_add_key() {
let mut app = App::default();
+16 -39
View File
@@ -1,20 +1,20 @@
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::radarr_handlers::library::add_movie_handler::AddMovieHandler;
use crate::handlers::radarr_handlers::library::delete_movie_handler::DeleteMovieHandler;
use crate::handlers::radarr_handlers::library::edit_movie_handler::EditMovieHandler;
use crate::handlers::radarr_handlers::library::movie_details_handler::MovieDetailsHandler;
use crate::handlers::radarr_handlers::{
filter_table, handle_change_tab_left_right_keys, search_table,
};
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, DELETE_MOVIE_SELECTION_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, LIBRARY_BLOCKS,
};
use crate::models::{BlockSelectionState, HorizontallyScrollableText, Scrollable};
use crate::network::radarr_network::RadarrEvent;
use crate::{handle_text_box_keys, handle_text_box_left_right_keys};
use crate::utils::strip_non_search_characters;
use crate::{filter_table, handle_text_box_keys, handle_text_box_left_right_keys, search_table};
mod add_movie_handler;
mod delete_movie_handler;
@@ -200,46 +200,22 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()),
ActiveRadarrBlock::SearchMovie => {
if self.app.data.radarr_data.filtered_movies.items.is_empty() {
let selected_index = search_table(
self.app,
&self.app.data.radarr_data.movies.items.clone(),
|movie| &movie.title.text,
);
self
.app
.data
.radarr_data
.movies
.select_index(selected_index);
search_table!(self.app, movies, ActiveRadarrBlock::SearchMovieError);
} else {
let selected_index = search_table(
search_table!(
self.app,
&self.app.data.radarr_data.filtered_movies.items.clone(),
|movie| &movie.title.text,
filtered_movies,
ActiveRadarrBlock::SearchMovieError
);
self
.app
.data
.radarr_data
.filtered_movies
.select_index(selected_index);
};
}
}
ActiveRadarrBlock::FilterMovies => {
let filtered_movies = filter_table(
filter_table!(
self.app,
&self.app.data.radarr_data.movies.items.clone(),
|movie| &movie.title.text,
movies,
filtered_movies,
ActiveRadarrBlock::FilterMoviesError
);
if !filtered_movies.is_empty() {
self
.app
.data
.radarr_data
.filtered_movies
.set_items(filtered_movies);
}
}
ActiveRadarrBlock::UpdateAllMoviesPrompt => {
if self.app.data.radarr_data.prompt_confirm {
@@ -254,12 +230,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
fn handle_esc(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::FilterMovies => {
ActiveRadarrBlock::FilterMovies | ActiveRadarrBlock::FilterMoviesError => {
self.app.pop_navigation_stack();
self.app.data.radarr_data.reset_filter();
self.app.should_ignore_quit_key = false;
}
ActiveRadarrBlock::SearchMovie => {
ActiveRadarrBlock::SearchMovie | ActiveRadarrBlock::SearchMovieError => {
self.app.pop_navigation_stack();
self.app.data.radarr_data.reset_search();
self.app.should_ignore_quit_key = false;
@@ -292,6 +268,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
self
.app
.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
self.app.data.radarr_data.reset_filter();
self.app.data.radarr_data.filter = Some(HorizontallyScrollableText::default());
self.app.data.radarr_data.is_filtering = true;
self.app.should_ignore_quit_key = true;
+96 -82
View File
@@ -7,7 +7,6 @@ use crate::handlers::radarr_handlers::root_folders::RootFoldersHandler;
use crate::handlers::radarr_handlers::system::SystemHandler;
use crate::handlers::KeyEventHandler;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::utils::strip_non_search_characters;
use crate::{App, Key};
mod collections;
@@ -100,87 +99,6 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
fn handle_char_key_event(&mut self) {}
}
pub fn search_table<T, F>(app: &mut App<'_>, rows: &[T], field_selection_fn: F) -> Option<usize>
where
F: Fn(&T) -> &str,
{
let search_index = if app.data.radarr_data.search.is_some() {
let search_string = app
.data
.radarr_data
.search
.as_ref()
.unwrap()
.text
.clone()
.to_lowercase();
app.data.radarr_data.search = None;
rows.iter().position(|item| {
strip_non_search_characters(field_selection_fn(item)).contains(&search_string)
})
} else {
None
};
app.data.radarr_data.is_searching = false;
app.should_ignore_quit_key = false;
if search_index.is_some() {
app.pop_navigation_stack();
}
search_index
}
pub fn filter_table<T, F>(app: &mut App<'_>, rows: &[T], field_selection_fn: F) -> Vec<T>
where
F: Fn(&T) -> &str,
T: Clone,
{
let empty_filter = app.data.radarr_data.filter.is_some()
&& app
.data
.radarr_data
.filter
.as_ref()
.unwrap()
.text
.is_empty();
let filter_matches = if app.data.radarr_data.filter.is_some()
&& !app
.data
.radarr_data
.filter
.as_ref()
.unwrap()
.text
.is_empty()
{
let filter =
strip_non_search_characters(&app.data.radarr_data.filter.as_ref().unwrap().text.clone());
rows
.iter()
.filter(|&item| strip_non_search_characters(field_selection_fn(item)).contains(&filter))
.cloned()
.collect()
} else {
Vec::new()
};
app.data.radarr_data.filter = None;
app.data.radarr_data.is_filtering = false;
app.should_ignore_quit_key = false;
if !filter_matches.is_empty() || empty_filter {
app.pop_navigation_stack();
}
filter_matches
}
pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: &Key) {
let key_ref = key;
match key_ref {
@@ -195,3 +113,99 @@ pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: &Key) {
_ => (),
}
}
#[macro_export]
macro_rules! search_table {
($app:expr, $data_ref:ident, $error_block:expr) => {
let search_index = if $app.data.radarr_data.search.is_some() {
let search_string = $app
.data
.radarr_data
.search
.as_ref()
.unwrap()
.text
.clone()
.to_lowercase();
$app.data.radarr_data.search = None;
$app
.data
.radarr_data
.$data_ref
.items
.iter()
.position(|item| strip_non_search_characters(&item.title.text).contains(&search_string))
} else {
None
};
$app.data.radarr_data.is_searching = false;
$app.should_ignore_quit_key = false;
if search_index.is_some() {
$app.pop_navigation_stack();
$app.data.radarr_data.$data_ref.select_index(search_index);
} else {
$app.pop_and_push_navigation_stack($error_block.into());
}
};
}
#[macro_export]
macro_rules! filter_table {
($app:expr, $source_table_ref:ident, $filter_table_ref:ident, $error_block:expr) => {
let empty_filter = $app.data.radarr_data.filter.is_some()
&& $app
.data
.radarr_data
.filter
.as_ref()
.unwrap()
.text
.is_empty();
let filter_matches = if $app.data.radarr_data.filter.is_some()
&& !$app
.data
.radarr_data
.filter
.as_ref()
.unwrap()
.text
.is_empty()
{
let filter =
strip_non_search_characters(&$app.data.radarr_data.filter.as_ref().unwrap().text.clone());
$app
.data
.radarr_data
.$source_table_ref
.items
.iter()
.filter(|item| strip_non_search_characters(&item.title.text).contains(&filter))
.cloned()
.collect()
} else {
Vec::new()
};
$app.data.radarr_data.filter = None;
$app.data.radarr_data.is_filtering = false;
$app.should_ignore_quit_key = false;
if filter_matches.is_empty() && !empty_filter {
$app.pop_and_push_navigation_stack($error_block.into());
} else if empty_filter {
$app.pop_navigation_stack();
} else {
$app.pop_navigation_stack();
$app
.data
.radarr_data
.$filter_table_ref
.set_items(filter_matches);
}
};
}
@@ -6,18 +6,21 @@ mod tests {
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App;
use crate::handlers::radarr_handlers::{
filter_table, handle_change_tab_left_right_keys, search_table, RadarrHandler,
};
use crate::handlers::radarr_handlers::{handle_change_tab_left_right_keys, RadarrHandler};
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::Movie;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::HorizontallyScrollableText;
use crate::{extended_stateful_iterable_vec, test_handler_delegation};
use crate::utils::strip_non_search_characters;
use crate::{
extended_stateful_iterable_vec, filter_table, search_table, test_handler_delegation,
};
#[test]
fn test_search_table() {
fn test_search_table_macro() {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
app
.data
.radarr_data
@@ -29,13 +32,13 @@ mod tests {
app.data.radarr_data.search = Some("Test 2".into());
app.data.radarr_data.is_searching = true;
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
let movies = &app.data.radarr_data.movies.items.clone();
search_table!(app, movies, ActiveRadarrBlock::SearchMovieError);
let index = search_table(&mut app, movies, |movie| &movie.title.text);
assert_eq!(index, Some(1));
assert_str_eq!(
app.data.radarr_data.movies.current_selection().title.text,
"Test 2"
);
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.is_searching);
assert!(!app.should_ignore_quit_key);
@@ -43,8 +46,39 @@ mod tests {
}
#[test]
fn test_search_table_no_search_hits() {
fn test_search_table_macro_empty_search() {
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.search = Some("".into());
app.data.radarr_data.is_searching = true;
app.should_ignore_quit_key = true;
search_table!(app, movies, ActiveRadarrBlock::SearchMovieError);
assert_str_eq!(
app.data.radarr_data.movies.current_selection().title.text,
"Test 1"
);
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.is_searching);
assert!(!app.should_ignore_quit_key);
assert!(app.data.radarr_data.search.is_none());
}
#[test]
fn test_search_table_macro_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
@@ -56,16 +90,16 @@ mod tests {
app.data.radarr_data.search = Some("Test 5".into());
app.data.radarr_data.is_searching = true;
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
let movies = &app.data.radarr_data.movies.items.clone();
search_table!(app, movies, ActiveRadarrBlock::SearchMovieError);
let index = search_table(&mut app, movies, |movie| &movie.title.text);
assert_eq!(index, None);
assert_str_eq!(
app.data.radarr_data.movies.current_selection().title.text,
"Test 1"
);
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::SearchMovie.into()
&ActiveRadarrBlock::SearchMovieError.into()
);
assert!(!app.data.radarr_data.is_searching);
assert!(!app.should_ignore_quit_key);
@@ -73,8 +107,10 @@ mod tests {
}
#[test]
fn test_filter_table() {
fn test_filter_table_macro() {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
app
.data
.radarr_data
@@ -86,14 +122,19 @@ mod tests {
app.data.radarr_data.filter = Some("Test 2".into());
app.data.radarr_data.is_filtering = true;
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
let movies = &app.data.radarr_data.movies.items.clone();
filter_table!(
app,
movies,
filtered_movies,
ActiveRadarrBlock::FilterMoviesError
);
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
assert_eq!(filter_matches.len(), 1);
assert_str_eq!(filter_matches[0].title.text, "Test 2");
assert_eq!(app.data.radarr_data.filtered_movies.items.len(), 1);
assert_str_eq!(
app.data.radarr_data.filtered_movies.items[0].title.text,
"Test 2"
);
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key);
@@ -101,38 +142,10 @@ mod tests {
}
#[test]
fn test_filter_table_no_filter_matches() {
fn test_filter_table_macro_reset_and_pop_on_empty_filter() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
app.data.radarr_data.filter = Some("Test 5".into());
app.data.radarr_data.is_filtering = true;
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
let movies = &app.data.radarr_data.movies.items.clone();
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
assert!(filter_matches.is_empty());
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterMovies.into()
);
assert!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key);
assert!(app.data.radarr_data.filter.is_none());
}
#[test]
fn test_filter_table_reset_and_pop_navigation_on_empty_filter() {
let mut app = App::default();
app
.data
.radarr_data
@@ -144,13 +157,15 @@ mod tests {
app.data.radarr_data.filter = Some("".into());
app.data.radarr_data.is_filtering = true;
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
let movies = &app.data.radarr_data.movies.items.clone();
filter_table!(
app,
movies,
filtered_movies,
ActiveRadarrBlock::FilterMoviesError
);
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
assert!(filter_matches.is_empty());
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key);
@@ -158,8 +173,44 @@ mod tests {
}
#[test]
fn test_filter_table_noop_on_none_filter() {
fn test_filter_table_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.filter = Some("Test 5".into());
app.data.radarr_data.is_filtering = true;
app.should_ignore_quit_key = true;
filter_table!(
app,
movies,
filtered_movies,
ActiveRadarrBlock::FilterMoviesError
);
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterMoviesError.into()
);
assert!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key);
assert!(app.data.radarr_data.filter.is_none());
}
#[test]
fn test_filter_table_macro_error_on_none_filter() {
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
app
.data
.radarr_data
@@ -170,16 +221,18 @@ mod tests {
));
app.data.radarr_data.is_filtering = true;
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::FilterMovies.into());
let movies = &app.data.radarr_data.movies.items.clone();
filter_table!(
app,
movies,
filtered_movies,
ActiveRadarrBlock::FilterMoviesError
);
let filter_matches = filter_table(&mut app, movies, |movie| &movie.title.text);
assert!(filter_matches.is_empty());
assert!(app.data.radarr_data.filtered_movies.items.is_empty());
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::FilterMovies.into()
&ActiveRadarrBlock::FilterMoviesError.into()
);
assert!(!app.data.radarr_data.is_filtering);
assert!(!app.should_ignore_quit_key);
@@ -244,7 +297,9 @@ mod tests {
#[values(
ActiveRadarrBlock::Movies,
ActiveRadarrBlock::SearchMovie,
ActiveRadarrBlock::SearchMovieError,
ActiveRadarrBlock::FilterMovies,
ActiveRadarrBlock::FilterMoviesError,
ActiveRadarrBlock::UpdateAllMoviesPrompt,
ActiveRadarrBlock::AddMovieSearchInput,
ActiveRadarrBlock::AddMovieSearchResults,
@@ -285,7 +340,9 @@ mod tests {
#[values(
ActiveRadarrBlock::Collections,
ActiveRadarrBlock::SearchCollection,
ActiveRadarrBlock::SearchCollectionError,
ActiveRadarrBlock::FilterCollections,
ActiveRadarrBlock::FilterCollectionsError,
ActiveRadarrBlock::UpdateAllCollectionsPrompt,
ActiveRadarrBlock::CollectionDetails,
ActiveRadarrBlock::ViewMovieOverview,