From c9244b045903ddfb547ed13b6583477d9e9d9db8 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Tue, 8 Sep 2026 22:01:03 -0600 Subject: [PATCH] feat(radarr): make the collection movie overview popup scrollable A collection movie's overview renders in a popup that does not scroll, so a long overview overflows with no way to read the rest. The popup now scrolls. The popup owns its own ScrollableText, built from the selected collection movie's overview when it opens and torn down on Esc so a reopened popup starts at the top. Scrolling mutates only that owned state. The background renders the Collection record's overview and the movies table, neither of which carries a scroll offset, so they cannot scroll along with the popup. The popup also gains the loading and absent fallbacks the rest of the tree already has. Give the collection movie fixture an overview distinct from its collection's, and a multi-paragraph one, so the snapshots can tell the two records apart and a scrolled popup is distinguishable from an unscrolled one. --- .../collections/collection_details_handler.rs | 42 ++- .../collection_details_handler_tests.rs | 95 ++++- .../radarr_handlers/collections/mod.rs | 1 + .../collections/movie_overview_handler.rs | 102 ++++++ .../movie_overview_handler_tests.rs | 345 ++++++++++++++++++ .../radarr_handler_test_utils.rs | 7 +- src/models/servarr_data/radarr/modals.rs | 6 + .../servarr_data/radarr/modals_tests.rs | 9 +- src/models/servarr_data/radarr/radarr_data.rs | 9 +- .../servarr_data/radarr/radarr_data_tests.rs | 1 + .../radarr_collections_network_tests.rs | 12 +- .../radarr_network_test_utils.rs | 9 +- .../collections/collection_details_ui.rs | 48 ++- .../collection_details_ui_tests.rs | 105 +++++- ...ts__snapshot_tests__ViewMovieOverview.snap | 8 +- ...ils_ui_renders_movie_overview_loading.snap | 48 +++ ...vie_overview_when_the_modal_is_absent.snap | 48 +++ ...ls_ui_renders_scrolled_movie_overview.snap | 48 +++ ...sts__AddMoviePrompt_CollectionDetails.snap | 6 +- ...MinimumAvailability_CollectionDetails.snap | 6 +- ...dMovieSelectMonitor_CollectionDetails.snap | 6 +- ...electQualityProfile_CollectionDetails.snap | 6 +- ...vieSelectRootFolder_CollectionDetails.snap | 6 +- ...__AddMovieTagsInput_CollectionDetails.snap | 6 +- 24 files changed, 913 insertions(+), 66 deletions(-) create mode 100644 src/handlers/radarr_handlers/collections/movie_overview_handler.rs create mode 100644 src/handlers/radarr_handlers/collections/movie_overview_handler_tests.rs create mode 100644 src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_loading.snap create mode 100644 src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_when_the_modal_is_absent.snap create mode 100644 src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_scrolled_movie_overview.snap diff --git a/src/handlers/radarr_handlers/collections/collection_details_handler.rs b/src/handlers/radarr_handlers/collections/collection_details_handler.rs index 92ca215f..a91faef0 100644 --- a/src/handlers/radarr_handlers/collections/collection_details_handler.rs +++ b/src/handlers/radarr_handlers/collections/collection_details_handler.rs @@ -1,14 +1,16 @@ +use super::movie_overview_handler::MovieOverviewHandler; use crate::app::App; use crate::event::Key; use crate::handlers::KeyEventHandler; use crate::handlers::table_handler::{TableHandlingConfig, handle_table}; use crate::matches_key; +use crate::models::servarr_data::radarr::modals::MovieOverviewModal; use crate::models::servarr_data::radarr::radarr_data::{ ADD_MOVIE_SELECTION_BLOCKS, ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS, }; use crate::models::stateful_table::StatefulTable; -use crate::models::{BlockSelectionState, Route}; +use crate::models::{BlockSelectionState, Route, ScrollableText}; #[cfg(test)] #[path = "collection_details_handler_tests.rs"] @@ -21,10 +23,35 @@ pub(super) struct CollectionDetailsHandler<'a, 'b> { _context: Option, } -impl CollectionDetailsHandler<'_, '_> {} +impl CollectionDetailsHandler<'_, '_> { + fn build_movie_overview_modal(&mut self) { + let overview = self + .app + .data + .radarr_data + .collection_movies + .current_selection() + .overview + .clone(); + + self.app.data.radarr_data.movie_overview_modal = Some(MovieOverviewModal { + overview: ScrollableText::with_string(overview), + }); + } +} impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHandler<'a, 'b> { fn handle(&mut self) { + if MovieOverviewHandler::accepts(self.active_radarr_block) { + return MovieOverviewHandler::new( + self.key, + self.app, + self.active_radarr_block, + self._context, + ) + .handle(); + } + let collection_movies_table_handling_config = TableHandlingConfig::new(ActiveRadarrBlock::CollectionDetails.into()); @@ -98,6 +125,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan .iter() .any(|movie| movie.tmdb_id == tmdb_id) { + self.build_movie_overview_modal(); self .app .push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into()); @@ -117,13 +145,9 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan } fn handle_esc(&mut self) { - match self.active_radarr_block { - ActiveRadarrBlock::CollectionDetails => { - self.app.data.radarr_data.collection_movies = StatefulTable::default(); - self.app.pop_navigation_stack(); - } - ActiveRadarrBlock::ViewMovieOverview => self.app.pop_navigation_stack(), - _ => (), + if self.active_radarr_block == ActiveRadarrBlock::CollectionDetails { + self.app.data.radarr_data.collection_movies = StatefulTable::default(); + self.app.pop_navigation_stack(); } } 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 2f5bdb87..57e8ee54 100644 --- a/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs +++ b/src/handlers/radarr_handlers/collections/collection_details_handler_tests.rs @@ -11,15 +11,18 @@ mod tests { 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::assert_navigation_pushed; + 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; @@ -143,12 +146,11 @@ mod tests { .data .radarr_data .collection_movies - .set_items(vec![CollectionMovie::default()]); - app - .data - .radarr_data - .movies - .set_items(vec![Movie::default()]); + .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, @@ -159,6 +161,63 @@ mod tests { .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); } } @@ -198,6 +257,7 @@ mod tests { 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, @@ -208,6 +268,7 @@ mod tests { .handle(); assert_navigation_popped!(app, ActiveRadarrBlock::CollectionDetails.into()); + assert_modal_absent!(app.data.radarr_data.movie_overview_modal); } } @@ -277,6 +338,15 @@ mod tests { }); } + #[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, @@ -345,4 +415,15 @@ mod tests { assert!(handler.is_ready()); } + + fn overview_offset(app: &App<'_>) -> u16 { + app + .data + .radarr_data + .movie_overview_modal + .as_ref() + .unwrap() + .overview + .offset + } } diff --git a/src/handlers/radarr_handlers/collections/mod.rs b/src/handlers/radarr_handlers/collections/mod.rs index 4e2e32a5..37bbdccd 100644 --- a/src/handlers/radarr_handlers/collections/mod.rs +++ b/src/handlers/radarr_handlers/collections/mod.rs @@ -16,6 +16,7 @@ use crate::network::radarr_network::RadarrEvent; mod collection_details_handler; mod edit_collection_handler; +mod movie_overview_handler; #[cfg(test)] #[path = "collections_handler_tests.rs"] diff --git a/src/handlers/radarr_handlers/collections/movie_overview_handler.rs b/src/handlers/radarr_handlers/collections/movie_overview_handler.rs new file mode 100644 index 00000000..57ca1375 --- /dev/null +++ b/src/handlers/radarr_handlers/collections/movie_overview_handler.rs @@ -0,0 +1,102 @@ +use crate::app::App; +use crate::event::Key; +use crate::handlers::KeyEventHandler; +use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; +use crate::models::{Route, Scrollable, ScrollableText}; + +#[cfg(test)] +#[path = "movie_overview_handler_tests.rs"] +mod movie_overview_handler_tests; + +pub(super) struct MovieOverviewHandler<'a, 'b> { + key: Key, + app: &'a mut App<'b>, + _active_radarr_block: ActiveRadarrBlock, + _context: Option, +} + +impl MovieOverviewHandler<'_, '_> { + fn overview(&mut self) -> &mut ScrollableText { + &mut self + .app + .data + .radarr_data + .movie_overview_modal + .as_mut() + .expect("Movie overview modal is undefined") + .overview + } +} + +impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieOverviewHandler<'a, 'b> { + fn accepts(active_block: ActiveRadarrBlock) -> bool { + active_block == ActiveRadarrBlock::ViewMovieOverview + } + + fn ignore_special_keys(&self) -> bool { + self.app.ignore_special_keys_for_textbox_input + } + + fn new( + key: Key, + app: &'a mut App<'b>, + active_block: ActiveRadarrBlock, + _context: Option, + ) -> MovieOverviewHandler<'a, 'b> { + MovieOverviewHandler { + key, + app, + _active_radarr_block: active_block, + _context, + } + } + + fn get_key(&self) -> Key { + self.key + } + + fn is_ready(&self) -> bool { + if self.app.is_loading { + return false; + } + + self.app.data.radarr_data.movie_overview_modal.is_some() + } + + fn handle_scroll_up(&mut self) { + self.overview().scroll_up(); + } + + fn handle_scroll_down(&mut self) { + self.overview().scroll_down(); + } + + fn handle_home(&mut self) { + self.overview().scroll_to_top(); + } + + fn handle_end(&mut self) { + self.overview().scroll_to_bottom(); + } + + fn handle_delete(&mut self) {} + + fn handle_left_right_action(&mut self) {} + + fn handle_submit(&mut self) {} + + fn handle_esc(&mut self) { + self.app.pop_navigation_stack(); + self.app.data.radarr_data.movie_overview_modal = None; + } + + fn handle_char_key_event(&mut self) {} + + fn app_mut(&mut self) -> &mut App<'b> { + self.app + } + + fn current_route(&self) -> Route { + self.app.get_current_route() + } +} diff --git a/src/handlers/radarr_handlers/collections/movie_overview_handler_tests.rs b/src/handlers/radarr_handlers/collections/movie_overview_handler_tests.rs new file mode 100644 index 00000000..ce345fc3 --- /dev/null +++ b/src/handlers/radarr_handlers/collections/movie_overview_handler_tests.rs @@ -0,0 +1,345 @@ +#[cfg(test)] +mod tests { + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::app::key_binding::DEFAULT_KEYBINDINGS; + use crate::handlers::KeyEventHandler; + use crate::handlers::radarr_handlers::collections::movie_overview_handler::MovieOverviewHandler; + use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; + + mod test_handle_scroll_up_and_down { + use super::*; + use pretty_assertions::assert_eq; + + #[test] + fn test_movie_overview_scroll_up() { + let mut app = app_with_movie_overview(); + set_offset(&mut app, 2); + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.up.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 1); + } + + #[test] + fn test_movie_overview_scroll_up_no_op_when_not_ready() { + let mut app = app_with_movie_overview(); + set_offset(&mut app, 2); + app.is_loading = true; + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.up.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 2); + } + + #[test] + fn test_movie_overview_scroll_down() { + let mut app = app_with_movie_overview(); + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.down.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 1); + } + + #[test] + fn test_movie_overview_scroll_down_no_op_when_not_ready() { + let mut app = app_with_movie_overview(); + app.is_loading = true; + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.down.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 0); + } + } + + mod test_handle_home_end { + use super::*; + use pretty_assertions::assert_eq; + + #[test] + fn test_movie_overview_home() { + let mut app = app_with_movie_overview(); + set_offset(&mut app, 3); + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.home.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 0); + } + + #[test] + fn test_movie_overview_end() { + let mut app = app_with_movie_overview(); + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.end.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 5); + } + + #[test] + fn test_movie_overview_home_no_op_when_not_ready() { + let mut app = app_with_movie_overview(); + set_offset(&mut app, 3); + app.is_loading = true; + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.home.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 3); + } + + #[test] + fn test_movie_overview_end_no_op_when_not_ready() { + let mut app = app_with_movie_overview(); + app.is_loading = true; + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.end.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 0); + } + } + + mod test_handle_esc { + use super::*; + use crate::{assert_modal_absent, assert_navigation_popped}; + + #[test] + fn test_movie_overview_esc_tears_down_the_movie_overview_modal() { + let mut app = app_with_movie_overview(); + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.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); + } + + #[test] + fn test_movie_overview_esc_tears_down_the_modal_even_when_loading() { + let mut app = app_with_movie_overview(); + app.is_loading = true; + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.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); + } + } + + #[test] + fn test_scrolling_the_overview_does_not_mutate_the_collection_movie_record() { + let mut app = app_with_movie_overview(); + let overview_before = app + .data + .radarr_data + .collection_movies + .current_selection() + .overview + .clone(); + + MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.down.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ) + .handle(); + + assert_eq!(overview_offset(&app), 1); + assert_eq!( + app + .data + .radarr_data + .collection_movies + .current_selection() + .overview, + overview_before + ); + } + + #[test] + fn test_movie_overview_handler_accepts() { + ActiveRadarrBlock::iter().for_each(|active_radarr_block| { + if active_radarr_block == ActiveRadarrBlock::ViewMovieOverview { + assert!( + MovieOverviewHandler::accepts(active_radarr_block), + "{active_radarr_block} is not accepted by the MovieOverviewHandler" + ); + } else { + assert!( + !MovieOverviewHandler::accepts(active_radarr_block), + "{active_radarr_block} is wrongly accepted by the MovieOverviewHandler" + ); + } + }); + } + + #[test] + fn test_movie_overview_handler_dispatches_no_network_events() { + let mut app = app_with_movie_overview(); + + for key in [ + DEFAULT_KEYBINDINGS.up.key, + DEFAULT_KEYBINDINGS.down.key, + DEFAULT_KEYBINDINGS.home.key, + DEFAULT_KEYBINDINGS.end.key, + DEFAULT_KEYBINDINGS.delete.key, + DEFAULT_KEYBINDINGS.left.key, + DEFAULT_KEYBINDINGS.right.key, + DEFAULT_KEYBINDINGS.submit.key, + DEFAULT_KEYBINDINGS.refresh.key, + ] { + MovieOverviewHandler::new(key, &mut app, ActiveRadarrBlock::ViewMovieOverview, None).handle(); + + assert_none!(app.data.radarr_data.prompt_confirm_action); + assert!(!app.data.radarr_data.prompt_confirm); + } + } + + #[test] + fn test_movie_overview_handler_is_not_ready_when_loading() { + let mut app = app_with_movie_overview(); + app.is_loading = true; + + let handler = MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.up.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ); + + assert!(!handler.is_ready()); + } + + #[test] + fn test_movie_overview_handler_is_not_ready_when_the_modal_is_absent() { + let mut app = app_with_movie_overview(); + app.data.radarr_data.movie_overview_modal = None; + + let handler = MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.up.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ); + + assert!(!handler.is_ready()); + } + + #[test] + fn test_movie_overview_handler_is_ready() { + let mut app = app_with_movie_overview(); + + let handler = MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.up.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ); + + assert!(handler.is_ready()); + } + + #[test] + fn test_movie_overview_handler_ignores_special_keys_for_textbox_input() { + let mut app = app_with_movie_overview(); + app.ignore_special_keys_for_textbox_input = true; + + let handler = MovieOverviewHandler::new( + DEFAULT_KEYBINDINGS.up.key, + &mut app, + ActiveRadarrBlock::ViewMovieOverview, + None, + ); + + assert!(handler.ignore_special_keys()); + } + + fn app_with_movie_overview() -> App<'static> { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); + app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into()); + + app + } + + fn overview_offset(app: &App<'_>) -> u16 { + app + .data + .radarr_data + .movie_overview_modal + .as_ref() + .unwrap() + .overview + .offset + } + + fn set_offset(app: &mut App<'_>, offset: u16) { + app + .data + .radarr_data + .movie_overview_modal + .as_mut() + .unwrap() + .overview + .offset = offset; + } +} diff --git a/src/handlers/radarr_handlers/radarr_handler_test_utils.rs b/src/handlers/radarr_handlers/radarr_handler_test_utils.rs index cc54e07c..92c0f4a8 100644 --- a/src/handlers/radarr_handlers/radarr_handler_test_utils.rs +++ b/src/handlers/radarr_handlers/radarr_handler_test_utils.rs @@ -295,7 +295,12 @@ pub(in crate::handlers::radarr_handlers) mod utils { pub fn collection_movie() -> CollectionMovie { CollectionMovie { title: "Test".to_owned().into(), - overview: "Collection blah blah blah".to_owned(), + overview: "Collection movie blah blah blah\r\n\ + \r\n\ + It was shot in Madison, Wisconsin: a city the cast never really left.\r\n\ + \r\n\ + The sequel took seven years to finish.\r\n" + .to_owned(), year: 2023, runtime: 120, tmdb_id: 1234, diff --git a/src/models/servarr_data/radarr/modals.rs b/src/models/servarr_data/radarr/modals.rs index 9dd2c599..b96cbfeb 100644 --- a/src/models/servarr_data/radarr/modals.rs +++ b/src/models/servarr_data/radarr/modals.rs @@ -247,3 +247,9 @@ impl From<&RadarrData<'_>> for EditCollectionModal { edit_collection_modal } } + +#[derive(Default)] +#[cfg_attr(test, derive(Debug))] +pub struct MovieOverviewModal { + pub overview: ScrollableText, +} diff --git a/src/models/servarr_data/radarr/modals_tests.rs b/src/models/servarr_data/radarr/modals_tests.rs index dabac4da..f12c70d0 100644 --- a/src/models/servarr_data/radarr/modals_tests.rs +++ b/src/models/servarr_data/radarr/modals_tests.rs @@ -2,7 +2,7 @@ mod test { use crate::models::radarr_models::{Collection, MinimumAvailability, Movie, MovieMonitor}; use crate::models::servarr_data::radarr::modals::{ - AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, + AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, MovieOverviewModal, }; use crate::models::servarr_data::radarr::radarr_data::RadarrData; use crate::models::servarr_data::radarr::radarr_data::radarr_test_utils::utils::create_test_radarr_data; @@ -254,4 +254,11 @@ mod test { assert_eq!(edit_collection_modal.monitored, Some(true)); assert_eq!(edit_collection_modal.search_on_add, Some(true)); } + + #[test] + fn test_movie_overview_modal_default() { + let movie_overview_modal = MovieOverviewModal::default(); + + assert_is_empty!(movie_overview_modal.overview); + } } diff --git a/src/models/servarr_data/radarr/radarr_data.rs b/src/models/servarr_data/radarr/radarr_data.rs index 22fc4a1d..3282f3e3 100644 --- a/src/models/servarr_data/radarr/radarr_data.rs +++ b/src/models/servarr_data/radarr/radarr_data.rs @@ -12,7 +12,7 @@ use crate::models::radarr_models::{ }; use crate::models::servarr_data::modals::{EditIndexerModal, IndexerTestResultModalItem}; use crate::models::servarr_data::radarr::modals::{ - AddMovieModal, EditCollectionModal, EditMovieModal, MovieDetailsModal, + AddMovieModal, EditCollectionModal, EditMovieModal, MovieDetailsModal, MovieOverviewModal, }; use crate::models::servarr_models::{DiskSpace, Indexer, QueueEvent, RootFolder}; use crate::models::stateful_list::StatefulList; @@ -86,6 +86,7 @@ pub struct RadarrData<'a> { pub indexer_test_errors: Option, pub indexer_test_all_results: Option>, pub movie_details_modal: Option, + pub movie_overview_modal: Option, pub prompt_confirm: bool, pub prompt_confirm_action: Option, pub delete_movie_files: bool, @@ -158,6 +159,7 @@ impl<'a> Default for RadarrData<'a> { indexer_test_errors: None, indexer_test_all_results: None, movie_details_modal: None, + movie_overview_modal: None, prompt_confirm: false, prompt_confirm_action: None, delete_movie_files: false, @@ -360,6 +362,10 @@ impl RadarrData<'_> { .movie_releases .sorting(vec![sort_option!(indexer_id)]); + let movie_overview_modal = MovieOverviewModal { + overview: ScrollableText::with_string(collection_movie().overview.clone()), + }; + let mut radarr_data = RadarrData { disk_space_vec: vec![diskspace()], version: "1.2.3.4".to_owned(), @@ -378,6 +384,7 @@ impl RadarrData<'_> { indexer_test_errors: Some("error".into()), indexer_test_all_results: Some(indexer_test_results), movie_details_modal: Some(movie_details_modal), + movie_overview_modal: Some(movie_overview_modal), delete_movie_files: true, ..RadarrData::default() }; diff --git a/src/models/servarr_data/radarr/radarr_data_tests.rs b/src/models/servarr_data/radarr/radarr_data_tests.rs index 15b25f0e..67145dee 100644 --- a/src/models/servarr_data/radarr/radarr_data_tests.rs +++ b/src/models/servarr_data/radarr/radarr_data_tests.rs @@ -135,6 +135,7 @@ mod tests { assert_none!(&radarr_data.indexer_test_errors); assert_none!(&radarr_data.indexer_test_all_results); assert_none!(&radarr_data.movie_details_modal); + assert_none!(&radarr_data.movie_overview_modal); assert_none!(&radarr_data.prompt_confirm_action); assert!(!radarr_data.prompt_confirm); assert!(!radarr_data.delete_movie_files); diff --git a/src/network/radarr_network/collections/radarr_collections_network_tests.rs b/src/network/radarr_network/collections/radarr_collections_network_tests.rs index 903cc514..e5b4a687 100644 --- a/src/network/radarr_network/collections/radarr_collections_network_tests.rs +++ b/src/network/radarr_network/collections/radarr_collections_network_tests.rs @@ -28,7 +28,7 @@ mod tests { "movies": [ { "title": "Test", - "overview": "Collection blah blah blah", + "overview": "Collection movie blah blah blah\r\n\r\nIt was shot in Madison, Wisconsin: a city the cast never really left.\r\n\r\nThe sequel took seven years to finish.\r\n", "year": 2023, "runtime": 120, "tmdbId": 1234, @@ -109,7 +109,7 @@ mod tests { "movies": [ { "title": "Test", - "overview": "Collection blah blah blah", + "overview": "Collection movie blah blah blah\r\n\r\nIt was shot in Madison, Wisconsin: a city the cast never really left.\r\n\r\nThe sequel took seven years to finish.\r\n", "year": 2023, "runtime": 120, "tmdbId": 1234, @@ -189,7 +189,7 @@ mod tests { "qualityProfileId": 2222, "movies": [{ "title": "Test", - "overview": "Collection blah blah blah", + "overview": "Collection movie blah blah blah\r\n\r\nIt was shot in Madison, Wisconsin: a city the cast never really left.\r\n\r\nThe sequel took seven years to finish.\r\n", "year": 2023, "runtime": 120, "tmdbId": 1234, @@ -218,7 +218,7 @@ mod tests { "qualityProfileId": 2222, "movies": [{ "title": "Test", - "overview": "Collection blah blah blah", + "overview": "Collection movie blah blah blah\r\n\r\nIt was shot in Madison, Wisconsin: a city the cast never really left.\r\n\r\nThe sequel took seven years to finish.\r\n", "year": 2023, "runtime": 120, "tmdbId": 1234, @@ -306,7 +306,7 @@ mod tests { "qualityProfileId": 2222, "movies": [{ "title": "Test", - "overview": "Collection blah blah blah", + "overview": "Collection movie blah blah blah\r\n\r\nIt was shot in Madison, Wisconsin: a city the cast never really left.\r\n\r\nThe sequel took seven years to finish.\r\n", "year": 2023, "runtime": 120, "tmdbId": 1234, @@ -335,7 +335,7 @@ mod tests { "qualityProfileId": 2222, "movies": [{ "title": "Test", - "overview": "Collection blah blah blah", + "overview": "Collection movie blah blah blah\r\n\r\nIt was shot in Madison, Wisconsin: a city the cast never really left.\r\n\r\nThe sequel took seven years to finish.\r\n", "year": 2023, "runtime": 120, "tmdbId": 1234, diff --git a/src/network/radarr_network/radarr_network_test_utils.rs b/src/network/radarr_network/radarr_network_test_utils.rs index b361f34f..8888dbdb 100644 --- a/src/network/radarr_network/radarr_network_test_utils.rs +++ b/src/network/radarr_network/radarr_network_test_utils.rs @@ -79,7 +79,7 @@ pub mod test_utils { "movies": [ { "title": "Test", - "overview": "Collection blah blah blah", + "overview": "Collection movie blah blah blah\r\n\r\nIt was shot in Madison, Wisconsin: a city the cast never really left.\r\n\r\nThe sequel took seven years to finish.\r\n", "year": 2023, "runtime": 120, "tmdbId": 1234, @@ -177,7 +177,12 @@ pub mod test_utils { pub fn collection_movie() -> CollectionMovie { CollectionMovie { title: "Test".to_owned().into(), - overview: "Collection blah blah blah".to_owned(), + overview: "Collection movie blah blah blah\r\n\ + \r\n\ + It was shot in Madison, Wisconsin: a city the cast never really left.\r\n\ + \r\n\ + The sequel took seven years to finish.\r\n" + .to_owned(), year: 2023, runtime: 120, tmdb_id: 1234, diff --git a/src/ui/radarr_ui/collections/collection_details_ui.rs b/src/ui/radarr_ui/collections/collection_details_ui.rs index f0bf0d42..250b88ab 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui.rs @@ -1,7 +1,7 @@ use ratatui::Frame; use ratatui::layout::{Constraint, Flex, Layout, Rect}; use ratatui::style::Stylize; -use ratatui::text::{Line, Text}; +use ratatui::text::{Line, Span, Text}; use ratatui::widgets::{Cell, Paragraph, Row, Wrap}; use crate::app::App; @@ -10,11 +10,12 @@ use crate::models::radarr_models::CollectionMovie; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, }; -use crate::ui::styles::ManagarrStyle; +use crate::ui::styles::{ManagarrStyle, default_style}; use crate::ui::utils::{ borderless_block, get_width_from_percentage, layout_block_top_border_with_title, title_block, title_style, }; +use crate::ui::widgets::loading_block::LoadingBlock; use crate::ui::widgets::managarr_table::ManagarrTable; use crate::ui::widgets::popup::Size; use crate::ui::{DrawUi, draw_popup}; @@ -219,20 +220,35 @@ fn draw_movie_overview(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { .flex(Flex::SpaceBetween) .margin(1) .areas(area); - let overview = Text::from( - app - .data - .radarr_data - .collection_movies - .current_selection() - .clone() - .overview, - ) - .default_color(); - let paragraph = Paragraph::new(overview) - .block(borderless_block()) - .wrap(Wrap { trim: false }); + match app.data.radarr_data.movie_overview_modal.as_ref() { + Some(movie_overview_modal) if !app.is_loading => { + let overview = &movie_overview_modal.overview; + let text = Text::from( + overview + .items + .iter() + .map(|line| overview_line(line)) + .collect::>>(), + ); - f.render_widget(paragraph, paragraph_area); + let paragraph = Paragraph::new(text) + .block(borderless_block()) + .wrap(Wrap { trim: false }) + .scroll((overview.offset, 0)); + + f.render_widget(paragraph, paragraph_area); + } + _ => f.render_widget( + LoadingBlock::new( + app.is_loading || app.data.radarr_data.movie_overview_modal.is_none(), + borderless_block(), + ), + paragraph_area, + ), + } +} + +fn overview_line(line: &str) -> Line<'static> { + Line::from(Span::styled(line.trim_end().to_owned(), default_style())) } diff --git a/src/ui/radarr_ui/collections/collection_details_ui_tests.rs b/src/ui/radarr_ui/collections/collection_details_ui_tests.rs index 9a78c2fd..b727a4a2 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui_tests.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui_tests.rs @@ -1,5 +1,6 @@ #[cfg(test)] mod tests { + use pretty_assertions::assert_str_eq; use strum::IntoEnumIterator; use crate::app::App; @@ -7,9 +8,39 @@ mod tests { ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, }; use crate::ui::DrawUi; - use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi; + use crate::ui::radarr_ui::collections::collection_details_ui::{ + CollectionDetailsUi, overview_line, + }; use crate::ui::ui_test_utils::test_utils::{TerminalSize, render_to_string_with_app}; + #[test] + fn test_overview_line_trims_a_trailing_carriage_return() { + let line = overview_line("The sequel took seven years to finish.\r"); + + assert_str_eq!( + line.spans[0].content, + "The sequel took seven years to finish." + ); + } + + #[test] + fn test_overview_line_renders_a_carriage_return_only_line_as_blank() { + let line = overview_line("\r"); + + assert_str_eq!(line.spans[0].content, ""); + } + + #[test] + fn test_overview_line_does_not_split_a_label_from_a_colon_in_the_prose() { + let line = overview_line("It was shot in Madison, Wisconsin: a city the cast never left."); + + assert_eq!(line.spans.len(), 1); + assert_str_eq!( + line.spans[0].content, + "It was shot in Madison, Wisconsin: a city the cast never left." + ); + } + #[test] fn test_collection_details_ui_accepts() { ActiveRadarrBlock::iter().for_each(|active_radarr_block| { @@ -36,6 +67,32 @@ mod tests { )); } + #[test] + fn test_scrolling_the_movie_overview_does_not_scroll_the_collection_details_behind_it() { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); + + let before = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + CollectionDetailsUi::draw(f, app, f.area()); + }); + + app + .data + .radarr_data + .movie_overview_modal + .as_mut() + .unwrap() + .overview + .offset = 3; + + let after = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + CollectionDetailsUi::draw(f, app, f.area()); + }); + + assert_contains!(before, "Overview: Collection blah blah blah"); + assert_str_eq!(before, after); + } + mod snapshot_tests { use super::*; use crate::models::stateful_table::StatefulTable; @@ -59,6 +116,52 @@ mod tests { insta::assert_snapshot!(active_radarr_block.to_string(), output); } + #[test] + fn test_collection_details_ui_renders_scrolled_movie_overview() { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into()); + app + .data + .radarr_data + .movie_overview_modal + .as_mut() + .unwrap() + .overview + .offset = 2; + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + CollectionDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_collection_details_ui_renders_movie_overview_loading() { + let mut app = App::test_default_fully_populated(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + CollectionDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_collection_details_ui_renders_movie_overview_when_the_modal_is_absent() { + let mut app = App::test_default_fully_populated(); + app.data.radarr_data.movie_overview_modal = None; + app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + CollectionDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + #[test] fn test_collection_details_ui_renders_collection_details_empty() { let mut app = App::test_default_fully_populated(); diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__ViewMovieOverview.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__ViewMovieOverview.snap index f1294684..25dfa99e 100644 --- a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__ViewMovieOverview.snap +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__ViewMovieOverview.snap @@ -18,12 +18,12 @@ expression: output │ │ │ │ │ ╭ Overview ────────────────────────────────────────────────────╮ │ - │ Movies ───────────────────│Collection blah blah blah │───────────────────────────│ + │ Movies ───────────────────│Collection movie blah blah blah │───────────────────────────│ │ ✔ Title │ │ │ - │=> ✔ Test │ │family, fun │ - │ │ │ │ - │ │ │ │ + │=> ✔ Test │It was shot in Madison, Wisconsin: a city the cast never really │family, fun │ + │ │left. │ │ │ │ │ │ + │ │The sequel took seven years to finish. │ │ │ │ │ │ │ │ │ │ │ │ │ │ diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_loading.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_loading.snap new file mode 100644 index 00000000..f2d2490d --- /dev/null +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_loading.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/radarr_ui/collections/collection_details_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test Collection ───────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │Overview: Collection blah blah blah │ + │Root Folder Path: /nfs/movies │ + │Quality Profile: HD - 1080p │ + │Minimum Availability: Released │ + │Monitored: Yes │ + │Search on Add: Yes │ + │ │ + │ │ + │ ╭ Overview ────────────────────────────────────────────────────╮ │ + │ Movies ───────────────────│ │───────────────────────────│ + │ │ │ │ + │ │ Loading ... │ │ + │ Loading ... │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ ╰────────────────────────────────────────────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_when_the_modal_is_absent.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_when_the_modal_is_absent.snap new file mode 100644 index 00000000..474665f3 --- /dev/null +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_movie_overview_when_the_modal_is_absent.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/radarr_ui/collections/collection_details_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test Collection ───────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │Overview: Collection blah blah blah │ + │Root Folder Path: /nfs/movies │ + │Quality Profile: HD - 1080p │ + │Minimum Availability: Released │ + │Monitored: Yes │ + │Search on Add: Yes │ + │ │ + │ │ + │ ╭ Overview ────────────────────────────────────────────────────╮ │ + │ Movies ───────────────────│ │───────────────────────────│ + │ ✔ Title │ │ │ + │=> ✔ Test │ Loading ... │family, fun │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ ╰────────────────────────────────────────────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_scrolled_movie_overview.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_scrolled_movie_overview.snap new file mode 100644 index 00000000..b03f945a --- /dev/null +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__snapshot_tests__collection_details_ui_renders_scrolled_movie_overview.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/radarr_ui/collections/collection_details_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test Collection ───────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │Overview: Collection blah blah blah │ + │Root Folder Path: /nfs/movies │ + │Quality Profile: HD - 1080p │ + │Minimum Availability: Released │ + │Monitored: Yes │ + │Search on Add: Yes │ + │ │ + │ │ + │ ╭ Overview ────────────────────────────────────────────────────╮ │ + │ Movies ───────────────────│It was shot in Madison, Wisconsin: a city the cast never really │───────────────────────────│ + │ ✔ Title │left. │ │ + │=> ✔ Test │ │family, fun │ + │ │The sequel took seven years to finish. │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ │ │ │ + │ ╰────────────────────────────────────────────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMoviePrompt_CollectionDetails.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMoviePrompt_CollectionDetails.snap index ae1d2432..5c152515 100644 --- a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMoviePrompt_CollectionDetails.snap +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMoviePrompt_CollectionDetails.snap @@ -13,11 +13,11 @@ expression: output │Root Folder Path: /nfs/movies │ │Quality Profile: HD - 1080p │ │Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │ - │Monitored: Y│ Collection blah blah blah │ │ + │Monitored: Y│ Collection movie blah blah blah │ │ │Search on Ad│ │ │ + │ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │ │ │ │ │ - │ │ │ │ - │ │ │ │ + │ │ The sequel took seven years to finish. │ │ │ Movies ──│ │───────────│ │ ✔ Title │ ╭────────────────────────────────────────────╮ │ │ │=> ✔ Test │ Root Folder: │/nfs ▼ │ │ │ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMinimumAvailability_CollectionDetails.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMinimumAvailability_CollectionDetails.snap index dfb9281c..dbef8d7d 100644 --- a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMinimumAvailability_CollectionDetails.snap +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMinimumAvailability_CollectionDetails.snap @@ -13,11 +13,11 @@ expression: output │Root Folder Path: /nfs/movies │ │Quality Profile: HD - 1080p │ │Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │ - │Monitored: Y│ Collection blah blah blah │ │ + │Monitored: Y│ Collection movie blah blah blah │ │ │Search on Ad│ │ │ + │ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │ │ │ │ │ - │ │ │ │ - │ │ │ │ + │ │ The sequel took seven years to finish. │ │ │ Movies ──│ │───────────│ │ ✔ Title │ ╭────────────────────────────────────────────╮ │ │ │=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMonitor_CollectionDetails.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMonitor_CollectionDetails.snap index 50f15fed..309deaa2 100644 --- a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMonitor_CollectionDetails.snap +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectMonitor_CollectionDetails.snap @@ -13,11 +13,11 @@ expression: output │Root Folder Path: /nfs/movies │ │Quality Profile: HD - 1080p │ │Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │ - │Monitored: Y│ Collection blah blah blah │ │ + │Monitored: Y│ Collection movie blah blah blah │ │ │Search on Ad│ │ │ + │ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │ │ │ │ │ - │ │ │ │ - │ │ │ │ + │ │ The sequel took seven years to finish. │ │ │ Movies ──│ │───────────│ │ ✔ Title │ ╭────────────────────────────────────────────╮ │ │ │=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectQualityProfile_CollectionDetails.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectQualityProfile_CollectionDetails.snap index 4c3ee663..e373d8f7 100644 --- a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectQualityProfile_CollectionDetails.snap +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectQualityProfile_CollectionDetails.snap @@ -13,11 +13,11 @@ expression: output │Root Folder Path: /nfs/movies │ │Quality Profile: HD - 1080p │ │Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │ - │Monitored: Y│ Collection blah blah blah │ │ + │Monitored: Y│ Collection movie blah blah blah │ │ │Search on Ad│ │ │ + │ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │ │ │ │ │ - │ │ │ │ - │ │ │ │ + │ │ The sequel took seven years to finish. │ │ │ Movies ──│ │───────────│ │ ✔ Title │ ╭────────────────────────────────────────────╮ │ │ │=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectRootFolder_CollectionDetails.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectRootFolder_CollectionDetails.snap index 23dfbaaf..91b19825 100644 --- a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectRootFolder_CollectionDetails.snap +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieSelectRootFolder_CollectionDetails.snap @@ -13,11 +13,11 @@ expression: output │Root Folder Path: /nfs/movies │ │Quality Profile: HD - 1080p │ │Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │ - │Monitored: Y│ Collection blah blah blah │ │ + │Monitored: Y│ Collection movie blah blah blah │ │ │Search on Ad│ │ │ + │ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │ │ │ │ │ - │ │ │ │ - │ │ │ │ + │ │ The sequel took seven years to finish. │ │ │ Movies ──│ │───────────│ │ ✔ Title │ ╭────────────────────────────────────────────╮ │ │ │=> ✔ Test │ ╭───────────────────────────────╮ ▼ │ │ │ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieTagsInput_CollectionDetails.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieTagsInput_CollectionDetails.snap index ae1d2432..5c152515 100644 --- a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieTagsInput_CollectionDetails.snap +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__snapshot_tests__AddMovieTagsInput_CollectionDetails.snap @@ -13,11 +13,11 @@ expression: output │Root Folder Path: /nfs/movies │ │Quality Profile: HD - 1080p │ │Minimum Avai╭────────────────────────────────────── Add Movie - Test ───────────────────────────────────────╮ │ - │Monitored: Y│ Collection blah blah blah │ │ + │Monitored: Y│ Collection movie blah blah blah │ │ │Search on Ad│ │ │ + │ │ It was shot in Madison, Wisconsin: a city the cast never really left. │ │ │ │ │ │ - │ │ │ │ - │ │ │ │ + │ │ The sequel took seven years to finish. │ │ │ Movies ──│ │───────────│ │ ✔ Title │ ╭────────────────────────────────────────────╮ │ │ │=> ✔ Test │ Root Folder: │/nfs ▼ │ │ │