Refactored to require handlers to specify the components they rely on and to specify when they are ready. This fixes a lot of bugs with the UI when users try to press buttons while the application is still loading.

This commit is contained in:
2024-07-17 19:55:10 -06:00
parent 9104b7c356
commit d84e7dfcab
49 changed files with 5143 additions and 265 deletions
-1
View File
@@ -40,7 +40,6 @@ mod tests {
},
]
);
assert_str_eq!(app.title, "Managarr");
assert_eq!(app.tick_until_poll, 400);
assert_eq!(app.ticks_until_scroll, 4);
assert_eq!(app.tick_count, 0);
-5
View File
@@ -2,7 +2,6 @@ use anyhow::anyhow;
use log::{debug, error};
use serde::{Deserialize, Serialize};
use tokio::sync::mpsc::Sender;
use tokio::time::Instant;
use tokio_util::sync::CancellationToken;
use crate::app::context_clues::{build_context_clue_string, SERVARR_CONTEXT_CLUES};
@@ -26,11 +25,9 @@ pub struct App<'a> {
cancellation_token: CancellationToken,
pub server_tabs: TabState,
pub error: HorizontallyScrollableText,
pub title: &'static str,
pub tick_until_poll: u64,
pub ticks_until_scroll: u64,
pub tick_count: u64,
pub last_tick: Instant,
pub is_routing: bool,
pub is_loading: bool,
pub should_refresh: bool,
@@ -151,11 +148,9 @@ impl<'a> Default for App<'a> {
contextual_help: None,
},
]),
title: "Managarr",
tick_until_poll: 400,
ticks_until_scroll: 4,
tick_count: 0,
last_tick: Instant::now(),
is_loading: false,
is_routing: false,
should_refresh: false,
+36 -7
View File
@@ -19,17 +19,45 @@ pub trait KeyEventHandler<'a, 'b, T: Into<Route>> {
fn handle_key_event(&mut self) {
let key = self.get_key();
match key {
_ if *key == DEFAULT_KEYBINDINGS.up.key => self.handle_scroll_up(),
_ if *key == DEFAULT_KEYBINDINGS.down.key => self.handle_scroll_down(),
_ if *key == DEFAULT_KEYBINDINGS.home.key => self.handle_home(),
_ if *key == DEFAULT_KEYBINDINGS.end.key => self.handle_end(),
_ if *key == DEFAULT_KEYBINDINGS.delete.key => self.handle_delete(),
_ if *key == DEFAULT_KEYBINDINGS.up.key => {
if self.is_ready() {
self.handle_scroll_up();
}
}
_ if *key == DEFAULT_KEYBINDINGS.down.key => {
if self.is_ready() {
self.handle_scroll_down();
}
}
_ if *key == DEFAULT_KEYBINDINGS.home.key => {
if self.is_ready() {
self.handle_home();
}
}
_ if *key == DEFAULT_KEYBINDINGS.end.key => {
if self.is_ready() {
self.handle_end();
}
}
_ if *key == DEFAULT_KEYBINDINGS.delete.key => {
if self.is_ready() {
self.handle_delete();
}
}
_ if *key == DEFAULT_KEYBINDINGS.left.key || *key == DEFAULT_KEYBINDINGS.right.key => {
self.handle_left_right_action()
}
_ if *key == DEFAULT_KEYBINDINGS.submit.key => self.handle_submit(),
_ if *key == DEFAULT_KEYBINDINGS.submit.key => {
if self.is_ready() {
self.handle_submit();
}
}
_ if *key == DEFAULT_KEYBINDINGS.esc.key => self.handle_esc(),
_ => self.handle_char_key_event(),
_ => {
if self.is_ready() {
self.handle_char_key_event();
}
}
}
}
@@ -40,6 +68,7 @@ pub trait KeyEventHandler<'a, 'b, T: Into<Route>> {
fn accepts(active_block: &'a T) -> bool;
fn with(key: &'a Key, app: &'a mut App<'b>, active_block: &'a T, context: &'a Option<T>) -> Self;
fn get_key(&self) -> &Key;
fn is_ready(&self) -> bool;
fn handle_scroll_up(&mut self);
fn handle_scroll_down(&mut self);
fn handle_home(&mut self);
@@ -1,5 +1,11 @@
#[cfg(test)]
mod tests {
use std::cmp::Ordering;
use chrono::DateTime;
use pretty_assertions::{assert_eq, assert_str_eq};
use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App;
use crate::event::Key;
@@ -10,10 +16,6 @@ mod tests {
};
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS};
use crate::models::stateful_table::SortOption;
use chrono::DateTime;
use pretty_assertions::{assert_eq, assert_str_eq};
use std::cmp::Ordering;
use strum::IntoEnumIterator;
mod test_handle_scroll_up_and_down {
use pretty_assertions::{assert_eq, assert_str_eq};
@@ -35,6 +37,49 @@ mod tests {
to_string
);
#[rstest]
fn test_blocklist_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.blocklist
.set_items(simple_stateful_iterable_vec!(
BlocklistItem,
String,
source_title
));
BlocklistHandler::with(&key, &mut app, &ActiveRadarrBlock::Blocklist, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.blocklist
.current_selection()
.source_title
.to_string(),
"Test 1"
);
BlocklistHandler::with(&key, &mut app, &ActiveRadarrBlock::Blocklist, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.blocklist
.current_selection()
.source_title
.to_string(),
"Test 1"
);
}
#[rstest]
fn test_blocklist_sort_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
@@ -92,10 +137,12 @@ mod tests {
}
mod test_handle_home_end {
use super::*;
use pretty_assertions::{assert_eq, assert_str_eq};
use crate::models::radarr_models::BlocklistItem;
use crate::{extended_stateful_iterable_vec, test_iterable_home_and_end};
use pretty_assertions::{assert_eq, assert_str_eq};
use super::*;
test_iterable_home_and_end!(
test_blocklist_home_and_end,
@@ -108,6 +155,59 @@ mod tests {
to_string
);
#[test]
fn test_blocklist_home_and_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.blocklist
.set_items(extended_stateful_iterable_vec!(
BlocklistItem,
String,
source_title
));
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.blocklist
.current_selection()
.source_title
.to_string(),
"Test 1"
);
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.blocklist
.current_selection()
.source_title
.to_string(),
"Test 1"
);
}
#[test]
fn test_blocklist_sort_home_end() {
let blocklist_field_vec = sort_options();
@@ -157,30 +257,51 @@ mod tests {
}
mod test_handle_delete {
use super::*;
use crate::assert_delete_prompt;
use pretty_assertions::assert_eq;
use super::*;
const DELETE_KEY: Key = DEFAULT_KEYBINDINGS.delete.key;
#[test]
fn test_delete_blocklist_item_prompt() {
assert_delete_prompt!(
BlocklistHandler,
ActiveRadarrBlock::Blocklist,
ActiveRadarrBlock::DeleteBlocklistItemPrompt
let mut app = App::default();
app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(&DELETE_KEY, &mut app, &ActiveRadarrBlock::Blocklist, &None).handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::DeleteBlocklistItemPrompt.into()
);
}
#[test]
fn test_delete_blocklist_item_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(&DELETE_KEY, &mut app, &ActiveRadarrBlock::Blocklist, &None).handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Blocklist.into()
);
}
}
mod test_handle_left_right_action {
use super::*;
use pretty_assertions::assert_eq;
use rstest::rstest;
#[test]
fn test_blocklist_tab_left() {
use super::*;
#[rstest]
fn test_blocklist_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(3);
BlocklistHandler::with(
@@ -201,9 +322,10 @@ mod tests {
);
}
#[test]
fn test_blocklist_tab_right() {
#[rstest]
fn test_blocklist_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(3);
BlocklistHandler::with(
@@ -246,14 +368,44 @@ mod tests {
}
mod test_handle_submit {
use crate::network::radarr_network::RadarrEvent;
use pretty_assertions::assert_eq;
use rstest::rstest;
use crate::network::radarr_network::RadarrEvent;
use super::*;
const SUBMIT_KEY: Key = DEFAULT_KEYBINDINGS.submit.key;
#[test]
fn test_blocklist_submit() {
let mut app = App::default();
app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::Blocklist, &None).handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::BlocklistItemDetails.into()
);
}
#[test]
fn test_blocklist_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::Blocklist, &None).handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Blocklist.into()
);
}
#[rstest]
#[case(
ActiveRadarrBlock::Blocklist,
@@ -271,6 +423,7 @@ mod tests {
#[case] expected_action: RadarrEvent,
) {
let mut app = App::default();
app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into());
@@ -294,6 +447,7 @@ mod tests {
prompt_block: ActiveRadarrBlock,
) {
let mut app = App::default();
app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.push_navigation_stack(prompt_block.into());
@@ -337,11 +491,13 @@ mod tests {
}
mod test_handle_esc {
use super::*;
use crate::handlers::radarr_handlers::downloads::DownloadsHandler;
use pretty_assertions::assert_eq;
use rstest::rstest;
use crate::handlers::radarr_handlers::downloads::DownloadsHandler;
use super::*;
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[rstest]
@@ -408,9 +564,10 @@ mod tests {
);
}
#[test]
fn test_default_esc() {
#[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
@@ -426,18 +583,57 @@ mod tests {
}
mod test_handle_key_char {
use super::*;
use crate::assert_refresh_key;
use pretty_assertions::assert_eq;
use super::*;
#[test]
fn test_refresh_blocklist_key() {
assert_refresh_key!(BlocklistHandler, ActiveRadarrBlock::Blocklist);
let mut app = App::default();
app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Blocklist.into()
);
assert!(app.should_refresh);
}
#[test]
fn test_refresh_blocklist_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Blocklist.into()
);
assert!(!app.should_refresh);
}
#[test]
fn test_clear_blocklist_key() {
let mut app = App::default();
app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.clear.key,
@@ -453,9 +649,31 @@ mod tests {
);
}
#[test]
fn test_clear_blocklist_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.clear.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Blocklist.into()
);
}
#[test]
fn test_sort_key() {
let mut app = App::default();
app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.sort.key,
@@ -475,6 +693,29 @@ mod tests {
);
assert!(!app.data.radarr_data.blocklist.sort_asc);
}
#[test]
fn test_sort_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.sort.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Blocklist.into()
);
assert!(app.data.radarr_data.blocklist.sort.is_none());
assert!(!app.data.radarr_data.blocklist.sort_asc);
}
}
#[test]
@@ -612,6 +853,67 @@ mod tests {
assert_str_eq!(sort_option.name, "Date");
}
#[test]
fn test_blocklist_handler_accepts() {
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if BLOCKLIST_BLOCKS.contains(&active_radarr_block) {
assert!(BlocklistHandler::accepts(&active_radarr_block));
} else {
assert!(!BlocklistHandler::accepts(&active_radarr_block));
}
})
}
#[test]
fn test_blocklist_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_blocklist_handler_not_ready_when_blocklist_is_empty() {
let mut app = App::default();
app.is_loading = false;
let handler = BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_blocklist_handler_ready_when_not_loading_and_blocklist_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app
.data
.radarr_data
.blocklist
.set_items(vec![BlocklistItem::default()]);
let handler = BlocklistHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Blocklist,
&None,
);
assert!(handler.is_ready());
}
fn blocklist_vec() -> Vec<BlocklistItem> {
vec![
BlocklistItem {
@@ -692,15 +994,4 @@ mod tests {
}),
}]
}
#[test]
fn test_blocklist_handler_accepts() {
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if BLOCKLIST_BLOCKS.contains(&active_radarr_block) {
assert!(BlocklistHandler::accepts(&active_radarr_block));
} else {
assert!(!BlocklistHandler::accepts(&active_radarr_block));
}
})
}
}
@@ -43,6 +43,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && !self.app.data.radarr_data.blocklist.is_empty()
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::Blocklist => self.app.data.radarr_data.blocklist.scroll_up(),
@@ -43,6 +43,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && !self.app.data.radarr_data.collection_movies.is_empty()
}
fn handle_scroll_up(&mut self) {
if ActiveRadarrBlock::CollectionDetails == *self.active_radarr_block {
self.app.data.radarr_data.collection_movies.scroll_up()
@@ -31,6 +31,53 @@ mod tests {
title,
to_string
);
#[rstest]
fn test_collection_details_scroll_no_op_when_not_ready(
#[values(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key
)]
key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.collection_movies
.set_items(simple_stateful_iterable_vec!(
CollectionMovie,
HorizontallyScrollableText
));
CollectionDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::CollectionDetails, &None)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.collection_movies
.current_selection()
.title
.to_string(),
"Test 1"
);
CollectionDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::CollectionDetails, &None)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.collection_movies
.current_selection()
.title
.to_string(),
"Test 1"
);
}
}
mod test_handle_home_end {
@@ -48,6 +95,58 @@ mod tests {
title,
to_string
);
#[test]
fn test_collection_details_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.collection_movies
.set_items(extended_stateful_iterable_vec!(
CollectionMovie,
HorizontallyScrollableText
));
CollectionDetailsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::CollectionDetails,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.collection_movies
.current_selection()
.title
.to_string(),
"Test 1"
);
CollectionDetailsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::CollectionDetails,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.collection_movies
.current_selection()
.title
.to_string(),
"Test 1"
);
}
}
mod test_handle_submit {
@@ -139,6 +238,32 @@ mod tests {
);
}
#[test]
fn test_collection_details_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app
.data
.radarr_data
.collection_movies
.set_items(vec![CollectionMovie::default()]);
CollectionDetailsHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::CollectionDetails,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::CollectionDetails.into()
);
assert!(app.data.radarr_data.add_movie_modal.is_none());
}
#[test]
fn test_collection_details_submit_movie_already_in_library() {
let mut app = App::default();
@@ -169,15 +294,16 @@ mod tests {
}
mod test_handle_esc {
use pretty_assertions::assert_eq;
use super::*;
use pretty_assertions::assert_eq;
use rstest::rstest;
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_esc_collection_details() {
#[rstest]
fn test_esc_collection_details(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app
@@ -225,7 +351,6 @@ mod tests {
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};
@@ -233,7 +358,6 @@ mod tests {
use crate::models::servarr_data::radarr::radarr_data::{
RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS,
};
use crate::test_edit_collection_key;
use super::*;
@@ -246,6 +370,37 @@ mod tests {
ActiveRadarrBlock::CollectionDetails
);
}
#[test]
fn test_edit_key_no_op_when_not_ready() {
let mut app = App::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::with(
&DEFAULT_KEYBINDINGS.edit.key,
&mut app,
&ActiveRadarrBlock::CollectionDetails,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::CollectionDetails.into()
);
assert!(app.data.radarr_data.edit_collection_modal.is_none());
}
}
#[test]
@@ -258,4 +413,54 @@ mod tests {
}
});
}
#[test]
fn test_collection_details_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = CollectionDetailsHandler::with(
&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::default();
app.is_loading = false;
let handler = CollectionDetailsHandler::with(
&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::default();
app.is_loading = false;
app
.data
.radarr_data
.collection_movies
.set_items(vec![CollectionMovie::default()]);
let handler = CollectionDetailsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::CollectionDetails,
&None,
);
assert!(handler.is_ready());
}
}
@@ -1,9 +1,10 @@
#[cfg(test)]
mod tests {
use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest;
use std::cmp::Ordering;
use std::iter;
use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest;
use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -22,10 +23,10 @@ mod tests {
use crate::{extended_stateful_iterable_vec, test_handler_delegation};
mod test_handle_scroll_up_and_down {
use pretty_assertions::assert_eq;
use rstest::rstest;
use crate::{simple_stateful_iterable_vec, test_iterable_scroll};
use pretty_assertions::assert_eq;
use super::*;
@@ -40,6 +41,51 @@ mod tests {
to_string
);
#[rstest]
fn test_collections_scroll_no_op_when_not_ready(
#[values(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key
)]
key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.collections
.set_items(simple_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
CollectionsHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.collections
.current_selection()
.title
.to_string(),
"Test 1"
);
CollectionsHandler::with(&key, &mut app, &ActiveRadarrBlock::Collections, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.collections
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[rstest]
fn test_collections_sort_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
@@ -114,9 +160,66 @@ mod tests {
to_string
);
#[test]
fn test_collections_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.collections
.set_items(extended_stateful_iterable_vec!(
Collection,
HorizontallyScrollableText
));
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.collections
.current_selection()
.title
.to_string(),
"Test 1"
);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.collections
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[test]
fn test_collection_search_box_home_end_keys() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.data.radarr_data.collections.search = Some("Test".into());
CollectionsHandler::with(
@@ -165,6 +268,11 @@ mod tests {
#[test]
fn test_collection_filter_box_home_end_keys() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.data.radarr_data.collections.filter = Some("Test".into());
CollectionsHandler::with(
@@ -264,9 +372,10 @@ mod tests {
use super::*;
#[test]
fn test_collections_tab_left() {
#[rstest]
fn test_collections_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(1);
CollectionsHandler::with(
@@ -284,9 +393,10 @@ mod tests {
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
}
#[test]
fn test_collections_tab_right() {
#[rstest]
fn test_collections_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(1);
CollectionsHandler::with(
@@ -443,6 +553,11 @@ mod tests {
#[test]
fn test_collections_submit() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&SUBMIT_KEY,
@@ -458,6 +573,31 @@ mod tests {
);
}
#[test]
fn test_collections_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
}
#[test]
fn test_search_collections_submit() {
let mut app = App::default();
@@ -661,6 +801,11 @@ mod tests {
#[test]
fn test_update_all_collections_prompt_confirm_submit() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
@@ -687,6 +832,11 @@ mod tests {
#[test]
fn test_update_all_collections_prompt_decline_submit() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
@@ -849,9 +999,10 @@ mod tests {
);
}
#[test]
fn test_default_esc() {
#[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
@@ -881,7 +1032,6 @@ mod tests {
mod test_handle_key_char {
use bimap::BiMap;
use pretty_assertions::{assert_eq, assert_str_eq};
use strum::IntoEnumIterator;
use crate::models::radarr_models::MinimumAvailability;
@@ -889,15 +1039,18 @@ mod tests {
use crate::models::servarr_data::radarr::radarr_data::{
RadarrData, EDIT_COLLECTION_SELECTION_BLOCKS,
};
use crate::models::stateful_table::StatefulTable;
use crate::{assert_refresh_key, test_edit_collection_key};
use crate::test_edit_collection_key;
use super::*;
#[test]
fn test_search_collections_key() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.search.key,
@@ -918,9 +1071,41 @@ mod tests {
);
}
#[test]
fn test_search_collections_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.search.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
assert!(!app.should_ignore_quit_key);
assert_eq!(app.data.radarr_data.collections.search, None);
}
#[test]
fn test_filter_collections_key() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.filter.key,
@@ -938,13 +1123,44 @@ mod tests {
assert!(app.data.radarr_data.collections.filter.is_some());
}
#[test]
fn test_filter_collections_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.filter.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
assert!(!app.should_ignore_quit_key);
assert!(app.data.radarr_data.collections.filter.is_none());
}
#[test]
fn test_filter_collections_key_resets_previous_filter() {
let mut app = App::default();
app.data.radarr_data = create_test_radarr_data();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.data.radarr_data = create_test_radarr_data();
app.data.radarr_data.collections = StatefulTable::default();
app.data.radarr_data.collections.filter = Some("Test".into());
CollectionsHandler::with(
@@ -977,9 +1193,45 @@ mod tests {
);
}
#[test]
fn test_collection_edit_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.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;
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.edit.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
assert!(app.data.radarr_data.edit_collection_modal.is_none());
}
#[test]
fn test_update_key() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
@@ -995,14 +1247,90 @@ mod tests {
);
}
#[test]
fn test_update_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
}
#[test]
fn test_refresh_collections_key() {
assert_refresh_key!(CollectionsHandler, ActiveRadarrBlock::Collections);
let mut app = App::default();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
assert!(app.should_refresh);
}
#[test]
fn test_refresh_collections_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
assert!(!app.should_refresh);
}
#[test]
fn test_search_collections_box_backspace_key() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.data.radarr_data.collections.search = Some("Test".into());
CollectionsHandler::with(
@@ -1029,7 +1357,11 @@ mod tests {
#[test]
fn test_filter_collections_box_backspace_key() {
let mut app = App::default();
app.data.radarr_data.collections = StatefulTable::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.data.radarr_data.collections.filter = Some("Test".into());
CollectionsHandler::with(
@@ -1056,6 +1388,11 @@ mod tests {
#[test]
fn test_search_collections_box_char_key() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.data.radarr_data.collections.search = Some(HorizontallyScrollableText::default());
CollectionsHandler::with(
@@ -1082,7 +1419,11 @@ mod tests {
#[test]
fn test_filter_collections_box_char_key() {
let mut app = App::default();
app.data.radarr_data.collections = StatefulTable::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
app.data.radarr_data.collections.filter = Some(HorizontallyScrollableText::default());
CollectionsHandler::with(
@@ -1109,6 +1450,11 @@ mod tests {
#[test]
fn test_sort_key() {
let mut app = App::default();
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.sort.key,
@@ -1135,6 +1481,33 @@ mod tests {
);
assert!(!app.data.radarr_data.collections.sort_asc);
}
#[test]
fn test_sort_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.sort.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Collections.into()
);
assert!(app.data.radarr_data.collections.sort.is_none());
assert!(!app.data.radarr_data.collections.sort_asc);
}
}
#[rstest]
@@ -1279,6 +1652,72 @@ mod tests {
assert_str_eq!(sort_option.name, "Monitored");
}
#[test]
fn test_collections_handler_accepts() {
let mut collections_handler_blocks = Vec::new();
collections_handler_blocks.extend(COLLECTIONS_BLOCKS);
collections_handler_blocks.extend(COLLECTION_DETAILS_BLOCKS);
collections_handler_blocks.extend(EDIT_COLLECTION_BLOCKS);
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if collections_handler_blocks.contains(&active_radarr_block) {
assert!(CollectionsHandler::accepts(&active_radarr_block));
} else {
assert!(!CollectionsHandler::accepts(&active_radarr_block));
}
});
}
#[test]
fn test_collections_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_collections_handler_not_ready_when_collections_is_empty() {
let mut app = App::default();
app.is_loading = false;
let handler = CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_collections_handler_ready_when_not_loading_and_collections_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app
.data
.radarr_data
.collections
.set_items(vec![Collection::default()]);
let handler = CollectionsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Collections,
&None,
);
assert!(handler.is_ready());
}
fn collections_vec() -> Vec<Collection> {
vec![
Collection {
@@ -1325,20 +1764,4 @@ mod tests {
}),
}]
}
#[test]
fn test_collections_handler_accepts() {
let mut collections_handler_blocks = Vec::new();
collections_handler_blocks.extend(COLLECTIONS_BLOCKS);
collections_handler_blocks.extend(COLLECTION_DETAILS_BLOCKS);
collections_handler_blocks.extend(EDIT_COLLECTION_BLOCKS);
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if collections_handler_blocks.contains(&active_radarr_block) {
assert!(CollectionsHandler::accepts(&active_radarr_block));
} else {
assert!(!CollectionsHandler::accepts(&active_radarr_block));
}
});
}
}
@@ -41,6 +41,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && self.app.data.radarr_data.edit_collection_modal.is_some()
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability => self
@@ -9,6 +9,7 @@ mod tests {
use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::MinimumAvailability;
use crate::models::servarr_data::radarr::modals::EditCollectionModal;
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS,
};
@@ -146,6 +147,7 @@ mod tests {
#[rstest]
fn test_edit_collection_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&EDIT_COLLECTION_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
@@ -170,6 +172,31 @@ mod tests {
);
}
}
#[rstest]
fn test_edit_collection_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&EDIT_COLLECTION_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
EditCollectionHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::EditCollectionPrompt,
&None,
)
.handle();
assert_eq!(
app.data.radarr_data.selected_block.get_active_block(),
&ActiveRadarrBlock::EditCollectionSelectMinimumAvailability
);
}
}
mod test_handle_home_end {
@@ -479,6 +506,7 @@ mod tests {
#[test]
fn test_edit_collection_prompt_prompt_decline_submit() {
let mut app = App::default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.data.radarr_data.selected_block =
@@ -507,6 +535,7 @@ mod tests {
#[test]
fn test_edit_collection_confirm_prompt_prompt_confirmation_submit() {
let mut app = App::default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.data.radarr_data.prompt_confirm = true;
@@ -537,6 +566,38 @@ mod tests {
assert!(app.should_refresh);
}
#[test]
fn test_edit_collection_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.data.radarr_data.prompt_confirm = true;
app.data.radarr_data.selected_block =
BlockSelectionState::new(&EDIT_COLLECTION_SELECTION_BLOCKS);
app
.data
.radarr_data
.selected_block
.set_index(EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1);
EditCollectionHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::EditCollectionPrompt,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::EditCollectionPrompt.into()
);
assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
assert!(!app.should_refresh);
}
#[test]
fn test_edit_collection_toggle_monitored_submit() {
let current_route = Route::from((
@@ -657,6 +718,7 @@ mod tests {
#[case] index: usize,
) {
let mut app = App::default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(
(
ActiveRadarrBlock::EditCollectionPrompt,
@@ -697,6 +759,7 @@ mod tests {
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.push_navigation_stack(active_radarr_block.into());
@@ -733,6 +796,7 @@ mod tests {
fn test_edit_collection_root_folder_path_input_esc() {
let mut app = App::default();
app.data.radarr_data = create_test_radarr_data();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionRootFolderPathInput.into());
@@ -784,8 +848,10 @@ mod tests {
ActiveRadarrBlock::EditCollectionSelectQualityProfile
)]
active_radarr_block: ActiveRadarrBlock,
#[values(true, false)] is_ready: bool,
) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data = create_test_radarr_data();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(active_radarr_block.into());
@@ -869,4 +935,50 @@ mod tests {
}
});
}
#[test]
fn test_edit_collection_handler_is_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = EditCollectionHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditCollectionPrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_collection_handler_is_not_ready_when_edit_collection_modal_is_none() {
let mut app = App::default();
app.is_loading = false;
let handler = EditCollectionHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditCollectionPrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_collection_handler_is_ready_when_edit_collection_modal_is_some() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
let handler = EditCollectionHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditCollectionPrompt,
&None,
);
assert!(handler.is_ready());
}
}
@@ -67,6 +67,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && !self.app.data.radarr_data.collections.is_empty()
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::Collections => self.app.data.radarr_data.collections.scroll_up(),
@@ -8,6 +8,7 @@ mod tests {
use crate::event::Key;
use crate::handlers::radarr_handlers::downloads::DownloadsHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::DownloadRecord;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS};
mod test_handle_scroll_up_and_down {
@@ -27,6 +28,36 @@ mod tests {
None,
title
);
#[rstest]
fn test_downloads_scroll_no_op_when_not_ready(
#[values(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key
)]
key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.downloads
.set_items(simple_stateful_iterable_vec!(DownloadRecord));
DownloadsHandler::with(&key, &mut app, &ActiveRadarrBlock::Downloads, &None).handle();
assert_str_eq!(
app.data.radarr_data.downloads.current_selection().title,
"Test 1"
);
DownloadsHandler::with(&key, &mut app, &ActiveRadarrBlock::Downloads, &None).handle();
assert_str_eq!(
app.data.radarr_data.downloads.current_selection().title,
"Test 1"
);
}
}
mod test_handle_home_end {
@@ -44,23 +75,85 @@ mod tests {
None,
title
);
#[test]
fn test_downloads_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.downloads
.set_items(extended_stateful_iterable_vec!(DownloadRecord));
DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.downloads.current_selection().title,
"Test 1"
);
DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.downloads.current_selection().title,
"Test 1"
);
}
}
mod test_handle_delete {
use pretty_assertions::assert_eq;
use crate::assert_delete_prompt;
use super::*;
const DELETE_KEY: Key = DEFAULT_KEYBINDINGS.delete.key;
#[test]
fn test_delete_download_prompt() {
assert_delete_prompt!(
DownloadsHandler,
ActiveRadarrBlock::Downloads,
ActiveRadarrBlock::DeleteDownloadPrompt
let mut app = App::default();
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(&DELETE_KEY, &mut app, &ActiveRadarrBlock::Downloads, &None).handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::DeleteDownloadPrompt.into()
);
}
#[test]
fn test_delete_download_prompt_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(&DELETE_KEY, &mut app, &ActiveRadarrBlock::Downloads, &None).handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Downloads.into()
);
}
}
@@ -71,9 +164,10 @@ mod tests {
use super::*;
#[test]
fn test_downloads_tab_left() {
#[rstest]
fn test_downloads_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(2);
DownloadsHandler::with(
@@ -94,9 +188,10 @@ mod tests {
);
}
#[test]
fn test_downloads_tab_right() {
#[rstest]
fn test_downloads_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(2);
DownloadsHandler::with(
@@ -165,6 +260,11 @@ mod tests {
#[case] expected_action: RadarrEvent,
) {
let mut app = App::default();
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into());
@@ -187,6 +287,11 @@ mod tests {
#[case] prompt_block: ActiveRadarrBlock,
) {
let mut app = App::default();
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into());
@@ -224,9 +329,10 @@ mod tests {
assert!(!app.data.radarr_data.prompt_confirm);
}
#[test]
fn test_default_esc() {
#[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
@@ -244,13 +350,16 @@ mod tests {
mod test_handle_key_char {
use pretty_assertions::assert_eq;
use crate::assert_refresh_key;
use super::*;
#[test]
fn test_update_downloads_key() {
let mut app = App::default();
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
@@ -266,9 +375,80 @@ mod tests {
);
}
#[test]
fn test_update_downloads_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Downloads.into()
);
}
#[test]
fn test_refresh_downloads_key() {
assert_refresh_key!(DownloadsHandler, ActiveRadarrBlock::Downloads);
let mut app = App::default();
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Downloads.into()
);
assert!(app.should_refresh);
}
#[test]
fn test_refresh_downloads_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::Downloads.into()
);
assert!(!app.should_refresh);
}
}
@@ -282,4 +462,54 @@ mod tests {
}
})
}
#[test]
fn test_downloads_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_downloads_handler_not_ready_when_downloads_is_empty() {
let mut app = App::default();
app.is_loading = false;
let handler = DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_downloads_handler_ready_when_not_loading_and_downloads_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app
.data
.radarr_data
.downloads
.set_items(vec![DownloadRecord::default()]);
let handler = DownloadsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Downloads,
&None,
);
assert!(handler.is_ready());
}
}
@@ -41,6 +41,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a,
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && !self.app.data.radarr_data.downloads.is_empty()
}
fn handle_scroll_up(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::Downloads {
self.app.data.radarr_data.downloads.scroll_up()
@@ -40,6 +40,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditIndexerHandler<'
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && self.app.data.radarr_data.edit_indexer_modal.is_some()
}
fn handle_scroll_up(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::EditIndexerPrompt {
self.app.data.radarr_data.selected_block.previous();
@@ -1,9 +1,11 @@
#[cfg(test)]
mod tests {
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App;
use crate::event::Key;
use crate::handlers::radarr_handlers::indexers::edit_indexer_handler::EditIndexerHandler;
use crate::handlers::KeyEventHandler;
use crate::models::servarr_data::radarr::modals::EditIndexerModal;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS};
use strum::IntoEnumIterator;
@@ -41,6 +43,26 @@ mod tests {
);
}
}
#[rstest]
fn test_edit_indexer_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
EditIndexerHandler::with(&key, &mut app, &ActiveRadarrBlock::EditIndexerPrompt, &None)
.handle();
assert_eq!(
app.data.radarr_data.selected_block.get_active_block(),
&ActiveRadarrBlock::EditIndexerToggleEnableRss
);
}
}
mod test_handle_home_end {
@@ -803,6 +825,32 @@ mod tests {
);
}
#[test]
fn test_edit_indexer_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.radarr_data.prompt_confirm = true;
EditIndexerHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::EditIndexerPrompt,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::EditIndexerPrompt.into()
);
assert!(app.data.radarr_data.edit_indexer_modal.is_some());
assert!(!app.should_refresh);
assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
}
#[rstest]
#[case(0, ActiveRadarrBlock::EditIndexerNameInput)]
#[case(5, ActiveRadarrBlock::EditIndexerUrlInput)]
@@ -814,6 +862,7 @@ mod tests {
#[case] block: ActiveRadarrBlock,
) {
let mut app = App::default();
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
@@ -1177,9 +1226,10 @@ mod tests {
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_edit_indexer_prompt_esc() {
#[rstest]
fn test_edit_indexer_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
@@ -1518,4 +1568,50 @@ mod tests {
}
})
}
#[test]
fn test_edit_indexer_handler_is_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = EditIndexerHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditIndexerPrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_indexer_handler_is_not_ready_when_edit_indexer_modal_is_none() {
let mut app = App::default();
app.is_loading = false;
let handler = EditIndexerHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditIndexerPrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_indexer_handler_is_ready_when_edit_indexer_modal_is_some() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
let handler = EditIndexerHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditIndexerPrompt,
&None,
);
assert!(handler.is_ready());
}
}
@@ -42,6 +42,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexerSettingsHandl
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && self.app.data.radarr_data.indexer_settings.is_some()
}
fn handle_scroll_up(&mut self) {
let indexer_settings = self.app.data.radarr_data.indexer_settings.as_mut().unwrap();
match self.active_radarr_block {
@@ -7,6 +7,7 @@ mod tests {
use crate::event::Key;
use crate::handlers::radarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::IndexerSettings;
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS,
};
@@ -121,6 +122,31 @@ mod tests {
}
}
#[rstest]
fn test_edit_indexer_settings_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
IndexerSettingsHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::IndexerSettingsPrompt,
&None,
)
.handle();
assert_eq!(
app.data.radarr_data.selected_block.get_active_block(),
&ActiveRadarrBlock::IndexerSettingsRetentionInput
);
}
#[rstest]
fn test_edit_indexer_settings_minimum_age_scroll(#[values(Key::Up, Key::Down)] key: Key) {
test_i64_counter_scroll_value!(
@@ -462,6 +488,30 @@ mod tests {
assert!(app.should_refresh);
}
#[test]
fn test_edit_indexer_settings_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::IndexerSettingsPrompt.into());
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.radarr_data.prompt_confirm = true;
IndexerSettingsHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::IndexerSettingsPrompt,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::IndexerSettingsPrompt.into()
);
assert!(!app.should_refresh);
}
#[rstest]
#[case(ActiveRadarrBlock::IndexerSettingsMinimumAgeInput, 0)]
#[case(ActiveRadarrBlock::IndexerSettingsRetentionInput, 1)]
@@ -473,6 +523,7 @@ mod tests {
#[case] index: usize,
) {
let mut app = App::default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::IndexerSettingsPrompt.into());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&INDEXER_SETTINGS_SELECTION_BLOCKS);
@@ -489,9 +540,36 @@ mod tests {
assert_eq!(app.get_current_route(), &selected_block.into());
}
#[rstest]
fn test_edit_indexer_settings_prompt_submit_selected_block_no_op_when_not_ready(
#[values(0, 1, 2, 5, 6)] index: usize,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::IndexerSettingsPrompt.into());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(index);
IndexerSettingsHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::IndexerSettingsPrompt,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::IndexerSettingsPrompt.into()
);
}
#[test]
fn test_edit_indexer_settings_prompt_submit_whitelisted_subtitle_tags_input() {
let mut app = App::default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::IndexerSettingsPrompt.into());
app.data.radarr_data.selected_block =
BlockSelectionState::new(&INDEXER_SETTINGS_SELECTION_BLOCKS);
@@ -669,6 +747,7 @@ mod tests {
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::IndexerSettingsPrompt.into());
app.push_navigation_stack(active_radarr_block.into());
@@ -691,9 +770,10 @@ mod tests {
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_edit_indexer_settings_prompt_esc() {
#[rstest]
fn test_edit_indexer_settings_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::IndexerSettingsPrompt.into());
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
@@ -837,4 +917,50 @@ mod tests {
}
})
}
#[test]
fn test_edit_indexer_settings_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = IndexerSettingsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::IndexerSettingsPrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_indexer_settings_handler_not_ready_when_indexer_settings_is_none() {
let mut app = App::default();
app.is_loading = false;
let handler = IndexerSettingsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::IndexerSettingsPrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_indexer_settings_handler_ready_when_not_loading_and_indexer_settings_is_some() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
let handler = IndexerSettingsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::IndexerSettingsPrompt,
&None,
);
assert!(handler.is_ready());
}
}
@@ -9,6 +9,7 @@ mod tests {
use crate::event::Key;
use crate::handlers::radarr_handlers::indexers::IndexersHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::Indexer;
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, EDIT_INDEXER_BLOCKS, INDEXERS_BLOCKS, INDEXER_SETTINGS_BLOCKS,
};
@@ -31,6 +32,36 @@ mod tests {
None,
protocol
);
#[rstest]
fn test_indexers_scroll_no_op_when_not_ready(
#[values(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key
)]
key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.indexers
.set_items(simple_stateful_iterable_vec!(Indexer, String, protocol));
IndexersHandler::with(&key, &mut app, &ActiveRadarrBlock::Indexers, &None).handle();
assert_str_eq!(
app.data.radarr_data.indexers.current_selection().protocol,
"Test 1"
);
IndexersHandler::with(&key, &mut app, &ActiveRadarrBlock::Indexers, &None).handle();
assert_str_eq!(
app.data.radarr_data.indexers.current_selection().protocol,
"Test 1"
);
}
}
mod test_handle_home_end {
@@ -48,25 +79,84 @@ mod tests {
None,
protocol
);
#[test]
fn test_indexers_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.indexers
.set_items(extended_stateful_iterable_vec!(Indexer, String, protocol));
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.indexers.current_selection().protocol,
"Test 1"
);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.indexers.current_selection().protocol,
"Test 1"
);
}
}
mod test_handle_delete {
use pretty_assertions::assert_eq;
use crate::assert_delete_prompt;
use super::*;
const DELETE_KEY: Key = DEFAULT_KEYBINDINGS.delete.key;
#[test]
fn test_delete_indexer_prompt() {
assert_delete_prompt!(
IndexersHandler,
ActiveRadarrBlock::Indexers,
ActiveRadarrBlock::DeleteIndexerPrompt
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(&DELETE_KEY, &mut app, &ActiveRadarrBlock::Indexers, &None).handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::DeleteIndexerPrompt.into()
);
}
#[test]
fn test_delete_indexer_prompt_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(&DELETE_KEY, &mut app, &ActiveRadarrBlock::Indexers, &None).handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
}
}
mod test_handle_left_right_action {
@@ -75,9 +165,10 @@ mod tests {
use super::*;
#[test]
fn test_indexers_tab_left() {
#[rstest]
fn test_indexers_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(5);
IndexersHandler::with(
@@ -98,9 +189,10 @@ mod tests {
);
}
#[test]
fn test_indexers_tab_right() {
#[rstest]
fn test_indexers_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(5);
IndexersHandler::with(
@@ -243,9 +335,31 @@ mod tests {
}
}
#[test]
fn test_edit_indexer_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::Indexers, &None).handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
assert_eq!(app.data.radarr_data.edit_indexer_modal, None);
}
#[test]
fn test_delete_indexer_prompt_confirm_submit() {
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into());
@@ -269,6 +383,11 @@ mod tests {
#[test]
fn test_prompt_decline_submit() {
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into());
@@ -293,9 +412,10 @@ mod tests {
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_delete_indexer_prompt_block_esc() {
#[rstest]
fn test_delete_indexer_prompt_block_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into());
app.data.radarr_data.prompt_confirm = true;
@@ -312,9 +432,10 @@ mod tests {
assert!(!app.data.radarr_data.prompt_confirm);
}
#[test]
fn test_test_indexer_esc() {
#[rstest]
fn test_test_indexer_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.indexer_test_error = Some("test result".to_owned());
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::TestIndexer.into());
@@ -325,9 +446,10 @@ mod tests {
assert_eq!(app.data.radarr_data.indexer_test_error, None);
}
#[test]
fn test_default_esc() {
#[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
@@ -342,7 +464,6 @@ mod tests {
mod test_handle_key_char {
use pretty_assertions::assert_eq;
use crate::assert_refresh_key;
use crate::models::servarr_data::radarr::radarr_data::INDEXER_SETTINGS_SELECTION_BLOCKS;
use super::*;
@@ -350,6 +471,11 @@ mod tests {
#[test]
fn test_indexer_add() {
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.add.key,
@@ -365,14 +491,81 @@ mod tests {
);
}
#[test]
fn test_indexer_add_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.add.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
}
#[test]
fn test_refresh_indexers_key() {
assert_refresh_key!(IndexersHandler, ActiveRadarrBlock::Indexers);
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
assert!(app.should_refresh);
}
#[test]
fn test_refresh_indexers_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
assert!(!app.should_refresh);
}
#[test]
fn test_indexer_settings_key() {
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.settings.key,
@@ -392,9 +585,36 @@ mod tests {
);
}
#[test]
fn test_indexer_settings_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.settings.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
}
#[test]
fn test_test_key() {
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.test.key,
@@ -410,9 +630,36 @@ mod tests {
);
}
#[test]
fn test_test_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.test.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
}
#[test]
fn test_test_all_key() {
let mut app = App::default();
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.test_all.key,
@@ -427,6 +674,28 @@ mod tests {
&ActiveRadarrBlock::TestAllIndexers.into()
);
}
#[test]
fn test_test_all_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
IndexersHandler::with(
&DEFAULT_KEYBINDINGS.test_all.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
}
}
#[rstest]
@@ -500,4 +769,54 @@ mod tests {
}
})
}
#[test]
fn test_indexers_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = IndexersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_indexers_handler_not_ready_when_indexers_is_empty() {
let mut app = App::default();
app.is_loading = false;
let handler = IndexersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_indexers_handler_ready_when_not_loading_and_indexers_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app
.data
.radarr_data
.indexers
.set_items(vec![Indexer::default()]);
let handler = IndexersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Indexers,
&None,
);
assert!(handler.is_ready());
}
}
@@ -72,6 +72,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && !self.app.data.radarr_data.indexers.is_empty()
}
fn handle_scroll_up(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::Indexers {
self.app.data.radarr_data.indexers.scroll_up();
@@ -38,6 +38,16 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for TestAllIndexersHandl
self.key
}
fn is_ready(&self) -> bool {
let table_is_ready = if let Some(table) = &self.app.data.radarr_data.indexer_test_all_results {
!table.is_empty()
} else {
false
};
!self.app.is_loading && table_is_ready
}
fn handle_scroll_up(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::TestAllIndexers {
self
@@ -5,7 +5,9 @@ mod tests {
use crate::event::Key;
use crate::handlers::radarr_handlers::indexers::test_all_indexers_handler::TestAllIndexersHandler;
use crate::handlers::KeyEventHandler;
use crate::models::servarr_data::radarr::modals::IndexerTestResultModalItem;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::stateful_table::StatefulTable;
use strum::IntoEnumIterator;
mod test_handle_scroll_up_and_down {
@@ -61,6 +63,51 @@ mod tests {
"Test 1"
);
}
#[rstest]
fn test_test_all_indexers_results_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
let mut indexer_test_results = StatefulTable::default();
indexer_test_results.set_items(simple_stateful_iterable_vec!(
IndexerTestResultModalItem,
String,
name
));
app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results);
TestAllIndexersHandler::with(&key, &mut app, &ActiveRadarrBlock::TestAllIndexers, &None)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.indexer_test_all_results
.as_ref()
.unwrap()
.current_selection()
.name,
"Test 1"
);
TestAllIndexersHandler::with(&key, &mut app, &ActiveRadarrBlock::TestAllIndexers, &None)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.indexer_test_all_results
.as_ref()
.unwrap()
.current_selection()
.name,
"Test 1"
);
}
}
mod test_handle_home_end {
@@ -122,17 +169,71 @@ mod tests {
"Test 1"
);
}
#[test]
fn test_test_all_indexers_results_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
let mut indexer_test_results = StatefulTable::default();
indexer_test_results.set_items(extended_stateful_iterable_vec!(
IndexerTestResultModalItem,
String,
name
));
app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results);
TestAllIndexersHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::TestAllIndexers,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.indexer_test_all_results
.as_ref()
.unwrap()
.current_selection()
.name,
"Test 1"
);
TestAllIndexersHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::TestAllIndexers,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.indexer_test_all_results
.as_ref()
.unwrap()
.current_selection()
.name,
"Test 1"
);
}
}
mod test_handle_esc {
use super::*;
use crate::models::stateful_table::StatefulTable;
use pretty_assertions::assert_eq;
use rstest::rstest;
use super::*;
#[test]
fn test_test_all_indexers_esc() {
#[rstest]
fn test_test_all_indexers_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::TestAllIndexers.into());
app.data.radarr_data.indexer_test_all_results = Some(StatefulTable::default());
@@ -161,4 +262,68 @@ mod tests {
}
});
}
#[test]
fn test_test_all_indexers_handler_is_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = TestAllIndexersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::TestAllIndexers,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_test_all_indexers_handler_is_not_ready_when_results_is_none() {
let mut app = App::default();
app.is_loading = false;
let handler = TestAllIndexersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::TestAllIndexers,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_test_all_indexers_handler_is_not_ready_when_results_is_empty() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.indexer_test_all_results = Some(StatefulTable::default());
let handler = TestAllIndexersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::TestAllIndexers,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_test_all_indexers_handler_is_ready_when_results_is_not_empty_and_is_loaded() {
let mut app = App::default();
app.is_loading = false;
let mut indexer_test_results = StatefulTable::default();
indexer_test_results.set_items(vec![IndexerTestResultModalItem::default()]);
app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results);
let handler = TestAllIndexersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::TestAllIndexers,
&None,
);
assert!(handler.is_ready());
}
}
@@ -41,6 +41,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::AddMovieSearchResults => self
@@ -82,6 +82,62 @@ mod tests {
);
}
#[rstest]
fn test_add_movie_search_results_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(simple_stateful_iterable_vec!(
AddMovieSearchResult,
HorizontallyScrollableText
));
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
AddMovieHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
AddMovieHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[rstest]
fn test_add_movie_select_monitor_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
@@ -342,6 +398,21 @@ mod tests {
);
}
}
#[rstest]
fn test_add_movie_prompt_scroll_no_op_when_not_ready(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.selected_block = BlockSelectionState::new(&ADD_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
AddMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::AddMoviePrompt, &None).handle();
assert_eq!(
app.data.radarr_data.selected_block.get_active_block(),
&ActiveRadarrBlock::AddMovieSelectMonitor
);
}
}
mod test_handle_home_end {
@@ -406,6 +477,60 @@ mod tests {
);
}
#[test]
fn test_add_movie_search_results_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(extended_stateful_iterable_vec!(
AddMovieSearchResult,
HorizontallyScrollableText
));
app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
AddMovieHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
AddMovieHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.add_searched_movies
.as_ref()
.unwrap()
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[test]
fn test_add_movie_select_monitor_home_end() {
let monitor_vec = Vec::from_iter(Monitor::iter());
@@ -970,6 +1095,29 @@ mod tests {
);
}
#[test]
fn test_add_movie_search_results_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into());
let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
AddMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::AddMovieSearchResults,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::AddMovieSearchResults.into()
);
assert!(app.data.radarr_data.add_movie_modal.is_none());
}
#[test]
fn test_add_movie_search_results_submit_does_nothing_on_empty_table() {
let mut app = App::default();
@@ -1155,9 +1303,10 @@ mod tests {
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_add_movie_search_input_esc() {
#[rstest]
fn test_add_movie_search_input_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data = create_test_radarr_data();
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
@@ -1447,4 +1596,34 @@ mod tests {
}
});
}
#[test]
fn test_add_movie_handler_is_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = AddMovieHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::AddMoviePrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_add_movie_handler_is_ready_when_not_loading() {
let mut app = App::default();
app.is_loading = false;
let handler = AddMovieHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::AddMoviePrompt,
&None,
);
assert!(handler.is_ready());
}
}
@@ -38,6 +38,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DeleteMovieHandler<'
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading
}
fn handle_scroll_up(&mut self) {
if *self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt {
self.app.data.radarr_data.selected_block.previous();
@@ -40,6 +40,25 @@ mod tests {
);
}
}
#[rstest]
fn test_delete_movie_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.selected_block =
BlockSelectionState::new(&DELETE_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
DeleteMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::DeleteMoviePrompt, &None)
.handle();
assert_eq!(
app.data.radarr_data.selected_block.get_active_block(),
&ActiveRadarrBlock::DeleteMovieToggleAddListExclusion
);
}
}
mod test_handle_left_right_action {
@@ -139,6 +158,35 @@ mod tests {
assert!(app.data.radarr_data.add_list_exclusion);
}
#[test]
fn test_delete_movie_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
app.data.radarr_data.prompt_confirm = true;
app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true;
DeleteMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::DeleteMoviePrompt.into()
);
assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
assert!(!app.should_refresh);
assert!(app.data.radarr_data.prompt_confirm);
assert!(app.data.radarr_data.delete_movie_files);
assert!(app.data.radarr_data.add_list_exclusion);
}
#[test]
fn test_delete_movie_toggle_delete_files_submit() {
let current_route = ActiveRadarrBlock::DeleteMoviePrompt.into();
@@ -173,12 +221,14 @@ mod tests {
mod test_handle_esc {
use super::*;
use rstest::rstest;
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_delete_movie_prompt_esc() {
#[rstest]
fn test_delete_movie_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
app.data.radarr_data.prompt_confirm = true;
@@ -210,4 +260,34 @@ mod tests {
}
});
}
#[test]
fn test_delete_movie_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = DeleteMovieHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_delete_movie_handler_ready_when_not_loading() {
let mut app = App::default();
app.is_loading = false;
let handler = DeleteMovieHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::DeleteMoviePrompt,
&None,
);
assert!(handler.is_ready());
}
}
@@ -41,6 +41,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a,
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && self.app.data.radarr_data.edit_movie_modal.is_some()
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::EditMovieSelectMinimumAvailability => self
@@ -9,6 +9,7 @@ mod tests {
use crate::handlers::radarr_handlers::library::edit_movie_handler::EditMovieHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::MinimumAvailability;
use crate::models::servarr_data::radarr::modals::EditMovieModal;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS};
mod test_handle_scroll_up_and_down {
@@ -144,6 +145,7 @@ mod tests {
#[rstest]
fn test_edit_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
@@ -161,6 +163,22 @@ mod tests {
);
}
}
#[rstest]
fn test_edit_movie_prompt_scroll_no_op_when_not_ready(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.next();
EditMovieHandler::with(&key, &mut app, &ActiveRadarrBlock::EditMoviePrompt, &None).handle();
assert_eq!(
app.data.radarr_data.selected_block.get_active_block(),
&ActiveRadarrBlock::EditMovieSelectMinimumAvailability
);
}
}
mod test_handle_home_end {
@@ -596,6 +614,7 @@ mod tests {
#[test]
fn test_edit_movie_prompt_prompt_decline_submit() {
let mut app = App::default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS);
@@ -648,6 +667,31 @@ mod tests {
assert!(app.should_refresh);
}
#[test]
fn test_edit_movie_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.data.radarr_data.prompt_confirm = true;
EditMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::EditMoviePrompt,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::EditMoviePrompt.into()
);
assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
assert!(!app.should_refresh);
}
#[test]
fn test_edit_movie_toggle_monitored_submit() {
let current_route = Route::from((
@@ -710,6 +754,7 @@ mod tests {
#[case] index: usize,
) {
let mut app = App::default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(
(
ActiveRadarrBlock::EditMoviePrompt,
@@ -741,6 +786,43 @@ mod tests {
}
}
#[rstest]
fn test_edit_movie_prompt_selected_block_submit_no_op_when_not_ready(
#[values(1, 2, 3, 4)] index: usize,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(
(
ActiveRadarrBlock::EditMoviePrompt,
Some(ActiveRadarrBlock::Movies),
)
.into(),
);
app.data.radarr_data.selected_block = BlockSelectionState::new(&EDIT_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(index);
EditMovieHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::EditMoviePrompt,
&Some(ActiveRadarrBlock::Movies),
)
.handle();
assert_eq!(
app.get_current_route(),
&(
ActiveRadarrBlock::EditMoviePrompt,
Some(ActiveRadarrBlock::Movies),
)
.into()
);
assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
assert!(!app.should_ignore_quit_key);
}
#[rstest]
fn test_edit_movie_prompt_selecting_preferences_blocks_submit(
#[values(
@@ -752,6 +834,7 @@ mod tests {
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.push_navigation_stack(active_radarr_block.into());
@@ -838,8 +921,10 @@ mod tests {
ActiveRadarrBlock::EditMovieSelectQualityProfile
)]
active_radarr_block: ActiveRadarrBlock,
#[values(true, false)] is_ready: bool,
) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data = create_test_radarr_data();
app.push_navigation_stack(active_radarr_block.into());
@@ -974,4 +1059,50 @@ mod tests {
}
});
}
#[test]
fn test_edit_movie_handler_is_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = EditMovieHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditMoviePrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_movie_handler_is_not_ready_when_edit_movie_modal_is_none() {
let mut app = App::default();
app.is_loading = false;
let handler = EditMovieHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditMoviePrompt,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_edit_movie_handler_is_ready_when_edit_movie_modal_is_some() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
let handler = EditMovieHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::EditMoviePrompt,
&None,
);
assert!(handler.is_ready());
}
}
@@ -36,6 +36,48 @@ mod tests {
to_string
);
#[rstest]
fn test_movies_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.movies
.set_items(simple_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
LibraryHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.movies
.current_selection()
.title
.to_string(),
"Test 1"
);
LibraryHandler::with(&key, &mut app, &ActiveRadarrBlock::Movies, &None).handle();
assert_str_eq!(
app
.data
.radarr_data
.movies
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[rstest]
fn test_movies_sort_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
@@ -100,9 +142,66 @@ mod tests {
to_string
);
#[test]
fn test_movies_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.movies
.set_items(extended_stateful_iterable_vec!(
Movie,
HorizontallyScrollableText
));
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.movies
.current_selection()
.title
.to_string(),
"Test 1"
);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_str_eq!(
app
.data
.radarr_data
.movies
.current_selection()
.title
.to_string(),
"Test 1"
);
}
#[test]
fn test_movie_search_box_home_end_keys() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.data.radarr_data.movies.search = Some("Test".into());
LibraryHandler::with(
@@ -151,6 +250,11 @@ mod tests {
#[test]
fn test_movie_filter_box_home_end_keys() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.data.radarr_data.movies.filter = Some("Test".into());
LibraryHandler::with(
@@ -257,6 +361,11 @@ mod tests {
#[test]
fn test_movies_delete() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
assert_delete_prompt!(
LibraryHandler,
@@ -269,6 +378,22 @@ mod tests {
&DELETE_MOVIE_SELECTION_BLOCKS
);
}
#[test]
fn test_movies_delete_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(&DELETE_KEY, &mut app, &ActiveRadarrBlock::Movies, &None).handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
}
}
mod test_handle_left_right_action {
@@ -277,9 +402,10 @@ mod tests {
use super::*;
#[test]
fn test_movie_tab_left() {
#[rstest]
fn test_movie_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(0);
LibraryHandler::with(
@@ -297,9 +423,10 @@ mod tests {
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
}
#[test]
fn test_movie_tab_right() {
#[rstest]
fn test_movie_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(0);
LibraryHandler::with(
@@ -457,6 +584,11 @@ mod tests {
#[test]
fn test_movie_details_submit() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::Movies, &None).handle();
@@ -466,6 +598,22 @@ mod tests {
);
}
#[test]
fn test_movie_details_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(&SUBMIT_KEY, &mut app, &ActiveRadarrBlock::Movies, &None).handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
}
#[test]
fn test_search_movie_submit() {
let mut app = App::default();
@@ -532,6 +680,11 @@ mod tests {
#[test]
fn test_search_filtered_movies_submit() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into());
app
@@ -636,6 +789,11 @@ mod tests {
#[test]
fn test_update_all_movies_prompt_confirm_submit() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
@@ -659,6 +817,11 @@ mod tests {
#[test]
fn test_update_all_movies_prompt_decline_submit() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
@@ -793,9 +956,10 @@ mod tests {
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
}
#[test]
fn test_default_esc() {
#[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
@@ -831,14 +995,18 @@ mod tests {
RadarrData, EDIT_MOVIE_SELECTION_BLOCKS,
};
use crate::models::stateful_table::StatefulTable;
use crate::{assert_refresh_key, test_edit_movie_key};
use crate::test_edit_movie_key;
use super::*;
#[test]
fn test_search_movies_key() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.search.key,
@@ -859,10 +1027,38 @@ mod tests {
);
}
#[test]
fn test_search_movies_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.search.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.should_ignore_quit_key);
assert_eq!(app.data.radarr_data.movies.search, None);
}
#[test]
fn test_filter_movies_key() {
let mut app = App::default();
app.data.radarr_data.movies = StatefulTable::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.filter.key,
@@ -880,13 +1076,41 @@ mod tests {
assert!(app.data.radarr_data.movies.filter.is_some());
}
#[test]
fn test_filter_movies_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.filter.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.should_ignore_quit_key);
assert!(app.data.radarr_data.movies.filter.is_none());
}
#[test]
fn test_filter_movies_key_resets_previous_filter() {
let mut app = App::default();
app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.data.radarr_data = create_test_radarr_data();
app.data.radarr_data.movies = StatefulTable::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.data.radarr_data.movies.filter = Some("Test".into());
LibraryHandler::with(
@@ -913,6 +1137,11 @@ mod tests {
#[test]
fn test_movie_add_key() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.add.key,
@@ -930,6 +1159,30 @@ mod tests {
assert!(app.data.radarr_data.add_movie_search.is_some());
}
#[test]
fn test_movie_add_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.add.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.should_ignore_quit_key);
assert!(app.data.radarr_data.add_movie_search.is_none());
}
#[test]
fn test_movie_edit_key() {
test_edit_movie_key!(
@@ -939,9 +1192,37 @@ mod tests {
);
}
#[test]
fn test_movie_edit_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.edit.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(app.data.radarr_data.edit_movie_modal.is_none());
}
#[test]
fn test_update_all_movies_key() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
@@ -957,15 +1238,82 @@ mod tests {
);
}
#[test]
fn test_update_all_movies_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
}
#[test]
fn test_refresh_movies_key() {
assert_refresh_key!(LibraryHandler, ActiveRadarrBlock::Movies);
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(app.should_refresh);
}
#[test]
fn test_refresh_movies_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(!app.should_refresh);
}
#[test]
fn test_search_movies_box_backspace_key() {
let mut app = App::default();
app.data.radarr_data.movies.search = Some("Test".into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.backspace.key,
@@ -984,7 +1332,11 @@ mod tests {
#[test]
fn test_filter_movies_box_backspace_key() {
let mut app = App::default();
app.data.radarr_data.movies = StatefulTable::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.data.radarr_data.movies.filter = Some("Test".into());
LibraryHandler::with(
@@ -1004,6 +1356,11 @@ mod tests {
#[test]
fn test_search_movies_box_char_key() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.data.radarr_data.movies.search = Some(HorizontallyScrollableText::default());
LibraryHandler::with(
@@ -1023,7 +1380,11 @@ mod tests {
#[test]
fn test_filter_movies_box_char_key() {
let mut app = App::default();
app.data.radarr_data.movies = StatefulTable::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
app.data.radarr_data.movies.filter = Some(HorizontallyScrollableText::default());
LibraryHandler::with(
@@ -1043,6 +1404,11 @@ mod tests {
#[test]
fn test_sort_key() {
let mut app = App::default();
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.sort.key,
@@ -1062,6 +1428,29 @@ mod tests {
);
assert!(!app.data.radarr_data.movies.sort_asc);
}
#[test]
fn test_sort_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
LibraryHandler::with(
&DEFAULT_KEYBINDINGS.sort.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Movies.into());
assert!(app.data.radarr_data.movies.sort.is_none());
}
}
#[rstest]
@@ -1314,6 +1703,74 @@ mod tests {
assert_str_eq!(sort_option.name, "Tags");
}
#[test]
fn test_library_handler_accepts() {
let mut library_handler_blocks = Vec::new();
library_handler_blocks.extend(LIBRARY_BLOCKS);
library_handler_blocks.extend(ADD_MOVIE_BLOCKS);
library_handler_blocks.extend(DELETE_MOVIE_BLOCKS);
library_handler_blocks.extend(EDIT_MOVIE_BLOCKS);
library_handler_blocks.extend(MOVIE_DETAILS_BLOCKS);
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if library_handler_blocks.contains(&active_radarr_block) {
assert!(LibraryHandler::accepts(&active_radarr_block));
} else {
assert!(!LibraryHandler::accepts(&active_radarr_block));
}
});
}
#[test]
fn test_library_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = LibraryHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_library_handler_not_ready_when_movies_is_empty() {
let mut app = App::default();
app.is_loading = false;
let handler = LibraryHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_library_handler_ready_when_not_loading_and_movies_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app
.data
.radarr_data
.movies
.set_items(vec![Movie::default()]);
let handler = LibraryHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::Movies,
&None,
);
assert!(handler.is_ready());
}
fn movies_vec() -> Vec<Movie> {
vec![
Movie {
@@ -1378,22 +1835,4 @@ mod tests {
}),
}]
}
#[test]
fn test_library_handler_accepts() {
let mut library_handler_blocks = Vec::new();
library_handler_blocks.extend(LIBRARY_BLOCKS);
library_handler_blocks.extend(ADD_MOVIE_BLOCKS);
library_handler_blocks.extend(DELETE_MOVIE_BLOCKS);
library_handler_blocks.extend(EDIT_MOVIE_BLOCKS);
library_handler_blocks.extend(MOVIE_DETAILS_BLOCKS);
ActiveRadarrBlock::iter().for_each(|active_radarr_block| {
if library_handler_blocks.contains(&active_radarr_block) {
assert!(LibraryHandler::accepts(&active_radarr_block));
} else {
assert!(!LibraryHandler::accepts(&active_radarr_block));
}
});
}
}
@@ -80,6 +80,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && !self.app.data.radarr_data.movies.is_empty()
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::Movies => self.app.data.radarr_data.movies.scroll_up(),
@@ -46,6 +46,21 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
self.key
}
fn is_ready(&self) -> bool {
let movie_details_modal_is_ready =
if let Some(movie_details_modal) = &self.app.data.radarr_data.movie_details_modal {
!movie_details_modal.movie_details.is_empty()
|| !movie_details_modal.movie_history.is_empty()
|| !movie_details_modal.movie_cast.is_empty()
|| !movie_details_modal.movie_crew.is_empty()
|| !movie_details_modal.movie_releases.is_empty()
} else {
false
};
!self.app.is_loading && movie_details_modal_is_ready
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::MovieDetails => self
File diff suppressed because it is too large Load Diff
+4
View File
@@ -85,6 +85,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
self.key
}
fn is_ready(&self) -> bool {
true
}
fn handle_scroll_up(&mut self) {}
fn handle_scroll_down(&mut self) {}
@@ -216,4 +216,19 @@ mod tests {
assert!(RadarrHandler::accepts(&active_radarr_block));
})
}
#[test]
fn test_radarr_handler_is_ready() {
let mut app = App::default();
app.is_loading = true;
let handler = RadarrHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
);
assert!(handler.is_ready());
}
}
@@ -42,6 +42,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading && !self.app.data.radarr_data.root_folders.is_empty()
}
fn handle_scroll_up(&mut self) {
if self.active_radarr_block == &ActiveRadarrBlock::RootFolders {
self.app.data.radarr_data.root_folders.scroll_up()
@@ -8,6 +8,7 @@ mod tests {
use crate::event::Key;
use crate::handlers::radarr_handlers::root_folders::RootFoldersHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::RootFolder;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS};
use crate::models::HorizontallyScrollableText;
@@ -28,6 +29,33 @@ mod tests {
None,
path
);
#[rstest]
fn test_root_folders_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.root_folders
.set_items(simple_stateful_iterable_vec!(RootFolder, String, path));
RootFoldersHandler::with(&key, &mut app, &ActiveRadarrBlock::RootFolders, &None).handle();
assert_str_eq!(
app.data.radarr_data.root_folders.current_selection().path,
"Test 1"
);
RootFoldersHandler::with(&key, &mut app, &ActiveRadarrBlock::RootFolders, &None).handle();
assert_str_eq!(
app.data.radarr_data.root_folders.current_selection().path,
"Test 1"
);
}
}
mod test_handle_home_end {
@@ -48,9 +76,51 @@ mod tests {
path
);
#[test]
fn test_root_folders_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.root_folders
.set_items(extended_stateful_iterable_vec!(RootFolder, String, path));
RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.root_folders.current_selection().path,
"Test 1"
);
RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.root_folders.current_selection().path,
"Test 1"
);
}
#[test]
fn test_add_root_folder_prompt_home_end_keys() {
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.data.radarr_data.edit_root_folder = Some("Test".into());
RootFoldersHandler::with(
@@ -98,18 +168,55 @@ mod tests {
mod test_handle_delete {
use pretty_assertions::assert_eq;
use crate::assert_delete_prompt;
use super::*;
const DELETE_KEY: Key = DEFAULT_KEYBINDINGS.delete.key;
#[test]
fn test_delete_root_folder_prompt() {
assert_delete_prompt!(
RootFoldersHandler,
ActiveRadarrBlock::RootFolders,
ActiveRadarrBlock::DeleteRootFolderPrompt
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
RootFoldersHandler::with(
&DELETE_KEY,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::DeleteRootFolderPrompt.into()
);
}
#[test]
fn test_delete_root_folder_prompt_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
RootFoldersHandler::with(
&DELETE_KEY,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::RootFolders.into()
);
}
}
@@ -120,9 +227,10 @@ mod tests {
use super::*;
#[test]
fn test_root_folders_tab_left() {
#[rstest]
fn test_root_folders_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(4);
RootFoldersHandler::with(
@@ -143,9 +251,10 @@ mod tests {
);
}
#[test]
fn test_root_folders_tab_right() {
#[rstest]
fn test_root_folders_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(4);
RootFoldersHandler::with(
@@ -249,6 +358,11 @@ mod tests {
#[test]
fn test_add_root_folder_prompt_confirm_submit() {
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.data.radarr_data.edit_root_folder = Some("Test".into());
app.data.radarr_data.prompt_confirm = true;
app.should_ignore_quit_key = true;
@@ -304,6 +418,11 @@ mod tests {
#[test]
fn test_delete_root_folder_prompt_confirm_submit() {
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into());
@@ -330,6 +449,11 @@ mod tests {
#[test]
fn test_delete_root_folder_prompt_decline_submit() {
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into());
@@ -351,9 +475,9 @@ mod tests {
}
mod test_handle_esc {
use pretty_assertions::assert_eq;
use super::*;
use pretty_assertions::assert_eq;
use rstest::rstest;
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
@@ -405,9 +529,10 @@ mod tests {
assert!(!app.should_ignore_quit_key);
}
#[test]
fn test_default_esc() {
#[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
@@ -425,13 +550,16 @@ mod tests {
mod test_handle_key_char {
use pretty_assertions::{assert_eq, assert_str_eq};
use crate::assert_refresh_key;
use super::*;
#[test]
fn test_root_folder_add() {
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.add.key,
@@ -449,14 +577,92 @@ mod tests {
assert!(app.data.radarr_data.edit_root_folder.is_some());
}
#[test]
fn test_root_folder_add_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.add.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::RootFolders.into()
);
assert!(!app.should_ignore_quit_key);
assert!(app.data.radarr_data.edit_root_folder.is_none());
}
#[test]
fn test_refresh_root_folders_key() {
assert_refresh_key!(RootFoldersHandler, ActiveRadarrBlock::RootFolders);
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::RootFolders.into()
);
assert!(app.should_refresh);
}
#[test]
fn test_refresh_root_folders_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::RootFolders.into()
);
assert!(!app.should_refresh);
}
#[test]
fn test_add_root_folder_prompt_backspace_key() {
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.data.radarr_data.edit_root_folder = Some("/nfs/test".into());
RootFoldersHandler::with(
@@ -476,6 +682,11 @@ mod tests {
#[test]
fn test_add_root_folder_prompt_char_key() {
let mut app = App::default();
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
app.data.radarr_data.edit_root_folder = Some(HorizontallyScrollableText::default());
RootFoldersHandler::with(
@@ -503,4 +714,54 @@ mod tests {
}
})
}
#[test]
fn test_root_folders_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_root_folders_handler_not_ready_when_root_folders_is_empty() {
let mut app = App::default();
app.is_loading = false;
let handler = RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_root_folders_handler_ready_when_not_loading_and_root_folders_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app
.data
.radarr_data
.root_folders
.set_items(vec![RootFolder::default()]);
let handler = RootFoldersHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::RootFolders,
&None,
);
assert!(handler.is_ready());
}
}
@@ -53,6 +53,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemHandler<'a, 'b
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading
&& !self.app.data.radarr_data.logs.is_empty()
&& !self.app.data.radarr_data.queued_events.is_empty()
&& !self.app.data.radarr_data.tasks.is_empty()
}
fn handle_scroll_up(&mut self) {}
fn handle_scroll_down(&mut self) {}
@@ -41,6 +41,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
self.key
}
fn is_ready(&self) -> bool {
!self.app.is_loading
&& (!self.app.data.radarr_data.log_details.is_empty()
|| !self.app.data.radarr_data.updates.is_empty())
}
fn handle_scroll_up(&mut self) {
match self.active_radarr_block {
ActiveRadarrBlock::SystemLogs => self.app.data.radarr_data.log_details.scroll_up(),
@@ -12,6 +12,7 @@ mod tests {
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS,
};
use crate::models::{HorizontallyScrollableText, ScrollableText};
mod test_handle_scroll_up_and_down {
use rstest::rstest;
@@ -31,25 +32,170 @@ mod tests {
text
);
test_iterable_scroll!(
test_tasks_scroll,
SystemDetailsHandler,
tasks,
simple_stateful_iterable_vec!(Task, String, name),
ActiveRadarrBlock::SystemTasks,
None,
name
);
#[rstest]
fn test_log_details_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.log_details
.set_items(simple_stateful_iterable_vec!(
HorizontallyScrollableText,
String,
text
));
test_iterable_scroll!(
test_queued_events_scroll,
SystemDetailsHandler,
queued_events,
simple_stateful_iterable_vec!(QueueEvent, String, name),
ActiveRadarrBlock::SystemQueuedEvents,
None,
name
);
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemLogs, &None).handle();
assert_str_eq!(
app.data.radarr_data.log_details.current_selection().text,
"Test 1"
);
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemLogs, &None).handle();
assert_str_eq!(
app.data.radarr_data.log_details.current_selection().text,
"Test 1"
);
}
#[rstest]
fn test_tasks_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app
.data
.radarr_data
.tasks
.set_items(simple_stateful_iterable_vec!(Task, String, name));
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemTasks, &None).handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 2"
);
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemTasks, &None).handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 1"
);
}
#[rstest]
fn test_tasks_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app
.data
.radarr_data
.tasks
.set_items(simple_stateful_iterable_vec!(Task, String, name));
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemTasks, &None).handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 1"
);
SystemDetailsHandler::with(&key, &mut app, &ActiveRadarrBlock::SystemTasks, &None).handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 1"
);
}
#[rstest]
fn test_queued_events_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app
.data
.radarr_data
.queued_events
.set_items(simple_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 2"
);
SystemDetailsHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 1"
);
}
#[rstest]
fn test_queued_events_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app
.data
.radarr_data
.queued_events
.set_items(simple_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 1"
);
SystemDetailsHandler::with(
&key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 1"
);
}
#[test]
fn test_system_updates_scroll() {
@@ -76,6 +222,33 @@ mod tests {
assert_eq!(app.data.radarr_data.updates.offset, 1);
}
#[test]
fn test_system_updates_scroll_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.up.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
)
.handle();
assert_eq!(app.data.radarr_data.updates.offset, 0);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.down.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
)
.handle();
assert_eq!(app.data.radarr_data.updates.offset, 0);
}
}
mod test_handle_home_end {
@@ -94,25 +267,200 @@ mod tests {
text
);
test_iterable_home_and_end!(
test_tasks_home_end,
SystemDetailsHandler,
tasks,
extended_stateful_iterable_vec!(Task, String, name),
ActiveRadarrBlock::SystemTasks,
None,
name
);
#[test]
fn test_log_details_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app
.data
.radarr_data
.log_details
.set_items(extended_stateful_iterable_vec!(
HorizontallyScrollableText,
String,
text
));
test_iterable_home_and_end!(
test_queued_events_home_end,
SystemDetailsHandler,
queued_events,
extended_stateful_iterable_vec!(QueueEvent, String, name),
ActiveRadarrBlock::SystemQueuedEvents,
None,
name
);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::SystemLogs,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.log_details.current_selection().text,
"Test 1"
);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::SystemLogs,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.log_details.current_selection().text,
"Test 1"
);
}
#[test]
fn test_tasks_home_end() {
let mut app = App::default();
app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
app
.data
.radarr_data
.tasks
.set_items(extended_stateful_iterable_vec!(Task, String, name));
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::SystemTasks,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 3"
);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::SystemTasks,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 1"
);
}
#[test]
fn test_tasks_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
app
.data
.radarr_data
.tasks
.set_items(extended_stateful_iterable_vec!(Task, String, name));
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::SystemTasks,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 1"
);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::SystemTasks,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name,
"Test 1"
);
}
#[test]
fn test_queued_events_home_end() {
let mut app = App::default();
app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
app
.data
.radarr_data
.queued_events
.set_items(extended_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 3"
);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 1"
);
}
#[test]
fn test_queued_events_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
app
.data
.radarr_data
.queued_events
.set_items(extended_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 1"
);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::SystemQueuedEvents,
&None,
)
.handle();
assert_str_eq!(
app.data.radarr_data.queued_events.current_selection().name,
"Test 1"
);
}
#[test]
fn test_system_updates_home_end() {
@@ -139,6 +487,33 @@ mod tests {
assert_eq!(app.data.radarr_data.updates.offset, 0);
}
#[test]
fn test_system_updates_home_end_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.end.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
)
.handle();
assert_eq!(app.data.radarr_data.updates.offset, 0);
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.home.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
)
.handle();
assert_eq!(app.data.radarr_data.updates.offset, 0);
}
}
mod test_handle_left_right_action {
@@ -286,6 +661,7 @@ mod tests {
#[test]
fn test_system_tasks_submit() {
let mut app = App::default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
SystemDetailsHandler::with(
&SUBMIT_KEY,
@@ -301,9 +677,31 @@ mod tests {
);
}
#[test]
fn test_system_tasks_submit_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
SystemDetailsHandler::with(
&SUBMIT_KEY,
&mut app,
&ActiveRadarrBlock::SystemTasks,
&None,
)
.handle();
assert_eq!(
app.get_current_route(),
&ActiveRadarrBlock::SystemTasks.into()
);
}
#[test]
fn test_system_tasks_start_task_prompt_confirm_submit() {
let mut app = App::default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into());
@@ -330,6 +728,7 @@ mod tests {
#[test]
fn test_system_tasks_start_task_prompt_decline_submit() {
let mut app = App::default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into());
@@ -351,17 +750,18 @@ mod tests {
}
mod test_handle_esc {
use pretty_assertions::assert_eq;
use crate::models::HorizontallyScrollableText;
use pretty_assertions::assert_eq;
use rstest::rstest;
use super::*;
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_esc_system_logs() {
#[rstest]
fn test_esc_system_logs(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app
.data
.radarr_data
@@ -382,9 +782,10 @@ mod tests {
assert!(app.data.radarr_data.log_details.items.is_empty());
}
#[test]
fn test_esc_system_tasks() {
#[rstest]
fn test_esc_system_tasks(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
@@ -395,9 +796,10 @@ mod tests {
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
}
#[test]
fn test_esc_system_queued_events() {
#[rstest]
fn test_esc_system_queued_events(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemQueuedEvents.into());
app
@@ -417,9 +819,10 @@ mod tests {
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
}
#[test]
fn test_esc_system_updates() {
#[rstest]
fn test_esc_system_updates(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemUpdates.into());
@@ -468,6 +871,7 @@ mod tests {
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.push_navigation_stack(active_radarr_block.into());
SystemDetailsHandler::with(
@@ -481,6 +885,33 @@ mod tests {
assert_eq!(app.get_current_route(), &active_radarr_block.into());
assert!(app.should_refresh);
}
#[rstest]
fn test_refresh_key_no_op_when_not_ready(
#[values(
ActiveRadarrBlock::SystemLogs,
ActiveRadarrBlock::SystemTasks,
ActiveRadarrBlock::SystemQueuedEvents,
ActiveRadarrBlock::SystemUpdates
)]
active_radarr_block: ActiveRadarrBlock,
) {
let mut app = App::default();
app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.push_navigation_stack(active_radarr_block.into());
SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&active_radarr_block,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &active_radarr_block.into());
assert!(!app.should_refresh);
}
}
#[test]
@@ -493,4 +924,70 @@ mod tests {
}
})
}
#[test]
fn test_system_details_handler_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let handler = SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_system_details_handler_not_ready_when_both_log_details_and_updates_are_empty() {
let mut app = App::default();
app.is_loading = false;
let handler = SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
);
assert!(!handler.is_ready());
}
#[test]
fn test_system_details_handler_ready_when_not_loading_and_log_details_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app
.data
.radarr_data
.log_details
.set_items(vec![HorizontallyScrollableText::default()]);
let handler = SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
);
assert!(handler.is_ready());
}
#[test]
fn test_system_details_handler_ready_when_not_loading_and_updates_is_not_empty() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
let handler = SystemDetailsHandler::with(
&DEFAULT_KEYBINDINGS.esc.key,
&mut app,
&ActiveRadarrBlock::SystemUpdates,
&None,
);
assert!(handler.is_ready());
}
}
@@ -9,6 +9,7 @@ mod tests {
use crate::event::Key;
use crate::handlers::radarr_handlers::system::SystemHandler;
use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::{QueueEvent, Task};
use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS,
};
@@ -19,9 +20,10 @@ mod tests {
use super::*;
#[test]
fn test_system_tab_left() {
#[rstest]
fn test_system_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(6);
SystemHandler::with(
@@ -39,9 +41,10 @@ mod tests {
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::Indexers.into());
}
#[test]
fn test_system_tab_right() {
#[rstest]
fn test_system_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default();
app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(6);
SystemHandler::with(
@@ -67,9 +70,10 @@ mod tests {
const ESC_KEY: Key = DEFAULT_KEYBINDINGS.esc.key;
#[test]
fn test_default_esc() {
#[rstest]
fn test_default_esc(#[values(true, false)] is_loading: bool) {
let mut app = App::default();
app.is_loading = is_loading;
app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::System.into());
@@ -84,7 +88,6 @@ mod tests {
mod test_handle_key_char {
use pretty_assertions::{assert_eq, assert_str_eq};
use crate::assert_refresh_key;
use crate::models::HorizontallyScrollableText;
use super::*;
@@ -92,6 +95,16 @@ mod tests {
#[test]
fn test_update_system_key() {
let mut app = App::default();
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
@@ -107,9 +120,46 @@ mod tests {
);
}
#[test]
fn test_update_system_key_no_op_if_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
}
#[test]
fn test_queued_events_key() {
let mut app = App::default();
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.events.key,
@@ -125,9 +175,87 @@ mod tests {
);
}
#[test]
fn test_queued_events_key_no_op_if_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.events.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
}
#[test]
fn test_refresh_system_key() {
assert_refresh_key!(SystemHandler, ActiveRadarrBlock::System);
let mut app = App::default();
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
app.push_navigation_stack(ActiveRadarrBlock::System.into());
SystemHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
assert!(app.should_refresh);
}
#[test]
fn test_refresh_system_key_no_op_if_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
app.push_navigation_stack(ActiveRadarrBlock::System.into());
SystemHandler::with(
&DEFAULT_KEYBINDINGS.refresh.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
assert!(!app.should_refresh);
}
#[test]
@@ -137,6 +265,12 @@ mod tests {
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.logs.key,
@@ -160,9 +294,47 @@ mod tests {
);
}
#[test]
fn test_logs_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.logs.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
assert!(app.data.radarr_data.log_details.is_empty());
}
#[test]
fn test_tasks_key() {
let mut app = App::default();
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.tasks.key,
@@ -177,6 +349,33 @@ mod tests {
&ActiveRadarrBlock::SystemTasks.into()
);
}
#[test]
fn test_tasks_key_no_op_when_not_ready() {
let mut app = App::default();
app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"),
]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
SystemHandler::with(
&DEFAULT_KEYBINDINGS.tasks.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
)
.handle();
assert_eq!(app.get_current_route(), &ActiveRadarrBlock::System.into());
}
}
#[rstest]
@@ -210,4 +409,100 @@ mod tests {
}
})
}
#[test]
fn test_system_handler_is_not_ready_when_loading() {
let mut app = App::default();
app.is_loading = true;
let system_handler = SystemHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
);
assert!(!system_handler.is_ready());
}
#[test]
fn test_system_handler_is_not_ready_when_logs_is_empty() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
let system_handler = SystemHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
);
assert!(!system_handler.is_ready());
}
#[test]
fn test_system_handler_is_not_ready_when_tasks_is_empty() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.logs.set_items(vec!["test".into()]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
let system_handler = SystemHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
);
assert!(!system_handler.is_ready());
}
#[test]
fn test_system_handler_is_not_ready_when_queued_events_is_empty() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.logs.set_items(vec!["test".into()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
let system_handler = SystemHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
);
assert!(!system_handler.is_ready());
}
#[test]
fn test_system_handler_is_ready_when_all_required_tables_are_not_empty() {
let mut app = App::default();
app.is_loading = false;
app.data.radarr_data.logs.set_items(vec!["test".into()]);
app.data.radarr_data.tasks.set_items(vec![Task::default()]);
app
.data
.radarr_data
.queued_events
.set_items(vec![QueueEvent::default()]);
let system_handler = SystemHandler::with(
&DEFAULT_KEYBINDINGS.update.key,
&mut app,
&ActiveRadarrBlock::System,
&None,
);
assert!(system_handler.is_ready());
}
}
+4
View File
@@ -52,6 +52,10 @@ impl ScrollableText {
pub fn get_text(&self) -> String {
self.items.join("\n")
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
}
impl Scrollable for ScrollableText {
+12
View File
@@ -41,6 +41,18 @@ mod tests {
assert_str_eq!(scrollable_text.get_text(), test_text);
}
#[test]
fn test_scrollable_text_is_empty() {
let scrollable_text = ScrollableText::default();
assert!(scrollable_text.is_empty());
let test_text = "Test \nString";
let scrollable_text = ScrollableText::with_string(test_text.to_owned());
assert!(!scrollable_text.is_empty());
}
#[test]
fn test_scrollable_text_scroll() {
let mut scrollable_text = ScrollableText::with_string("Test \nString".to_owned());
+4
View File
@@ -92,4 +92,8 @@ where
pub fn current_selection(&self) -> &T {
&self.items[self.state.selected().unwrap_or(0)]
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
}
+11
View File
@@ -102,6 +102,17 @@ mod tests {
assert_eq!(stateful_list.state.selected(), Some(0));
}
#[test]
fn test_stateful_list_is_empty() {
let mut stateful_list = create_test_stateful_list();
assert!(!stateful_list.is_empty());
stateful_list = StatefulList::default();
assert!(stateful_list.is_empty());
}
fn create_test_stateful_list() -> StatefulList<&'static str> {
let mut stateful_list = StatefulList::default();
stateful_list.set_items(vec!["Test 1", "Test 2"]);
+4
View File
@@ -302,4 +302,8 @@ where
pub fn reset_search(&mut self) {
self.search = None;
}
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
}
+11
View File
@@ -638,6 +638,17 @@ mod tests {
assert_eq!(stateful_table.search, None);
}
#[test]
fn test_stateful_table_is_empty() {
let mut stateful_table = create_test_stateful_table();
assert!(!stateful_table.is_empty());
stateful_table = StatefulTable::default();
assert!(stateful_table.is_empty());
}
fn create_test_stateful_table() -> StatefulTable<&'static str> {
let mut stateful_table = StatefulTable::default();
stateful_table.set_items(vec!["Test 1", "Test 2"]);
+15 -11
View File
@@ -133,17 +133,21 @@ pub(super) fn draw_library(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
.get_by_left(&movie.quality_profile_id)
.unwrap()
.to_owned();
let tags = movie
.tags
.iter()
.map(|tag_id| {
tags_map
.get_by_left(&tag_id.as_i64().unwrap())
.unwrap()
.clone()
})
.collect::<Vec<String>>()
.join(", ");
let tags = if !movie.tags.is_empty() {
movie
.tags
.iter()
.map(|tag_id| {
tags_map
.get_by_left(&tag_id.as_i64().unwrap())
.unwrap()
.clone()
})
.collect::<Vec<String>>()
.join(", ")
} else {
String::new()
};
decorate_with_row_style(
downloads_vec,
+11 -3
View File
@@ -8,6 +8,7 @@ use ratatui::Frame;
use crate::app::App;
use crate::models::radarr_models::{Credit, MovieHistoryItem, Release};
use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS};
use crate::models::Route;
use crate::ui::radarr_ui::library::draw_library;
@@ -165,11 +166,17 @@ fn draw_file_info(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
fn draw_movie_details(f: &mut Frame<'_>, app: &App<'_>, area: Rect) {
let block = layout_block_top_border();
let is_monitored = app.data.radarr_data.movies.current_selection().monitored;
let status = app.data.radarr_data.movies.current_selection().status.clone();
match app.data.radarr_data.movie_details_modal.as_ref() {
Some(movie_details_modal) if !app.is_loading => {
let is_monitored = app.data.radarr_data.movies.current_selection().monitored;
let status = app
.data
.radarr_data
.movies
.current_selection()
.status
.clone();
let movie_details = &movie_details_modal.movie_details;
let download_status = movie_details
.items
@@ -368,6 +375,7 @@ fn draw_movie_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
_ => (Release::default(), true),
};
let current_route = *app.get_current_route();
let mut default_movie_details_modal = MovieDetailsModal::default();
let help_footer = app
.data
.radarr_data
@@ -379,7 +387,7 @@ fn draw_movie_releases(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) {
.radarr_data
.movie_details_modal
.as_mut()
.unwrap()
.unwrap_or(&mut default_movie_details_modal)
.movie_releases,
);
let releases_row_mapping = |release: &Release| {