feat(models): Added the necessary contextual help and tabs for the Sonarr UI
This commit is contained in:
@@ -31,3 +31,58 @@ pub static HISTORY_CONTEXT_CLUES: [ContextClue; 6] = [
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.esc, "cancel filter"),
|
||||
];
|
||||
|
||||
pub static SERIES_DETAILS_CONTEXT_CLUES: [ContextClue; 5] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.update, DEFAULT_KEYBINDINGS.update.desc),
|
||||
(DEFAULT_KEYBINDINGS.submit, "details"),
|
||||
(DEFAULT_KEYBINDINGS.search, "auto search"),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub static SEASON_DETAILS_CONTEXT_CLUES: [ContextClue; 5] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.submit, "details"),
|
||||
(DEFAULT_KEYBINDINGS.search, "auto search"),
|
||||
(DEFAULT_KEYBINDINGS.delete, "delete episode"),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub static MANUAL_SEASON_SEARCH_CONTEXT_CLUES: [ContextClue; 5] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.search, "auto search"),
|
||||
(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] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.search, "auto search"),
|
||||
(DEFAULT_KEYBINDINGS.sort, DEFAULT_KEYBINDINGS.sort.desc),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
pub static MANUAL_EPISODE_SEARCH_CONTEXTUAL_CONTEXT_CLUES: [ContextClue; 1] =
|
||||
[(DEFAULT_KEYBINDINGS.submit, "details")];
|
||||
|
||||
pub static EPISODE_DETAILS_CONTEXT_CLUES: [ContextClue; 3] = [
|
||||
(
|
||||
DEFAULT_KEYBINDINGS.refresh,
|
||||
DEFAULT_KEYBINDINGS.refresh.desc,
|
||||
),
|
||||
(DEFAULT_KEYBINDINGS.search, "auto search"),
|
||||
(DEFAULT_KEYBINDINGS.esc, DEFAULT_KEYBINDINGS.esc.desc),
|
||||
];
|
||||
|
||||
@@ -4,7 +4,12 @@ mod tests {
|
||||
|
||||
use crate::app::{
|
||||
key_binding::DEFAULT_KEYBINDINGS,
|
||||
sonarr::sonarr_context_clues::{HISTORY_CONTEXT_CLUES, SERIES_CONTEXT_CLUES},
|
||||
sonarr::sonarr_context_clues::{
|
||||
EPISODE_DETAILS_CONTEXT_CLUES, HISTORY_CONTEXT_CLUES,
|
||||
MANUAL_EPISODE_SEARCH_CONTEXTUAL_CONTEXT_CLUES, MANUAL_EPISODE_SEARCH_CONTEXT_CLUES,
|
||||
MANUAL_SEASON_SEARCH_CONTEXT_CLUES, SEASON_DETAILS_CONTEXT_CLUES, SERIES_CONTEXT_CLUES,
|
||||
SERIES_DETAILS_CONTEXT_CLUES,
|
||||
},
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -98,4 +103,155 @@ mod tests {
|
||||
assert_str_eq!(*description, "cancel filter");
|
||||
assert_eq!(history_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_series_details_context_clues() {
|
||||
let mut series_details_context_clues_iter = SERIES_DETAILS_CONTEXT_CLUES.iter();
|
||||
|
||||
let (key_binding, description) = series_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) = series_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.update);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.update.desc);
|
||||
|
||||
let (key_binding, description) = series_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "details");
|
||||
|
||||
let (key_binding, description) = series_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.search);
|
||||
assert_str_eq!(*description, "auto search");
|
||||
|
||||
let (key_binding, description) = series_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.esc);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.esc.desc);
|
||||
assert_eq!(series_details_context_clues_iter.next(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_season_details_context_clues() {
|
||||
let mut season_details_context_clues_iter = SEASON_DETAILS_CONTEXT_CLUES.iter();
|
||||
|
||||
let (key_binding, description) = season_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) = season_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.submit);
|
||||
assert_str_eq!(*description, "details");
|
||||
|
||||
let (key_binding, description) = season_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.search);
|
||||
assert_str_eq!(*description, "auto search");
|
||||
|
||||
let (key_binding, description) = season_details_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.delete);
|
||||
assert_str_eq!(*description, "delete episode");
|
||||
|
||||
let (key_binding, description) = season_details_context_clues_iter.next().unwrap();
|
||||
|
||||
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_manual_season_search_context_clues() {
|
||||
let mut manual_season_search_context_clues_iter = MANUAL_SEASON_SEARCH_CONTEXT_CLUES.iter();
|
||||
|
||||
let (key_binding, description) = manual_season_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.refresh);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.refresh.desc);
|
||||
|
||||
let (key_binding, description) = manual_season_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.search);
|
||||
assert_str_eq!(*description, "auto search");
|
||||
|
||||
let (key_binding, description) = manual_season_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.sort);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.sort.desc);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_manual_episode_search_context_clues() {
|
||||
let mut manual_episode_search_context_clues_iter = MANUAL_EPISODE_SEARCH_CONTEXT_CLUES.iter();
|
||||
|
||||
let (key_binding, description) = manual_episode_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.refresh);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.refresh.desc);
|
||||
|
||||
let (key_binding, description) = manual_episode_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.search);
|
||||
assert_str_eq!(*description, "auto search");
|
||||
|
||||
let (key_binding, description) = manual_episode_search_context_clues_iter.next().unwrap();
|
||||
|
||||
assert_eq!(*key_binding, DEFAULT_KEYBINDINGS.sort);
|
||||
assert_str_eq!(*description, DEFAULT_KEYBINDINGS.sort.desc);
|
||||
|
||||
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 test_manual_episode_search_contextual_context_clues() {
|
||||
let mut manual_search_contextual_context_clues_iter =
|
||||
MANUAL_EPISODE_SEARCH_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();
|
||||
|
||||
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.search);
|
||||
assert_str_eq!(*description, "auto search");
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,25 @@
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::models::{
|
||||
servarr_data::modals::EditIndexerModal,
|
||||
servarr_models::{Indexer, RootFolder},
|
||||
sonarr_models::{Episode, Series, SeriesMonitor, SeriesType, SonarrHistoryItem, SonarrRelease},
|
||||
stateful_list::StatefulList,
|
||||
stateful_table::StatefulTable,
|
||||
HorizontallyScrollableText, ScrollableText,
|
||||
use crate::{
|
||||
app::{
|
||||
context_clues::build_context_clue_string,
|
||||
sonarr::sonarr_context_clues::{
|
||||
EPISODE_DETAILS_CONTEXT_CLUES, MANUAL_EPISODE_SEARCH_CONTEXTUAL_CONTEXT_CLUES,
|
||||
MANUAL_EPISODE_SEARCH_CONTEXT_CLUES, MANUAL_SEASON_SEARCH_CONTEXT_CLUES,
|
||||
SEASON_DETAILS_CONTEXT_CLUES,
|
||||
},
|
||||
},
|
||||
models::{
|
||||
servarr_data::modals::EditIndexerModal,
|
||||
servarr_models::{Indexer, RootFolder},
|
||||
sonarr_models::{Episode, Series, SeriesMonitor, SeriesType, SonarrHistoryItem, SonarrRelease},
|
||||
stateful_list::StatefulList,
|
||||
stateful_table::StatefulTable,
|
||||
HorizontallyScrollableText, ScrollableText, TabRoute, TabState,
|
||||
},
|
||||
};
|
||||
|
||||
use super::sonarr_data::SonarrData;
|
||||
use super::sonarr_data::{ActiveSonarrBlock, SonarrData};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "modals_tests.rs"]
|
||||
@@ -246,22 +256,86 @@ impl From<&SonarrData<'_>> for EditSeriesModal {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct EpisodeDetailsModal {
|
||||
// Temporarily allowing this, since the value is only current written and not read.
|
||||
// This will be read from once I begin the UI work for Sonarr
|
||||
#[allow(dead_code)]
|
||||
pub episode_details: ScrollableText,
|
||||
pub file_details: String,
|
||||
pub audio_details: String,
|
||||
pub video_details: String,
|
||||
pub episode_history: StatefulTable<SonarrHistoryItem>,
|
||||
pub episode_releases: StatefulTable<SonarrRelease>,
|
||||
pub episode_details_tabs: TabState,
|
||||
}
|
||||
|
||||
impl Default for EpisodeDetailsModal {
|
||||
fn default() -> EpisodeDetailsModal {
|
||||
EpisodeDetailsModal {
|
||||
episode_details: ScrollableText::default(),
|
||||
file_details: String::new(),
|
||||
audio_details: String::new(),
|
||||
video_details: String::new(),
|
||||
episode_history: StatefulTable::default(),
|
||||
episode_releases: StatefulTable::default(),
|
||||
episode_details_tabs: TabState::new(vec![
|
||||
TabRoute {
|
||||
title: "Details",
|
||||
route: ActiveSonarrBlock::EpisodeDetails.into(),
|
||||
help: build_context_clue_string(&EPISODE_DETAILS_CONTEXT_CLUES),
|
||||
contextual_help: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "History",
|
||||
route: ActiveSonarrBlock::EpisodeHistory.into(),
|
||||
help: build_context_clue_string(&EPISODE_DETAILS_CONTEXT_CLUES),
|
||||
contextual_help: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "File",
|
||||
route: ActiveSonarrBlock::EpisodeFile.into(),
|
||||
help: build_context_clue_string(&EPISODE_DETAILS_CONTEXT_CLUES),
|
||||
contextual_help: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "Manual Search",
|
||||
route: ActiveSonarrBlock::ManualEpisodeSearch.into(),
|
||||
help: build_context_clue_string(&MANUAL_EPISODE_SEARCH_CONTEXT_CLUES),
|
||||
contextual_help: Some(build_context_clue_string(
|
||||
&MANUAL_EPISODE_SEARCH_CONTEXTUAL_CONTEXT_CLUES,
|
||||
)),
|
||||
},
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct SeasonDetailsModal {
|
||||
pub episodes: StatefulTable<Episode>,
|
||||
pub episode_details_modal: Option<EpisodeDetailsModal>,
|
||||
pub season_releases: StatefulTable<SonarrRelease>,
|
||||
pub season_details_tabs: TabState,
|
||||
}
|
||||
|
||||
impl Default for SeasonDetailsModal {
|
||||
fn default() -> SeasonDetailsModal {
|
||||
SeasonDetailsModal {
|
||||
episodes: StatefulTable::default(),
|
||||
episode_details_modal: None,
|
||||
season_releases: StatefulTable::default(),
|
||||
season_details_tabs: TabState::new(vec![
|
||||
TabRoute {
|
||||
title: "Episodes",
|
||||
route: ActiveSonarrBlock::SeasonDetails.into(),
|
||||
help: String::new(),
|
||||
contextual_help: Some(build_context_clue_string(&SEASON_DETAILS_CONTEXT_CLUES)),
|
||||
},
|
||||
TabRoute {
|
||||
title: "Manual Search",
|
||||
route: ActiveSonarrBlock::ManualSeasonSearch.into(),
|
||||
help: String::new(),
|
||||
contextual_help: Some(build_context_clue_string(
|
||||
&MANUAL_SEASON_SEARCH_CONTEXT_CLUES,
|
||||
)),
|
||||
},
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,16 @@ mod tests {
|
||||
use rstest::rstest;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::models::servarr_data::sonarr::modals::EditSeriesModal;
|
||||
use crate::app::context_clues::build_context_clue_string;
|
||||
use crate::app::sonarr::sonarr_context_clues::{
|
||||
EPISODE_DETAILS_CONTEXT_CLUES, MANUAL_EPISODE_SEARCH_CONTEXTUAL_CONTEXT_CLUES,
|
||||
MANUAL_EPISODE_SEARCH_CONTEXT_CLUES, MANUAL_SEASON_SEARCH_CONTEXT_CLUES,
|
||||
SEASON_DETAILS_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::models::servarr_data::sonarr::modals::{
|
||||
EditSeriesModal, EpisodeDetailsModal, SeasonDetailsModal,
|
||||
};
|
||||
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
||||
use crate::models::servarr_models::{Indexer, IndexerField};
|
||||
use crate::models::{
|
||||
servarr_data::sonarr::{modals::AddSeriesModal, sonarr_data::SonarrData},
|
||||
@@ -221,4 +230,130 @@ mod tests {
|
||||
assert_eq!(edit_series_modal.monitored, Some(true));
|
||||
assert_eq!(edit_series_modal.use_season_folders, Some(true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_episode_details_modal_default() {
|
||||
let episode_details_modal = EpisodeDetailsModal::default();
|
||||
|
||||
assert!(episode_details_modal.episode_details.is_empty());
|
||||
assert!(episode_details_modal.file_details.is_empty());
|
||||
assert!(episode_details_modal.audio_details.is_empty());
|
||||
assert!(episode_details_modal.video_details.is_empty());
|
||||
assert!(episode_details_modal.episode_history.is_empty());
|
||||
assert!(episode_details_modal.episode_releases.is_empty());
|
||||
|
||||
assert_eq!(episode_details_modal.episode_details_tabs.tabs.len(), 4);
|
||||
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[0].title,
|
||||
"Details"
|
||||
);
|
||||
assert_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[0].route,
|
||||
ActiveSonarrBlock::EpisodeDetails.into()
|
||||
);
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[0].help,
|
||||
build_context_clue_string(&EPISODE_DETAILS_CONTEXT_CLUES)
|
||||
);
|
||||
assert!(episode_details_modal.episode_details_tabs.tabs[0]
|
||||
.contextual_help
|
||||
.is_none());
|
||||
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[1].title,
|
||||
"History"
|
||||
);
|
||||
assert_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[1].route,
|
||||
ActiveSonarrBlock::EpisodeHistory.into()
|
||||
);
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[1].help,
|
||||
build_context_clue_string(&EPISODE_DETAILS_CONTEXT_CLUES)
|
||||
);
|
||||
assert!(episode_details_modal.episode_details_tabs.tabs[1]
|
||||
.contextual_help
|
||||
.is_none());
|
||||
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[2].title,
|
||||
"File"
|
||||
);
|
||||
assert_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[2].route,
|
||||
ActiveSonarrBlock::EpisodeFile.into()
|
||||
);
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[2].help,
|
||||
build_context_clue_string(&EPISODE_DETAILS_CONTEXT_CLUES)
|
||||
);
|
||||
assert!(episode_details_modal.episode_details_tabs.tabs[2]
|
||||
.contextual_help
|
||||
.is_none());
|
||||
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[3].title,
|
||||
"Manual Search"
|
||||
);
|
||||
assert_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[3].route,
|
||||
ActiveSonarrBlock::ManualEpisodeSearch.into()
|
||||
);
|
||||
assert_str_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[3].help,
|
||||
build_context_clue_string(&MANUAL_EPISODE_SEARCH_CONTEXT_CLUES)
|
||||
);
|
||||
assert_eq!(
|
||||
episode_details_modal.episode_details_tabs.tabs[3].contextual_help,
|
||||
Some(build_context_clue_string(
|
||||
&MANUAL_EPISODE_SEARCH_CONTEXTUAL_CONTEXT_CLUES
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_season_details_modal_default() {
|
||||
let season_details_modal = SeasonDetailsModal::default();
|
||||
|
||||
assert!(season_details_modal.episodes.is_empty());
|
||||
assert!(season_details_modal.episode_details_modal.is_none());
|
||||
assert!(season_details_modal.season_releases.is_empty());
|
||||
|
||||
assert_eq!(season_details_modal.season_details_tabs.tabs.len(), 2);
|
||||
|
||||
assert_str_eq!(
|
||||
season_details_modal.season_details_tabs.tabs[0].title,
|
||||
"Episodes"
|
||||
);
|
||||
assert_eq!(
|
||||
season_details_modal.season_details_tabs.tabs[0].route,
|
||||
ActiveSonarrBlock::SeasonDetails.into()
|
||||
);
|
||||
assert!(season_details_modal.season_details_tabs.tabs[0]
|
||||
.help
|
||||
.is_empty());
|
||||
assert_eq!(
|
||||
season_details_modal.season_details_tabs.tabs[0].contextual_help,
|
||||
Some(build_context_clue_string(&SEASON_DETAILS_CONTEXT_CLUES))
|
||||
);
|
||||
|
||||
assert_str_eq!(
|
||||
season_details_modal.season_details_tabs.tabs[1].title,
|
||||
"Manual Search"
|
||||
);
|
||||
assert_eq!(
|
||||
season_details_modal.season_details_tabs.tabs[1].route,
|
||||
ActiveSonarrBlock::ManualSeasonSearch.into()
|
||||
);
|
||||
assert!(season_details_modal.season_details_tabs.tabs[1]
|
||||
.help
|
||||
.is_empty());
|
||||
assert_eq!(
|
||||
season_details_modal.season_details_tabs.tabs[1].contextual_help,
|
||||
Some(build_context_clue_string(
|
||||
&MANUAL_SEASON_SEARCH_CONTEXT_CLUES
|
||||
))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,9 @@ use crate::{
|
||||
build_context_clue_string, BLOCKLIST_CONTEXT_CLUES, DOWNLOADS_CONTEXT_CLUES,
|
||||
INDEXERS_CONTEXT_CLUES, ROOT_FOLDERS_CONTEXT_CLUES, SYSTEM_CONTEXT_CLUES,
|
||||
},
|
||||
sonarr::sonarr_context_clues::{HISTORY_CONTEXT_CLUES, SERIES_CONTEXT_CLUES},
|
||||
sonarr::sonarr_context_clues::{
|
||||
HISTORY_CONTEXT_CLUES, SERIES_CONTEXT_CLUES, SERIES_DETAILS_CONTEXT_CLUES,
|
||||
},
|
||||
},
|
||||
models::{
|
||||
servarr_data::modals::{EditIndexerModal, IndexerTestResultModalItem},
|
||||
@@ -30,6 +32,10 @@ use super::modals::{AddSeriesModal, EditSeriesModal, SeasonDetailsModal};
|
||||
#[path = "sonarr_data_tests.rs"]
|
||||
mod sonarr_data_tests;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "sonarr_test_utils.rs"]
|
||||
pub mod sonarr_test_utils;
|
||||
|
||||
pub struct SonarrData<'a> {
|
||||
pub add_list_exclusion: bool,
|
||||
pub add_searched_series: Option<StatefulTable<AddSeriesSearchResult>>,
|
||||
@@ -49,6 +55,7 @@ pub struct SonarrData<'a> {
|
||||
pub indexer_test_error: Option<String>,
|
||||
pub language_profiles_map: BiMap<i64, String>,
|
||||
pub logs: StatefulList<HorizontallyScrollableText>,
|
||||
pub log_details: StatefulList<HorizontallyScrollableText>,
|
||||
pub main_tabs: TabState,
|
||||
pub prompt_confirm: bool,
|
||||
pub prompt_confirm_action: Option<SonarrEvent>,
|
||||
@@ -60,6 +67,7 @@ pub struct SonarrData<'a> {
|
||||
pub selected_block: BlockSelectionState<'a, ActiveSonarrBlock>,
|
||||
pub series: StatefulTable<Series>,
|
||||
pub series_history: Option<StatefulTable<SonarrHistoryItem>>,
|
||||
pub series_info_tabs: TabState,
|
||||
pub start_time: DateTime<Utc>,
|
||||
pub tags_map: BiMap<i64, String>,
|
||||
pub tasks: StatefulTable<SonarrTask>,
|
||||
@@ -95,6 +103,7 @@ impl<'a> Default for SonarrData<'a> {
|
||||
indexer_test_all_results: None,
|
||||
language_profiles_map: BiMap::new(),
|
||||
logs: StatefulList::default(),
|
||||
log_details: StatefulList::default(),
|
||||
prompt_confirm: false,
|
||||
prompt_confirm_action: None,
|
||||
quality_profile_map: BiMap::new(),
|
||||
@@ -154,6 +163,20 @@ impl<'a> Default for SonarrData<'a> {
|
||||
contextual_help: Some(build_context_clue_string(&SYSTEM_CONTEXT_CLUES)),
|
||||
},
|
||||
]),
|
||||
series_info_tabs: TabState::new(vec![
|
||||
TabRoute {
|
||||
title: "Seasons",
|
||||
route: ActiveSonarrBlock::SeriesDetails.into(),
|
||||
help: String::new(),
|
||||
contextual_help: Some(build_context_clue_string(&SERIES_DETAILS_CONTEXT_CLUES)),
|
||||
},
|
||||
TabRoute {
|
||||
title: "History",
|
||||
route: ActiveSonarrBlock::SeriesHistory.into(),
|
||||
help: String::new(),
|
||||
contextual_help: Some(build_context_clue_string(&HISTORY_CONTEXT_CLUES)),
|
||||
},
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,9 @@ mod tests {
|
||||
build_context_clue_string, BLOCKLIST_CONTEXT_CLUES, DOWNLOADS_CONTEXT_CLUES,
|
||||
INDEXERS_CONTEXT_CLUES, ROOT_FOLDERS_CONTEXT_CLUES, SYSTEM_CONTEXT_CLUES,
|
||||
},
|
||||
sonarr::sonarr_context_clues::{HISTORY_CONTEXT_CLUES, SERIES_CONTEXT_CLUES},
|
||||
sonarr::sonarr_context_clues::{
|
||||
HISTORY_CONTEXT_CLUES, SERIES_CONTEXT_CLUES, SERIES_DETAILS_CONTEXT_CLUES,
|
||||
},
|
||||
},
|
||||
models::{
|
||||
servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData},
|
||||
@@ -76,6 +78,7 @@ mod tests {
|
||||
assert!(sonarr_data.indexer_test_all_results.is_none());
|
||||
assert!(sonarr_data.language_profiles_map.is_empty());
|
||||
assert!(sonarr_data.logs.is_empty());
|
||||
assert!(sonarr_data.log_details.is_empty());
|
||||
assert!(!sonarr_data.prompt_confirm);
|
||||
assert!(sonarr_data.prompt_confirm_action.is_none());
|
||||
assert!(sonarr_data.quality_profile_map.is_empty());
|
||||
@@ -170,6 +173,30 @@ mod tests {
|
||||
sonarr_data.main_tabs.tabs[6].contextual_help,
|
||||
Some(build_context_clue_string(&SYSTEM_CONTEXT_CLUES))
|
||||
);
|
||||
|
||||
assert_eq!(sonarr_data.series_info_tabs.tabs.len(), 2);
|
||||
|
||||
assert_str_eq!(sonarr_data.series_info_tabs.tabs[0].title, "Seasons");
|
||||
assert_eq!(
|
||||
sonarr_data.series_info_tabs.tabs[0].route,
|
||||
ActiveSonarrBlock::SeriesDetails.into()
|
||||
);
|
||||
assert!(sonarr_data.series_info_tabs.tabs[0].help.is_empty());
|
||||
assert_eq!(
|
||||
sonarr_data.series_info_tabs.tabs[0].contextual_help,
|
||||
Some(build_context_clue_string(&SERIES_DETAILS_CONTEXT_CLUES))
|
||||
);
|
||||
|
||||
assert_str_eq!(sonarr_data.series_info_tabs.tabs[1].title, "History");
|
||||
assert_eq!(
|
||||
sonarr_data.series_info_tabs.tabs[1].route,
|
||||
ActiveSonarrBlock::SeriesHistory.into()
|
||||
);
|
||||
assert!(sonarr_data.series_info_tabs.tabs[1].help.is_empty());
|
||||
assert_eq!(
|
||||
sonarr_data.series_info_tabs.tabs[1].contextual_help,
|
||||
Some(build_context_clue_string(&HISTORY_CONTEXT_CLUES))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
#[cfg(test)]
|
||||
pub mod utils {
|
||||
use crate::models::{
|
||||
servarr_data::sonarr::{
|
||||
modals::{EpisodeDetailsModal, SeasonDetailsModal},
|
||||
sonarr_data::SonarrData,
|
||||
},
|
||||
sonarr_models::{AddSeriesSearchResult, Episode, Season, SonarrHistoryItem, SonarrRelease},
|
||||
stateful_table::StatefulTable,
|
||||
HorizontallyScrollableText, ScrollableText,
|
||||
};
|
||||
|
||||
pub fn create_test_sonarr_data<'a>() -> SonarrData<'a> {
|
||||
let mut episode_details_modal = EpisodeDetailsModal {
|
||||
episode_details: ScrollableText::with_string("test episode details".to_owned()),
|
||||
..EpisodeDetailsModal::default()
|
||||
};
|
||||
episode_details_modal
|
||||
.episode_history
|
||||
.set_items(vec![SonarrHistoryItem::default()]);
|
||||
episode_details_modal
|
||||
.episode_releases
|
||||
.set_items(vec![SonarrRelease::default()]);
|
||||
let mut season_details_modal = SeasonDetailsModal::default();
|
||||
season_details_modal
|
||||
.episodes
|
||||
.set_items(vec![Episode::default()]);
|
||||
season_details_modal
|
||||
.season_releases
|
||||
.set_items(vec![SonarrRelease::default()]);
|
||||
season_details_modal.episode_details_modal = Some(episode_details_modal);
|
||||
|
||||
let mut seasons = StatefulTable::default();
|
||||
seasons.set_items(vec![Season::default()]);
|
||||
|
||||
let mut sonarr_data = SonarrData {
|
||||
delete_series_files: true,
|
||||
add_list_exclusion: true,
|
||||
add_series_search: Some("test search".into()),
|
||||
edit_root_folder: Some("test path".into()),
|
||||
seasons,
|
||||
season_details_modal: Some(season_details_modal),
|
||||
add_searched_series: Some(StatefulTable::default()),
|
||||
..SonarrData::default()
|
||||
};
|
||||
sonarr_data.series_info_tabs.index = 1;
|
||||
sonarr_data
|
||||
.add_searched_series
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.set_items(vec![AddSeriesSearchResult::default()]);
|
||||
sonarr_data
|
||||
.log_details
|
||||
.set_items(vec![HorizontallyScrollableText::default()]);
|
||||
|
||||
sonarr_data
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user