Files
managarr/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs
T
Dark-Alex-17 4cbec79334 test(radarr): pin table search, filter and selection behaviour
Radarr handler tests never asserted which block the search and filter keys
push, so transposing searching_block and filtering_block in a
TableHandlingConfig went undetected. Add a search key and a filter key test
for each of the three handlers that configure them: library, collections and
history.

No test moved a table or list selection off index 0 either, which made
current_selection() and items[0] indistinguishable. Select a non-zero index
in the tests covering every handler that reads a selected row, enriching
fixtures with a second, distinct entry where only one existed.

Several fixtures also asserted against a default value, so the expected
result was indistinguishable from an unset field. The system details tasks
now use two distinct non-default task names, and the add movie body expects
a non-default monitor and minimum availability.
2026-09-09 10:47:07 -06:00

434 lines
12 KiB
Rust

#[cfg(test)]
mod tests {
use pretty_assertions::assert_str_eq;
use rstest::rstest;
use strum::IntoEnumIterator;
use crate::app::App;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::assert_modal_absent;
use crate::event::Key;
use crate::handlers::KeyEventHandler;
use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler;
use crate::models::radarr_models::CollectionMovie;
use crate::models::servarr_data::radarr::modals::MovieOverviewModal;
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS,
};
use crate::test_handler_delegation;
mod test_handle_submit {
use crate::handlers::radarr_handlers::radarr_handler_test_utils::utils::collection_movie;
use crate::models::BlockSelectionState;
use crate::models::radarr_models::Movie;
use crate::models::servarr_data::radarr::radarr_data::ADD_MOVIE_SELECTION_BLOCKS;
use crate::{assert_modal_present, assert_navigation_pushed};
use bimap::BiMap;
use pretty_assertions::assert_eq;
use super::*;
const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key;
#[test]
fn test_collection_details_submit() {
let mut app = App::test_default();
app
.data
.radarr_data
.collection_movies
.set_items(vec![CollectionMovie::default()]);
app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(1, "B - Test 2".to_owned()), (0, "A - Test 1".to_owned())]);
app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS);
app
.data
.radarr_data
.selected_block
.set_index(0, ADD_MOVIE_SELECTION_BLOCKS.len() - 1);
CollectionDetailsHandler::new(
SUBMIT_KEY,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
)
.handle();
assert_navigation_pushed!(
app,
(
ActiveRadarrBlock::AddMoviePrompt,
Some(ActiveRadarrBlock::CollectionDetails)
)
.into()
);
assert!(
!app
.data
.radarr_data
.add_movie_modal
.as_ref()
.unwrap()
.monitor_list
.items
.is_empty()
);
assert_eq!(
app.data.radarr_data.selected_block.get_active_block(),
ActiveRadarrBlock::AddMovieSelectRootFolder
);
assert!(
!app
.data
.radarr_data
.add_movie_modal
.as_ref()
.unwrap()
.minimum_availability_list
.items
.is_empty()
);
assert!(
!app
.data
.radarr_data
.add_movie_modal
.as_ref()
.unwrap()
.quality_profile_list
.items
.is_empty()
);
assert_str_eq!(
app
.data
.radarr_data
.add_movie_modal
.as_ref()
.unwrap()
.quality_profile_list
.current_selection(),
"A - Test 1"
);
}
#[test]
fn test_collection_details_submit_no_op_when_not_ready() {
let mut app = App::test_default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app
.data
.radarr_data
.collection_movies
.set_items(vec![CollectionMovie::default()]);
CollectionDetailsHandler::new(
SUBMIT_KEY,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
)
.handle();
assert_eq!(
app.get_current_route(),
ActiveRadarrBlock::CollectionDetails.into()
);
assert_modal_absent!(app.data.radarr_data.add_movie_modal);
}
#[test]
fn test_collection_details_submit_movie_already_in_library() {
let mut app = App::test_default();
app.data.radarr_data.collection_movies.set_items(vec![
CollectionMovie {
tmdb_id: 5678,
overview: "Some other overview".to_owned(),
..CollectionMovie::default()
},
collection_movie(),
]);
app.data.radarr_data.collection_movies.select_index(Some(1));
app.data.radarr_data.movies.set_items(vec![Movie {
tmdb_id: collection_movie().tmdb_id,
..Movie::default()
}]);
CollectionDetailsHandler::new(
SUBMIT_KEY,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
)
.handle();
assert_navigation_pushed!(app, ActiveRadarrBlock::ViewMovieOverview.into());
assert_modal_present!(app.data.radarr_data.movie_overview_modal);
let movie_overview_modal = app.data.radarr_data.movie_overview_modal.as_ref().unwrap();
assert_eq!(movie_overview_modal.overview.offset, 0);
assert_str_eq!(
movie_overview_modal.overview.get_text(),
collection_movie().overview
);
}
#[test]
fn test_collection_details_submit_reopens_the_movie_overview_at_the_top() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app
.data
.radarr_data
.collection_movies
.set_items(vec![collection_movie()]);
app.data.radarr_data.movies.set_items(vec![Movie {
tmdb_id: collection_movie().tmdb_id,
..Movie::default()
}]);
CollectionDetailsHandler::new(
SUBMIT_KEY,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
)
.handle();
CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key,
&mut app,
ActiveRadarrBlock::ViewMovieOverview,
None,
)
.handle();
assert_eq!(overview_offset(&app), 5);
CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::ViewMovieOverview,
None,
)
.handle();
CollectionDetailsHandler::new(
SUBMIT_KEY,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
)
.handle();
assert_navigation_pushed!(app, ActiveRadarrBlock::ViewMovieOverview.into());
assert_eq!(overview_offset(&app), 0);
}
}
mod test_handle_esc {
use super::*;
use crate::assert_navigation_popped;
use rstest::rstest;
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[rstest]
fn test_esc_collection_details(#[values(true, false)] is_ready: bool) {
let mut app = App::test_default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app
.data
.radarr_data
.collection_movies
.set_items(vec![CollectionMovie::default()]);
CollectionDetailsHandler::new(
ESC_KEY,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
)
.handle();
assert_navigation_popped!(app, ActiveRadarrBlock::Collections.into());
assert_is_empty!(app.data.radarr_data.collection_movies.items);
}
#[test]
fn test_esc_view_movie_overview() {
let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into());
app.data.radarr_data.movie_overview_modal = Some(MovieOverviewModal::default());
CollectionDetailsHandler::new(
ESC_KEY,
&mut app,
ActiveRadarrBlock::ViewMovieOverview,
None,
)
.handle();
assert_navigation_popped!(app, ActiveRadarrBlock::CollectionDetails.into());
assert_modal_absent!(app.data.radarr_data.movie_overview_modal);
}
}
mod test_handle_key_char {
use bimap::BiMap;
use pretty_assertions::{assert_eq, assert_str_eq};
use strum::IntoEnumIterator;
use crate::models::radarr_models::{Collection, MinimumAvailability};
use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data;
use crate::models::servarr_data::radarr::radarr_data::{
EDIT_COLLECTION_SELECTION_BLOCKS, RadarrData,
};
use crate::test_edit_collection_key;
use super::*;
#[test]
fn test_edit_key() {
test_edit_collection_key!(
CollectionDetailsHandler,
ActiveRadarrBlock::CollectionDetails,
Some(ActiveRadarrBlock::CollectionDetails)
);
}
#[test]
fn test_edit_key_no_op_when_not_ready() {
let mut app = App::test_default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
let mut radarr_data = create_test_radarr_data();
radarr_data.collections.set_items(vec![Collection {
root_folder_path: "/nfs/movies/Test".to_owned().into(),
monitored: true,
search_on_add: true,
quality_profile_id: 2222,
minimum_availability: MinimumAvailability::Released,
..Collection::default()
}]);
app.data.radarr_data = radarr_data;
CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.edit.key,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
)
.handle();
assert_eq!(
app.get_current_route(),
ActiveRadarrBlock::CollectionDetails.into()
);
assert_modal_absent!(app.data.radarr_data.edit_collection_modal);
}
}
#[test]
fn test_collection_details_handler_accepts() {
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if COLLECTION_DETAILS_BLOCKS.contains(&active_radarr_block) {
assert!(CollectionDetailsHandler::accepts(active_radarr_block));
} else {
assert!(!CollectionDetailsHandler::accepts(active_radarr_block));
}
});
}
#[test]
fn test_delegates_view_movie_overview_to_movie_overview_handler() {
test_handler_delegation!(
CollectionDetailsHandler,
ActiveRadarrBlock::CollectionDetails,
ActiveRadarrBlock::ViewMovieOverview
);
}
#[rstest]
fn test_collection_details_handler_ignore_special_keys(
#[values(true, false)] ignore_special_keys_for_textbox_input: bool,
) {
let mut app = App::test_default();
app.ignore_special_keys_for_textbox_input = ignore_special_keys_for_textbox_input;
let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(
handler.ignore_special_keys(),
ignore_special_keys_for_textbox_input
);
}
#[test]
fn test_collection_details_handler_not_ready_when_loading() {
let mut app = App::test_default();
app.is_loading = true;
let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_collection_details_handler_not_ready_when_collection_movies_is_empty() {
let mut app = App::test_default();
app.is_loading = false;
let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_collection_details_handler_ready_when_not_loading_and_collection_movies_is_not_empty() {
let mut app = App::test_default();
app.is_loading = false;
app
.data
.radarr_data
.collection_movies
.set_items(vec![CollectionMovie::default()]);
let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::CollectionDetails,
None,
);
assert!(handler.is_ready());
}
fn overview_offset(app: &App<'_>) -> u16 {
app
.data
.radarr_data
.movie_overview_modal
.as_ref()
.unwrap()
.overview
.offset
}
}