feat: Refactor all keybinding tips into a dynamically changing menu that can be invoked via '?' [#32]
This commit is contained in:
@@ -1,4 +1,12 @@
|
||||
use crate::app::{context_clues::ContextClue, key_binding::DEFAULT_KEYBINDINGS};
|
||||
use crate::app::context_clues::{
|
||||
ContextClueProvider, BARE_POPUP_CONTEXT_CLUES, CONFIRMATION_PROMPT_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::app::{context_clues::ContextClue, key_binding::DEFAULT_KEYBINDINGS, App};
|
||||
use crate::models::servarr_data::sonarr::sonarr_data::{
|
||||
ActiveSonarrBlock, ADD_SERIES_BLOCKS, EDIT_INDEXER_BLOCKS, EDIT_SERIES_BLOCKS,
|
||||
EPISODE_DETAILS_BLOCKS, INDEXER_SETTINGS_BLOCKS, SEASON_DETAILS_BLOCKS, SERIES_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::models::Route;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "sonarr_context_clues_tests.rs"]
|
||||
@@ -79,12 +87,7 @@ pub static SERIES_HISTORY_CONTEXT_CLUES: [ContextClue; 9] = [
|
||||
(DEFAULT_KEYBINDINGS.esc, "cancel filter/close"),
|
||||
];
|
||||
|
||||
pub static SEASON_DETAILS_CONTEXTUAL_CONTEXT_CLUES: [ContextClue; 2] = [
|
||||
(DEFAULT_KEYBINDINGS.submit, "episode details"),
|
||||
(DEFAULT_KEYBINDINGS.delete, "delete episode"),
|
||||
];
|
||||
|
||||
pub static SEASON_DETAILS_CONTEXT_CLUES: [ContextClue; 5] = [
|
||||
pub static SEASON_DETAILS_CONTEXT_CLUES: [ContextClue; 7] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
@@ -99,9 +102,11 @@ pub static SEASON_DETAILS_CONTEXT_CLUES: [ContextClue; 5] = [
|
||||
DEFAULT_KEYBINDINGS.auto_search.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
(DEFAULT_KEYBINDINGS.submit, "episode details"),
|
||||
(DEFAULT_KEYBINDINGS.delete, "delete episode"),
|
||||
];
|
||||
|
||||
pub static SEASON_HISTORY_CONTEXT_CLUES: [ContextClue; 6] = [
|
||||
pub static SEASON_HISTORY_CONTEXT_CLUES: [ContextClue; 7] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
@@ -113,10 +118,11 @@ pub static SEASON_HISTORY_CONTEXT_CLUES: [ContextClue; 6] = [
|
||||
DEFAULT_KEYBINDINGS.auto_search,
|
||||
DEFAULT_KEYBINDINGS.auto_search.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.submit, "details"),
|
||||
(DEFAULT_KEYBINDINGS.esc, "cancel filter/close"),
|
||||
];
|
||||
|
||||
pub static MANUAL_SEASON_SEARCH_CONTEXT_CLUES: [ContextClue; 4] = [
|
||||
pub static MANUAL_SEASON_SEARCH_CONTEXT_CLUES: [ContextClue; 5] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
@@ -126,10 +132,11 @@ pub static MANUAL_SEASON_SEARCH_CONTEXT_CLUES: [ContextClue; 4] = [
|
||||
DEFAULT_KEYBINDINGS.auto_search.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.sort, DEFAULT_KEYBINDINGS.sort.desc),
|
||||
(DEFAULT_KEYBINDINGS.submit, "details"),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub static MANUAL_EPISODE_SEARCH_CONTEXT_CLUES: [ContextClue; 4] = [
|
||||
pub static MANUAL_EPISODE_SEARCH_CONTEXT_CLUES: [ContextClue; 5] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
@@ -139,12 +146,10 @@ pub static MANUAL_EPISODE_SEARCH_CONTEXT_CLUES: [ContextClue; 4] = [
|
||||
DEFAULT_KEYBINDINGS.auto_search.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.sort, DEFAULT_KEYBINDINGS.sort.desc),
|
||||
(DEFAULT_KEYBINDINGS.submit, "details"),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub static DETAILS_CONTEXTUAL_CONTEXT_CLUES: [ContextClue; 1] =
|
||||
[(DEFAULT_KEYBINDINGS.submit, "details")];
|
||||
|
||||
pub static EPISODE_DETAILS_CONTEXT_CLUES: [ContextClue; 3] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
@@ -157,7 +162,84 @@ pub static EPISODE_DETAILS_CONTEXT_CLUES: [ContextClue; 3] = [
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub static SELECTABLE_EPISODE_DETAILS_CONTEXT_CLUES: [ContextClue; 4] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
),
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.auto_search,
|
||||
DEFAULT_KEYBINDINGS.auto_search.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.submit, "details"),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub static SYSTEM_TASKS_CONTEXT_CLUES: [ContextClue; 2] = [
|
||||
(DEFAULT_KEYBINDINGS.submit, "start task"),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub(in crate::app) struct SonarrContextClueProvider;
|
||||
|
||||
impl ContextClueProvider for SonarrContextClueProvider {
|
||||
fn get_context_clues(app: &mut App<'_>) -> Option<&'static [ContextClue]> {
|
||||
let Route::Sonarr(active_sonarr_block, _) = app.get_current_route() else {
|
||||
panic!("SonarrContextClueProvider::get_context_clues called with non-Sonarr route");
|
||||
};
|
||||
match active_sonarr_block {
|
||||
_ if SERIES_DETAILS_BLOCKS.contains(&active_sonarr_block) => app
|
||||
.data
|
||||
.sonarr_data
|
||||
.series_info_tabs
|
||||
.get_active_route_contextual_help(),
|
||||
_ if SEASON_DETAILS_BLOCKS.contains(&active_sonarr_block) => app
|
||||
.data
|
||||
.sonarr_data
|
||||
.season_details_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.season_details_tabs
|
||||
.get_active_route_contextual_help(),
|
||||
_ if EPISODE_DETAILS_BLOCKS.contains(&active_sonarr_block) => app
|
||||
.data
|
||||
.sonarr_data
|
||||
.season_details_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.episode_details_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.episode_details_tabs
|
||||
.get_active_route_contextual_help(),
|
||||
ActiveSonarrBlock::TestAllIndexers
|
||||
| ActiveSonarrBlock::AddSeriesSearchInput
|
||||
| ActiveSonarrBlock::AddSeriesEmptySearchResults
|
||||
| ActiveSonarrBlock::SystemLogs
|
||||
| ActiveSonarrBlock::SystemUpdates => Some(&BARE_POPUP_CONTEXT_CLUES),
|
||||
_ if EDIT_INDEXER_BLOCKS.contains(&active_sonarr_block)
|
||||
|| INDEXER_SETTINGS_BLOCKS.contains(&active_sonarr_block)
|
||||
|| EDIT_SERIES_BLOCKS.contains(&active_sonarr_block) =>
|
||||
{
|
||||
Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES)
|
||||
}
|
||||
ActiveSonarrBlock::AddSeriesPrompt
|
||||
| ActiveSonarrBlock::AddSeriesSelectMonitor
|
||||
| ActiveSonarrBlock::AddSeriesSelectSeriesType
|
||||
| ActiveSonarrBlock::AddSeriesSelectQualityProfile
|
||||
| ActiveSonarrBlock::AddSeriesSelectLanguageProfile
|
||||
| ActiveSonarrBlock::AddSeriesSelectRootFolder
|
||||
| ActiveSonarrBlock::AddSeriesTagsInput
|
||||
| ActiveSonarrBlock::SystemTaskStartConfirmPrompt => Some(&CONFIRMATION_PROMPT_CONTEXT_CLUES),
|
||||
_ if ADD_SERIES_BLOCKS.contains(&active_sonarr_block) => {
|
||||
Some(&ADD_SERIES_SEARCH_RESULTS_CONTEXT_CLUES)
|
||||
}
|
||||
ActiveSonarrBlock::SystemTasks => Some(&SYSTEM_TASKS_CONTEXT_CLUES),
|
||||
_ => app
|
||||
.data
|
||||
.sonarr_data
|
||||
.main_tabs
|
||||
.get_active_route_contextual_help(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,29 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
|
||||
use crate::app::context_clues::{
|
||||
ContextClue, ContextClueProvider, BARE_POPUP_CONTEXT_CLUES, BLOCKLIST_CONTEXT_CLUES,
|
||||
CONFIRMATION_PROMPT_CONTEXT_CLUES, DOWNLOADS_CONTEXT_CLUES, INDEXERS_CONTEXT_CLUES,
|
||||
ROOT_FOLDERS_CONTEXT_CLUES, SYSTEM_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::app::sonarr::sonarr_context_clues::{
|
||||
SonarrContextClueProvider, SELECTABLE_EPISODE_DETAILS_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::app::{
|
||||
key_binding::DEFAULT_KEYBINDINGS,
|
||||
sonarr::sonarr_context_clues::{
|
||||
ADD_SERIES_SEARCH_RESULTS_CONTEXT_CLUES, DETAILS_CONTEXTUAL_CONTEXT_CLUES,
|
||||
EPISODE_DETAILS_CONTEXT_CLUES, HISTORY_CONTEXT_CLUES, MANUAL_EPISODE_SEARCH_CONTEXT_CLUES,
|
||||
MANUAL_SEASON_SEARCH_CONTEXT_CLUES, SEASON_DETAILS_CONTEXTUAL_CONTEXT_CLUES,
|
||||
SEASON_DETAILS_CONTEXT_CLUES, SEASON_HISTORY_CONTEXT_CLUES, SERIES_CONTEXT_CLUES,
|
||||
SERIES_DETAILS_CONTEXT_CLUES, SERIES_HISTORY_CONTEXT_CLUES, SYSTEM_TASKS_CONTEXT_CLUES,
|
||||
ADD_SERIES_SEARCH_RESULTS_CONTEXT_CLUES, EPISODE_DETAILS_CONTEXT_CLUES,
|
||||
HISTORY_CONTEXT_CLUES, MANUAL_EPISODE_SEARCH_CONTEXT_CLUES,
|
||||
MANUAL_SEASON_SEARCH_CONTEXT_CLUES, SEASON_DETAILS_CONTEXT_CLUES,
|
||||
SEASON_HISTORY_CONTEXT_CLUES, SERIES_CONTEXT_CLUES, SERIES_DETAILS_CONTEXT_CLUES,
|
||||
SERIES_HISTORY_CONTEXT_CLUES, SYSTEM_TASKS_CONTEXT_CLUES,
|
||||
},
|
||||
App,
|
||||
};
|
||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||
use crate::models::servarr_data::sonarr::modals::{EpisodeDetailsModal, SeasonDetailsModal};
|
||||
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData};
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
use rstest::rstest;
|
||||
|
||||
#[test]
|
||||
fn test_add_series_search_results_context_clues() {
|
||||
@@ -252,23 +264,18 @@ mod tests {
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.esc);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.esc.desc);
|
||||
assert_eq!(season_details_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_season_details_contextual_context_clues() {
|
||||
let mut season_details_contextual_context_clues_iter =
|
||||
SEASON_DETAILS_CONTEXTUAL_CONTEXT_CLUES.iter();
|
||||
let (key_binding, description) = season_details_contextual_context_clues_iter.next().unwrap();
|
||||
let (key_binding, description) = season_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "episode details");
|
||||
|
||||
let (key_binding, description) = season_details_contextual_context_clues_iter.next().unwrap();
|
||||
let (key_binding, description) = season_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.delete);
|
||||
assert_str_eq!(*description, "delete episode");
|
||||
assert_eq!(season_details_contextual_context_clues_iter.next(), None);
|
||||
|
||||
assert_eq!(season_details_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -301,6 +308,11 @@ mod tests {
|
||||
|
||||
let (key_binding, description) = season_history_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "details");
|
||||
|
||||
let (key_binding, description) = season_history_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.esc);
|
||||
assert_str_eq!(*description, "cancel filter/close");
|
||||
assert_eq!(season_history_context_clues_iter.next(), None);
|
||||
@@ -327,6 +339,11 @@ mod tests {
|
||||
|
||||
let (key_binding, description) = manual_season_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "details");
|
||||
|
||||
let (key_binding, description) = manual_season_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.esc);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.esc.desc);
|
||||
assert_eq!(manual_season_search_context_clues_iter.next(), None);
|
||||
@@ -353,21 +370,16 @@ mod tests {
|
||||
|
||||
let (key_binding, description) = manual_episode_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "details");
|
||||
|
||||
let (key_binding, description) = manual_episode_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.esc);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.esc.desc);
|
||||
assert_eq!(manual_episode_search_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn details_contextual_context_clues() {
|
||||
let mut manual_search_contextual_context_clues_iter = DETAILS_CONTEXTUAL_CONTEXT_CLUES.iter();
|
||||
let (key_binding, description) = manual_search_contextual_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "details");
|
||||
assert_eq!(manual_search_contextual_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_episode_details_context_clues() {
|
||||
let mut episode_details_context_clues_iter = EPISODE_DETAILS_CONTEXT_CLUES.iter();
|
||||
@@ -389,6 +401,32 @@ mod tests {
|
||||
assert_eq!(episode_details_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_selectable_episode_details_context_clues() {
|
||||
let mut episode_details_context_clues_iter = SELECTABLE_EPISODE_DETAILS_CONTEXT_CLUES.iter();
|
||||
|
||||
let (key_binding, description) = episode_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.refresh);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.refresh.desc);
|
||||
|
||||
let (key_binding, description) = episode_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.auto_search);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.auto_search.desc);
|
||||
|
||||
let (key_binding, description) = episode_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "details");
|
||||
|
||||
let (key_binding, description) = episode_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.esc);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.esc.desc);
|
||||
assert_eq!(episode_details_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_system_tasks_context_clues() {
|
||||
let mut system_tasks_context_clues_iter = SYSTEM_TASKS_CONTEXT_CLUES.iter();
|
||||
@@ -404,4 +442,258 @@ mod tests {
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.esc.desc);
|
||||
assert_eq!(system_tasks_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic(
|
||||
expected = "SonarrContextClueProvider::get_context_clues called with non-Sonarr route"
|
||||
)]
|
||||
fn test_sonarr_context_clue_provider_get_context_clues_non_sonarr_route() {
|
||||
let mut app = App::test_default();
|
||||
app.push_navigation_stack(ActiveRadarrBlock::default().into());
|
||||
|
||||
// This should panic because the route is not a Sonarr route
|
||||
SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0, ActiveSonarrBlock::SeriesDetails, &SERIES_DETAILS_CONTEXT_CLUES)]
|
||||
#[case(1, ActiveSonarrBlock::SeriesHistory, &SERIES_HISTORY_CONTEXT_CLUES)]
|
||||
fn test_sonarr_context_clue_provider_series_info_tabs(
|
||||
#[case] index: usize,
|
||||
#[case] active_sonarr_block: ActiveSonarrBlock,
|
||||
#[case] expected_context_clues: &[ContextClue],
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.data.sonarr_data = SonarrData::default();
|
||||
app.data.sonarr_data.series_info_tabs.set_index(index);
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(expected_context_clues, context_clues.unwrap());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0, ActiveSonarrBlock::SeasonDetails, &SEASON_DETAILS_CONTEXT_CLUES)]
|
||||
#[case(1, ActiveSonarrBlock::SeasonHistory, &SEASON_HISTORY_CONTEXT_CLUES)]
|
||||
#[case(2, ActiveSonarrBlock::ManualSeasonSearch, &MANUAL_SEASON_SEARCH_CONTEXT_CLUES)]
|
||||
fn test_sonarr_context_clue_provider_season_details_tabs(
|
||||
#[case] index: usize,
|
||||
#[case] active_sonarr_block: ActiveSonarrBlock,
|
||||
#[case] expected_context_clues: &[ContextClue],
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
let mut season_details_modal = SeasonDetailsModal::default();
|
||||
season_details_modal.season_details_tabs.set_index(index);
|
||||
let sonarr_data = SonarrData {
|
||||
season_details_modal: Some(season_details_modal),
|
||||
..SonarrData::default()
|
||||
};
|
||||
app.data.sonarr_data = sonarr_data;
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(expected_context_clues, context_clues.unwrap());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0, ActiveSonarrBlock::EpisodeDetails, &EPISODE_DETAILS_CONTEXT_CLUES)]
|
||||
#[case(1, ActiveSonarrBlock::EpisodeHistory, &SELECTABLE_EPISODE_DETAILS_CONTEXT_CLUES)]
|
||||
#[case(2, ActiveSonarrBlock::EpisodeFile, &EPISODE_DETAILS_CONTEXT_CLUES)]
|
||||
#[case(3, ActiveSonarrBlock::ManualEpisodeSearch, &MANUAL_EPISODE_SEARCH_CONTEXT_CLUES)]
|
||||
fn test_sonarr_context_clue_provider_episode_details_tabs(
|
||||
#[case] index: usize,
|
||||
#[case] active_sonarr_block: ActiveSonarrBlock,
|
||||
#[case] expected_context_clues: &[ContextClue],
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
let mut episode_details_modal = EpisodeDetailsModal::default();
|
||||
episode_details_modal.episode_details_tabs.set_index(index);
|
||||
let sonarr_data = SonarrData {
|
||||
season_details_modal: Some(SeasonDetailsModal {
|
||||
episode_details_modal: Some(episode_details_modal),
|
||||
..SeasonDetailsModal::default()
|
||||
}),
|
||||
..SonarrData::default()
|
||||
};
|
||||
app.data.sonarr_data = sonarr_data;
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(expected_context_clues, context_clues.unwrap());
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_sonarr_context_clue_provider_bare_popup_context_clues(
|
||||
#[values(
|
||||
ActiveSonarrBlock::TestAllIndexers,
|
||||
ActiveSonarrBlock::AddSeriesSearchInput,
|
||||
ActiveSonarrBlock::AddSeriesEmptySearchResults,
|
||||
ActiveSonarrBlock::SystemLogs,
|
||||
ActiveSonarrBlock::SystemUpdates
|
||||
)]
|
||||
active_sonarr_block: ActiveSonarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(context_clues.unwrap(), &BARE_POPUP_CONTEXT_CLUES);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_sonarr_context_clue_provider_confirmation_prompt_context_clues(
|
||||
#[values(
|
||||
ActiveSonarrBlock::AddSeriesPrompt,
|
||||
ActiveSonarrBlock::AddSeriesSelectMonitor,
|
||||
ActiveSonarrBlock::AddSeriesSelectSeriesType,
|
||||
ActiveSonarrBlock::AddSeriesSelectQualityProfile,
|
||||
ActiveSonarrBlock::AddSeriesSelectLanguageProfile,
|
||||
ActiveSonarrBlock::AddSeriesSelectRootFolder,
|
||||
ActiveSonarrBlock::AddSeriesTagsInput,
|
||||
ActiveSonarrBlock::SystemTaskStartConfirmPrompt
|
||||
)]
|
||||
active_sonarr_block: ActiveSonarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(context_clues.unwrap(), &CONFIRMATION_PROMPT_CONTEXT_CLUES);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_sonarr_context_clue_provider_confirmation_prompt_popup_clues_edit_indexer_blocks(
|
||||
#[values(
|
||||
ActiveSonarrBlock::EditIndexerPrompt,
|
||||
ActiveSonarrBlock::EditIndexerConfirmPrompt,
|
||||
ActiveSonarrBlock::EditIndexerApiKeyInput,
|
||||
ActiveSonarrBlock::EditIndexerNameInput,
|
||||
ActiveSonarrBlock::EditIndexerSeedRatioInput,
|
||||
ActiveSonarrBlock::EditIndexerToggleEnableRss,
|
||||
ActiveSonarrBlock::EditIndexerToggleEnableAutomaticSearch,
|
||||
ActiveSonarrBlock::EditIndexerToggleEnableInteractiveSearch,
|
||||
ActiveSonarrBlock::EditIndexerPriorityInput,
|
||||
ActiveSonarrBlock::EditIndexerUrlInput,
|
||||
ActiveSonarrBlock::EditIndexerTagsInput
|
||||
)]
|
||||
active_sonarr_block: ActiveSonarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(context_clues.unwrap(), &CONFIRMATION_PROMPT_CONTEXT_CLUES);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_sonarr_context_clue_provider_confirmation_prompt_popup_clues_indexer_settings_blocks(
|
||||
#[values(
|
||||
ActiveSonarrBlock::AllIndexerSettingsPrompt,
|
||||
ActiveSonarrBlock::IndexerSettingsConfirmPrompt,
|
||||
ActiveSonarrBlock::IndexerSettingsMaximumSizeInput,
|
||||
ActiveSonarrBlock::IndexerSettingsMinimumAgeInput,
|
||||
ActiveSonarrBlock::IndexerSettingsRetentionInput,
|
||||
ActiveSonarrBlock::IndexerSettingsRssSyncIntervalInput
|
||||
)]
|
||||
active_sonarr_block: ActiveSonarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(context_clues.unwrap(), &CONFIRMATION_PROMPT_CONTEXT_CLUES);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_sonarr_context_clue_provider_confirmation_prompt_popup_clues_edit_series_blocks(
|
||||
#[values(
|
||||
ActiveSonarrBlock::EditSeriesPrompt,
|
||||
ActiveSonarrBlock::EditSeriesConfirmPrompt,
|
||||
ActiveSonarrBlock::EditSeriesPathInput,
|
||||
ActiveSonarrBlock::EditSeriesSelectSeriesType,
|
||||
ActiveSonarrBlock::EditSeriesSelectQualityProfile,
|
||||
ActiveSonarrBlock::EditSeriesSelectLanguageProfile,
|
||||
ActiveSonarrBlock::EditSeriesTagsInput,
|
||||
ActiveSonarrBlock::EditSeriesToggleMonitored,
|
||||
ActiveSonarrBlock::EditSeriesToggleSeasonFolder
|
||||
)]
|
||||
active_sonarr_block: ActiveSonarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(context_clues.unwrap(), &CONFIRMATION_PROMPT_CONTEXT_CLUES);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_sonarr_context_clue_provider_add_series_search_results_clues(
|
||||
#[values(
|
||||
ActiveSonarrBlock::AddSeriesAlreadyInLibrary,
|
||||
ActiveSonarrBlock::AddSeriesSearchResults
|
||||
)]
|
||||
active_sonarr_block: ActiveSonarrBlock,
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(
|
||||
context_clues.unwrap(),
|
||||
&ADD_SERIES_SEARCH_RESULTS_CONTEXT_CLUES
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sonarr_context_clue_provider_system_tasks_clues() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
app.push_navigation_stack(ActiveSonarrBlock::SystemTasks.into());
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(context_clues.unwrap(), &SYSTEM_TASKS_CONTEXT_CLUES);
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
#[case(0, ActiveSonarrBlock::Series, &SERIES_CONTEXT_CLUES)]
|
||||
#[case(1, ActiveSonarrBlock::Downloads, &DOWNLOADS_CONTEXT_CLUES)]
|
||||
#[case(2, ActiveSonarrBlock::Blocklist, &BLOCKLIST_CONTEXT_CLUES)]
|
||||
#[case(3, ActiveSonarrBlock::History, &HISTORY_CONTEXT_CLUES)]
|
||||
#[case(4, ActiveSonarrBlock::RootFolders, &ROOT_FOLDERS_CONTEXT_CLUES)]
|
||||
#[case(5, ActiveSonarrBlock::Indexers, &INDEXERS_CONTEXT_CLUES)]
|
||||
#[case(6, ActiveSonarrBlock::System, &SYSTEM_CONTEXT_CLUES)]
|
||||
fn test_sonarr_context_clue_provider_sonarr_tabs(
|
||||
#[case] index: usize,
|
||||
#[case] active_sonarr_block: ActiveSonarrBlock,
|
||||
#[case] expected_context_clues: &[ContextClue],
|
||||
) {
|
||||
let mut app = App::test_default();
|
||||
app.data.sonarr_data = SonarrData::default();
|
||||
app.data.sonarr_data.main_tabs.set_index(index);
|
||||
app.push_navigation_stack(active_sonarr_block.into());
|
||||
|
||||
let context_clues = SonarrContextClueProvider::get_context_clues(&mut app);
|
||||
|
||||
assert!(context_clues.is_some());
|
||||
assert_eq!(expected_context_clues, context_clues.unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user