feat: scaffold Readarr support across the state, app, handler, UI, and CLI layers
Promote Route::Readarr from a unit stub to a tuple variant and wire Readarr through every layer, mirroring the Lidarr tree. Readarr appears as a fourth servarr tab and its library view renders the Authors table. Adds ReadarrData and its modals, the tick and context clue modules, the top-level ReadarrHandler, ReadarrUi with the Authors library view, and an empty ReadarrCommand behind ReadarrCliHandler. The default port is 8787. Promoting the route variant compiles cleanly without any of the arms that give it behaviour, so all six of those sites are wired explicitly here: App::on_tick, handlers::handle_events, handle_prompt_toggle, ServarrContextClueProvider, ui(), and verify_config_present_for_cli. Each was checked by removing the arm and confirming its covering assertion then fails. ReadarrEvent and ReadarrCommand are both declared empty. They gain variants alongside the network calls and CLI commands that use them, which keeps each later change to a single function. Adding the tab changes the rendered tab bar, so 13 existing snapshots regenerate. The only delta in each is that single tab bar line. This scaffold adds 24 dead_code warnings, all inside the Readarr tree and none outside it. They clear as the handlers, UI, network events, and CLI commands that consume these items land: block arrays awaiting their accepts implementations and BlockSelectionState seeding, modal and state fields awaiting their handlers, the CLI handler fields awaiting an inhabited command enum, and the top-level handler fields awaiting sub-handlers. The count must strictly decrease from here, so a later increase is a defect rather than transient noise. The 12 pre-existing collapsible_match warnings are unrelated and untouched.
This commit is contained in:
64 files changed
+6418
-22
No files matched your search
@@ -3,6 +3,7 @@ use crate::models::Route;
|
||||
pub mod lidarr;
|
||||
pub mod modals;
|
||||
pub mod radarr;
|
||||
pub mod readarr;
|
||||
pub mod sonarr;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
pub mod modals;
|
||||
pub mod readarr_data;
|
||||
@@ -0,0 +1,271 @@
|
||||
use super::readarr_data::{ActiveReadarrBlock, ReadarrData};
|
||||
use crate::app::readarr::readarr_context_clues::{
|
||||
BOOK_DETAILS_CONTEXT_CLUES, BOOK_HISTORY_CONTEXT_CLUES, MANUAL_BOOK_SEARCH_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::models::readarr_models::{BookFile, Edition, ReadarrHistoryItem, ReadarrRelease};
|
||||
use crate::models::servarr_data::modals::EditIndexerModal;
|
||||
use crate::models::servarr_models::Indexer;
|
||||
use crate::models::stateful_table::StatefulTable;
|
||||
use crate::models::{
|
||||
HorizontallyScrollableText, ScrollableText, TabRoute, TabState,
|
||||
readarr_models::{MonitorType, NewItemMonitorType},
|
||||
servarr_models::RootFolder,
|
||||
stateful_list::StatefulList,
|
||||
};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "modals_tests.rs"]
|
||||
mod modals_tests;
|
||||
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct AddAuthorModal {
|
||||
pub root_folder_list: StatefulList<RootFolder>,
|
||||
pub monitor_list: StatefulList<MonitorType>,
|
||||
pub monitor_new_items_list: StatefulList<NewItemMonitorType>,
|
||||
pub quality_profile_list: StatefulList<String>,
|
||||
pub metadata_profile_list: StatefulList<String>,
|
||||
pub tags: HorizontallyScrollableText,
|
||||
}
|
||||
|
||||
impl From<&ReadarrData<'_>> for AddAuthorModal {
|
||||
fn from(readarr_data: &ReadarrData<'_>) -> AddAuthorModal {
|
||||
let mut add_author_modal = AddAuthorModal::default();
|
||||
add_author_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(MonitorType::iter()));
|
||||
add_author_modal
|
||||
.monitor_new_items_list
|
||||
.set_items(Vec::from_iter(NewItemMonitorType::iter()));
|
||||
add_author_modal
|
||||
.quality_profile_list
|
||||
.set_items(readarr_data.sorted_quality_profile_names());
|
||||
add_author_modal
|
||||
.metadata_profile_list
|
||||
.set_items(readarr_data.sorted_metadata_profile_names());
|
||||
add_author_modal
|
||||
.root_folder_list
|
||||
.set_items(readarr_data.root_folders.items.to_vec());
|
||||
|
||||
add_author_modal
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct EditAuthorModal {
|
||||
pub monitor_list: StatefulList<NewItemMonitorType>,
|
||||
pub quality_profile_list: StatefulList<String>,
|
||||
pub metadata_profile_list: StatefulList<String>,
|
||||
pub monitored: Option<bool>,
|
||||
pub path: HorizontallyScrollableText,
|
||||
pub tags: HorizontallyScrollableText,
|
||||
}
|
||||
|
||||
impl From<&ReadarrData<'_>> for EditAuthorModal {
|
||||
fn from(readarr_data: &ReadarrData<'_>) -> EditAuthorModal {
|
||||
let mut edit_author_modal = EditAuthorModal::default();
|
||||
let author = readarr_data.authors.current_selection();
|
||||
|
||||
edit_author_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(NewItemMonitorType::iter()));
|
||||
edit_author_modal.path = author.path.clone().into();
|
||||
edit_author_modal.tags = readarr_data.tag_ids_to_display(&author.tags).into();
|
||||
edit_author_modal.monitored = Some(author.monitored);
|
||||
|
||||
let monitor_index = edit_author_modal
|
||||
.monitor_list
|
||||
.items
|
||||
.iter()
|
||||
.position(|m| *m == author.monitor_new_items);
|
||||
edit_author_modal.monitor_list.state.select(monitor_index);
|
||||
|
||||
edit_author_modal
|
||||
.quality_profile_list
|
||||
.set_items(readarr_data.sorted_quality_profile_names());
|
||||
let quality_profile_name = readarr_data
|
||||
.quality_profile_map
|
||||
.get_by_left(&author.quality_profile_id)
|
||||
.unwrap();
|
||||
let quality_profile_index = edit_author_modal
|
||||
.quality_profile_list
|
||||
.items
|
||||
.iter()
|
||||
.position(|profile| profile == quality_profile_name);
|
||||
edit_author_modal
|
||||
.quality_profile_list
|
||||
.state
|
||||
.select(quality_profile_index);
|
||||
|
||||
edit_author_modal
|
||||
.metadata_profile_list
|
||||
.set_items(readarr_data.sorted_metadata_profile_names());
|
||||
let metadata_profile_name = readarr_data
|
||||
.metadata_profile_map
|
||||
.get_by_left(&author.metadata_profile_id)
|
||||
.unwrap();
|
||||
let metadata_profile_index = edit_author_modal
|
||||
.metadata_profile_list
|
||||
.items
|
||||
.iter()
|
||||
.position(|profile| profile == metadata_profile_name);
|
||||
edit_author_modal
|
||||
.metadata_profile_list
|
||||
.state
|
||||
.select(metadata_profile_index);
|
||||
|
||||
edit_author_modal
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&ReadarrData<'_>> for EditIndexerModal {
|
||||
fn from(readarr_data: &ReadarrData<'_>) -> EditIndexerModal {
|
||||
let mut edit_indexer_modal = EditIndexerModal::default();
|
||||
let Indexer {
|
||||
name,
|
||||
enable_rss,
|
||||
enable_automatic_search,
|
||||
enable_interactive_search,
|
||||
tags,
|
||||
fields,
|
||||
priority,
|
||||
..
|
||||
} = readarr_data.indexers.current_selection();
|
||||
let seed_ratio_field_option = fields
|
||||
.as_ref()
|
||||
.expect("indexer fields must exist")
|
||||
.iter()
|
||||
.find(|field| {
|
||||
field.name.as_ref().expect("indexer field name must exist") == "seedCriteria.seedRatio"
|
||||
});
|
||||
let seed_ratio_value_option = if let Some(seed_ratio_field) = seed_ratio_field_option {
|
||||
seed_ratio_field.value.clone()
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
edit_indexer_modal.name = name.clone().expect("indexer name must exist").into();
|
||||
edit_indexer_modal.enable_rss = Some(*enable_rss);
|
||||
edit_indexer_modal.enable_automatic_search = Some(*enable_automatic_search);
|
||||
edit_indexer_modal.enable_interactive_search = Some(*enable_interactive_search);
|
||||
edit_indexer_modal.priority = *priority;
|
||||
edit_indexer_modal.url = fields
|
||||
.as_ref()
|
||||
.expect("indexer fields must exist")
|
||||
.iter()
|
||||
.find(|field| field.name.as_ref().expect("indexer field name must exist") == "baseUrl")
|
||||
.expect("baseUrl field must exist")
|
||||
.value
|
||||
.clone()
|
||||
.expect("baseUrl field value must exist")
|
||||
.as_str()
|
||||
.expect("baseUrl field value must be a string")
|
||||
.into();
|
||||
edit_indexer_modal.api_key = fields
|
||||
.as_ref()
|
||||
.expect("indexer fields must exist")
|
||||
.iter()
|
||||
.find(|field| field.name.as_ref().expect("indexer field name must exist") == "apiKey")
|
||||
.expect("apiKey field must exist")
|
||||
.value
|
||||
.clone()
|
||||
.expect("apiKey field value must exist")
|
||||
.as_str()
|
||||
.expect("apiKey field value must be a string")
|
||||
.into();
|
||||
|
||||
if let Some(seed_ratio_value) = seed_ratio_value_option {
|
||||
edit_indexer_modal.seed_ratio = seed_ratio_value
|
||||
.as_f64()
|
||||
.expect("Seed ratio value must be a valid f64")
|
||||
.to_string()
|
||||
.into();
|
||||
}
|
||||
|
||||
edit_indexer_modal.tags = readarr_data.tag_ids_to_display(tags).into();
|
||||
|
||||
edit_indexer_modal
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct AddReadarrRootFolderModal {
|
||||
pub name: HorizontallyScrollableText,
|
||||
pub path: HorizontallyScrollableText,
|
||||
pub monitor_list: StatefulList<MonitorType>,
|
||||
pub monitor_new_items_list: StatefulList<NewItemMonitorType>,
|
||||
pub quality_profile_list: StatefulList<String>,
|
||||
pub metadata_profile_list: StatefulList<String>,
|
||||
pub tags: HorizontallyScrollableText,
|
||||
}
|
||||
|
||||
impl From<&ReadarrData<'_>> for AddReadarrRootFolderModal {
|
||||
fn from(readarr_data: &ReadarrData<'_>) -> AddReadarrRootFolderModal {
|
||||
let mut add_root_folder_modal = AddReadarrRootFolderModal::default();
|
||||
add_root_folder_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(MonitorType::iter()));
|
||||
add_root_folder_modal
|
||||
.monitor_new_items_list
|
||||
.set_items(Vec::from_iter(NewItemMonitorType::iter()));
|
||||
add_root_folder_modal
|
||||
.quality_profile_list
|
||||
.set_items(readarr_data.sorted_quality_profile_names());
|
||||
add_root_folder_modal
|
||||
.metadata_profile_list
|
||||
.set_items(readarr_data.sorted_metadata_profile_names());
|
||||
|
||||
add_root_folder_modal
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct BookDetailsModal {
|
||||
pub editions: StatefulTable<Edition>,
|
||||
pub book_files: StatefulTable<BookFile>,
|
||||
pub edition_details_modal: Option<EditionDetailsModal>,
|
||||
pub book_history: StatefulTable<ReadarrHistoryItem>,
|
||||
pub book_releases: StatefulTable<ReadarrRelease>,
|
||||
pub book_details_tabs: TabState,
|
||||
}
|
||||
|
||||
impl Default for BookDetailsModal {
|
||||
fn default() -> BookDetailsModal {
|
||||
BookDetailsModal {
|
||||
editions: StatefulTable::default(),
|
||||
edition_details_modal: None,
|
||||
book_files: StatefulTable::default(),
|
||||
book_releases: StatefulTable::default(),
|
||||
book_history: StatefulTable::default(),
|
||||
book_details_tabs: TabState::new(vec![
|
||||
TabRoute {
|
||||
title: "Editions".to_string(),
|
||||
route: ActiveReadarrBlock::BookDetails.into(),
|
||||
contextual_help: Some(&BOOK_DETAILS_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "History".to_string(),
|
||||
route: ActiveReadarrBlock::BookHistory.into(),
|
||||
contextual_help: Some(&BOOK_HISTORY_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "Manual Search".to_string(),
|
||||
route: ActiveReadarrBlock::ManualBookSearch.into(),
|
||||
contextual_help: Some(&MANUAL_BOOK_SEARCH_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
pub struct EditionDetailsModal {
|
||||
pub edition_details: ScrollableText,
|
||||
}
|
||||
@@ -0,0 +1,322 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::app::readarr::readarr_context_clues::{
|
||||
BOOK_DETAILS_CONTEXT_CLUES, BOOK_HISTORY_CONTEXT_CLUES, MANUAL_BOOK_SEARCH_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::models::readarr_models::{Author, MonitorType, NewItemMonitorType};
|
||||
use crate::models::servarr_data::modals::EditIndexerModal;
|
||||
use crate::models::servarr_data::readarr::modals::{
|
||||
AddAuthorModal, AddReadarrRootFolderModal, BookDetailsModal, EditAuthorModal,
|
||||
EditionDetailsModal,
|
||||
};
|
||||
use crate::models::servarr_data::readarr::readarr_data::{ActiveReadarrBlock, ReadarrData};
|
||||
use crate::models::servarr_models::{Indexer, IndexerField, RootFolder};
|
||||
use bimap::BiMap;
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
use rstest::rstest;
|
||||
use serde_json::{Number, Value};
|
||||
|
||||
#[test]
|
||||
fn test_add_author_modal_from_readarr_data() {
|
||||
let mut readarr_data = ReadarrData {
|
||||
quality_profile_map: BiMap::from_iter([
|
||||
(2i64, "Lossless".to_owned()),
|
||||
(1i64, "Standard".to_owned()),
|
||||
]),
|
||||
metadata_profile_map: BiMap::from_iter([
|
||||
(2i64, "None".to_owned()),
|
||||
(1i64, "Standard".to_owned()),
|
||||
]),
|
||||
..ReadarrData::default()
|
||||
};
|
||||
let root_folder_1 = RootFolder {
|
||||
id: 1,
|
||||
path: "/nfs".to_owned(),
|
||||
accessible: true,
|
||||
free_space: 219902325555200,
|
||||
unmapped_folders: None,
|
||||
};
|
||||
readarr_data.root_folders.set_items(vec![
|
||||
root_folder_1.clone(),
|
||||
RootFolder {
|
||||
id: 2,
|
||||
path: "/nfs2".to_owned(),
|
||||
accessible: true,
|
||||
free_space: 21990232555520,
|
||||
unmapped_folders: None,
|
||||
},
|
||||
]);
|
||||
|
||||
let add_author_modal = AddAuthorModal::from(&readarr_data);
|
||||
|
||||
assert_eq!(
|
||||
*add_author_modal.monitor_list.current_selection(),
|
||||
MonitorType::default()
|
||||
);
|
||||
assert_eq!(
|
||||
*add_author_modal.monitor_new_items_list.current_selection(),
|
||||
NewItemMonitorType::default()
|
||||
);
|
||||
assert_str_eq!(
|
||||
add_author_modal.quality_profile_list.current_selection(),
|
||||
"Standard"
|
||||
);
|
||||
assert_str_eq!(
|
||||
add_author_modal.metadata_profile_list.current_selection(),
|
||||
"Standard"
|
||||
);
|
||||
assert_eq!(
|
||||
add_author_modal.root_folder_list.current_selection(),
|
||||
&root_folder_1
|
||||
);
|
||||
assert_is_empty!(add_author_modal.tags.text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_author_modal_from_readarr_data() {
|
||||
let mut readarr_data = ReadarrData {
|
||||
quality_profile_map: BiMap::from_iter([
|
||||
(1i64, "HD - 1080p".to_owned()),
|
||||
(2i64, "Any".to_owned()),
|
||||
]),
|
||||
metadata_profile_map: BiMap::from_iter([
|
||||
(1i64, "Standard".to_owned()),
|
||||
(2i64, "None".to_owned()),
|
||||
]),
|
||||
tags_map: BiMap::from_iter([(1i64, "usenet".to_owned())]),
|
||||
..ReadarrData::default()
|
||||
};
|
||||
let author = Author {
|
||||
id: 1,
|
||||
monitored: true,
|
||||
monitor_new_items: NewItemMonitorType::New,
|
||||
quality_profile_id: 1,
|
||||
metadata_profile_id: 1,
|
||||
path: "/nfs/books/test_author".to_owned(),
|
||||
tags: vec![Number::from(1)],
|
||||
..Author::default()
|
||||
};
|
||||
readarr_data.authors.set_items(vec![author]);
|
||||
|
||||
let edit_author_modal = EditAuthorModal::from(&readarr_data);
|
||||
|
||||
assert_some_eq_x!(&edit_author_modal.monitored, &true);
|
||||
assert_eq!(
|
||||
*edit_author_modal.monitor_list.current_selection(),
|
||||
NewItemMonitorType::New
|
||||
);
|
||||
assert_str_eq!(
|
||||
edit_author_modal.quality_profile_list.current_selection(),
|
||||
"HD - 1080p"
|
||||
);
|
||||
assert_str_eq!(
|
||||
edit_author_modal.metadata_profile_list.current_selection(),
|
||||
"Standard"
|
||||
);
|
||||
assert_str_eq!(edit_author_modal.path.text, "/nfs/books/test_author");
|
||||
assert_str_eq!(edit_author_modal.tags.text, "usenet");
|
||||
}
|
||||
|
||||
#[rstest]
|
||||
fn test_edit_indexer_modal_from_readarr_data(#[values(true, false)] seed_ratio_present: bool) {
|
||||
let mut readarr_data = ReadarrData {
|
||||
tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]),
|
||||
..ReadarrData::default()
|
||||
};
|
||||
let mut fields = vec![
|
||||
IndexerField {
|
||||
name: Some("baseUrl".to_owned()),
|
||||
value: Some(Value::String("https://test.com".to_owned())),
|
||||
},
|
||||
IndexerField {
|
||||
name: Some("apiKey".to_owned()),
|
||||
value: Some(Value::String("1234".to_owned())),
|
||||
},
|
||||
];
|
||||
|
||||
if seed_ratio_present {
|
||||
fields.push(IndexerField {
|
||||
name: Some("seedCriteria.seedRatio".to_owned()),
|
||||
value: Some(Value::from(1.2f64)),
|
||||
});
|
||||
}
|
||||
|
||||
let indexer = Indexer {
|
||||
name: Some("Test".to_owned()),
|
||||
enable_rss: true,
|
||||
enable_automatic_search: true,
|
||||
enable_interactive_search: true,
|
||||
tags: vec![Number::from(1), Number::from(2)],
|
||||
fields: Some(fields),
|
||||
priority: 1,
|
||||
..Indexer::default()
|
||||
};
|
||||
readarr_data.indexers.set_items(vec![indexer]);
|
||||
|
||||
let edit_indexer_modal = EditIndexerModal::from(&readarr_data);
|
||||
|
||||
assert_str_eq!(edit_indexer_modal.name.text, "Test");
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_rss, &true);
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_automatic_search, &true);
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_interactive_search, &true);
|
||||
assert_eq!(edit_indexer_modal.priority, 1);
|
||||
assert_str_eq!(edit_indexer_modal.url.text, "https://test.com");
|
||||
assert_str_eq!(edit_indexer_modal.api_key.text, "1234");
|
||||
|
||||
if seed_ratio_present {
|
||||
assert_str_eq!(edit_indexer_modal.seed_ratio.text, "1.2");
|
||||
} else {
|
||||
assert_is_empty!(edit_indexer_modal.seed_ratio.text);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_indexer_modal_from_readarr_data_seed_ratio_value_is_none() {
|
||||
let mut readarr_data = ReadarrData {
|
||||
tags_map: BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]),
|
||||
..ReadarrData::default()
|
||||
};
|
||||
let fields = vec![
|
||||
IndexerField {
|
||||
name: Some("baseUrl".to_owned()),
|
||||
value: Some(Value::String("https://test.com".to_owned())),
|
||||
},
|
||||
IndexerField {
|
||||
name: Some("apiKey".to_owned()),
|
||||
value: Some(Value::String("1234".to_owned())),
|
||||
},
|
||||
IndexerField {
|
||||
name: Some("seedCriteria.seedRatio".to_owned()),
|
||||
value: None,
|
||||
},
|
||||
];
|
||||
|
||||
let indexer = Indexer {
|
||||
name: Some("Test".to_owned()),
|
||||
enable_rss: true,
|
||||
enable_automatic_search: true,
|
||||
enable_interactive_search: true,
|
||||
tags: vec![Number::from(1), Number::from(2)],
|
||||
fields: Some(fields),
|
||||
priority: 1,
|
||||
..Indexer::default()
|
||||
};
|
||||
readarr_data.indexers.set_items(vec![indexer]);
|
||||
|
||||
let edit_indexer_modal = EditIndexerModal::from(&readarr_data);
|
||||
|
||||
assert_str_eq!(edit_indexer_modal.name.text, "Test");
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_rss, &true);
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_automatic_search, &true);
|
||||
assert_some_eq_x!(&edit_indexer_modal.enable_interactive_search, &true);
|
||||
assert_eq!(edit_indexer_modal.priority, 1);
|
||||
assert_str_eq!(edit_indexer_modal.url.text, "https://test.com");
|
||||
assert_str_eq!(edit_indexer_modal.api_key.text, "1234");
|
||||
assert_is_empty!(edit_indexer_modal.seed_ratio.text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_readarr_root_folder_modal_from_readarr_data() {
|
||||
let readarr_data = ReadarrData {
|
||||
quality_profile_map: BiMap::from_iter([
|
||||
(2i64, "Lossless".to_owned()),
|
||||
(1i64, "Standard".to_owned()),
|
||||
]),
|
||||
metadata_profile_map: BiMap::from_iter([
|
||||
(2i64, "None".to_owned()),
|
||||
(1i64, "Standard".to_owned()),
|
||||
]),
|
||||
..ReadarrData::default()
|
||||
};
|
||||
|
||||
let add_root_folder_modal = AddReadarrRootFolderModal::from(&readarr_data);
|
||||
|
||||
assert_eq!(
|
||||
*add_root_folder_modal.monitor_list.current_selection(),
|
||||
MonitorType::default()
|
||||
);
|
||||
assert_eq!(
|
||||
*add_root_folder_modal
|
||||
.monitor_new_items_list
|
||||
.current_selection(),
|
||||
NewItemMonitorType::default()
|
||||
);
|
||||
assert_str_eq!(
|
||||
add_root_folder_modal
|
||||
.quality_profile_list
|
||||
.current_selection(),
|
||||
"Standard"
|
||||
);
|
||||
assert_str_eq!(
|
||||
add_root_folder_modal
|
||||
.metadata_profile_list
|
||||
.current_selection(),
|
||||
"Standard"
|
||||
);
|
||||
assert_is_empty!(add_root_folder_modal.name.text);
|
||||
assert_is_empty!(add_root_folder_modal.path.text);
|
||||
assert_is_empty!(add_root_folder_modal.tags.text);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_book_details_modal_default() {
|
||||
let book_details_modal = BookDetailsModal::default();
|
||||
|
||||
assert_is_empty!(book_details_modal.editions);
|
||||
assert_none!(book_details_modal.edition_details_modal);
|
||||
assert_is_empty!(book_details_modal.book_files);
|
||||
assert_is_empty!(book_details_modal.book_releases);
|
||||
assert_is_empty!(book_details_modal.book_history);
|
||||
|
||||
assert_eq!(book_details_modal.book_details_tabs.tabs.len(), 3);
|
||||
|
||||
assert_str_eq!(
|
||||
book_details_modal.book_details_tabs.tabs[0].title,
|
||||
"Editions"
|
||||
);
|
||||
assert_eq!(
|
||||
book_details_modal.book_details_tabs.tabs[0].route,
|
||||
ActiveReadarrBlock::BookDetails.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&book_details_modal.book_details_tabs.tabs[0].contextual_help,
|
||||
&BOOK_DETAILS_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(book_details_modal.book_details_tabs.tabs[0].config);
|
||||
|
||||
assert_str_eq!(
|
||||
book_details_modal.book_details_tabs.tabs[1].title,
|
||||
"History"
|
||||
);
|
||||
assert_eq!(
|
||||
book_details_modal.book_details_tabs.tabs[1].route,
|
||||
ActiveReadarrBlock::BookHistory.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&book_details_modal.book_details_tabs.tabs[1].contextual_help,
|
||||
&BOOK_HISTORY_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(book_details_modal.book_details_tabs.tabs[1].config);
|
||||
|
||||
assert_str_eq!(
|
||||
book_details_modal.book_details_tabs.tabs[2].title,
|
||||
"Manual Search"
|
||||
);
|
||||
assert_eq!(
|
||||
book_details_modal.book_details_tabs.tabs[2].route,
|
||||
ActiveReadarrBlock::ManualBookSearch.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&book_details_modal.book_details_tabs.tabs[2].contextual_help,
|
||||
&MANUAL_BOOK_SEARCH_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(book_details_modal.book_details_tabs.tabs[2].config);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_modal_default() {
|
||||
let edition_details_modal = EditionDetailsModal::default();
|
||||
|
||||
assert_is_empty!(edition_details_modal.edition_details);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,980 @@
|
||||
use serde_json::Number;
|
||||
|
||||
use super::modals::{AddAuthorModal, AddReadarrRootFolderModal, BookDetailsModal, EditAuthorModal};
|
||||
use crate::app::context_clues::{
|
||||
BLOCKLIST_CONTEXT_CLUES, DOWNLOADS_CONTEXT_CLUES, HISTORY_CONTEXT_CLUES, INDEXERS_CONTEXT_CLUES,
|
||||
ROOT_FOLDERS_CONTEXT_CLUES, SYSTEM_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::app::readarr::readarr_context_clues::{
|
||||
AUTHOR_DETAILS_CONTEXT_CLUES, AUTHOR_HISTORY_CONTEXT_CLUES, AUTHORS_CONTEXT_CLUES,
|
||||
MANUAL_AUTHOR_SEARCH_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::models::readarr_models::{BlocklistItem, ReadarrRelease, ReadarrTask};
|
||||
use crate::models::servarr_data::modals::EditIndexerModal;
|
||||
use crate::models::servarr_models::{IndexerSettings, QueueEvent};
|
||||
use crate::models::stateful_list::StatefulList;
|
||||
use crate::models::{
|
||||
BlockSelectionState, HorizontallyScrollableText, Route, ScrollableText, TabRoute, TabState,
|
||||
readarr_models::{AddAuthorSearchResult, Author, Book, DownloadRecord, ReadarrHistoryItem},
|
||||
servarr_data::modals::IndexerTestResultModalItem,
|
||||
servarr_models::{DiskSpace, Indexer, RootFolder},
|
||||
stateful_table::StatefulTable,
|
||||
};
|
||||
use crate::network::readarr_network::ReadarrEvent;
|
||||
use bimap::BiMap;
|
||||
use chrono::{DateTime, Utc};
|
||||
use itertools::Itertools;
|
||||
use strum::EnumIter;
|
||||
#[cfg(test)]
|
||||
use {
|
||||
super::modals::EditionDetailsModal,
|
||||
crate::models::readarr_models::{
|
||||
AuthorStatus, BookFile, DownloadStatus, Edition, MonitorType, NewItemMonitorType,
|
||||
ReadarrHistoryEventType, ReadarrTaskName,
|
||||
},
|
||||
crate::models::servarr_models::{IndexerField, Quality, QualityWrapper},
|
||||
crate::models::stateful_table::SortOption,
|
||||
crate::network::servarr_test_utils::{
|
||||
diskspace, indexer_settings, indexer_test_result, queued_event,
|
||||
},
|
||||
crate::network::sonarr_network::sonarr_network_test_utils::test_utils::updates,
|
||||
crate::sort_option,
|
||||
serde_json::json,
|
||||
strum::{Display, EnumString, IntoEnumIterator},
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "readarr_data_tests.rs"]
|
||||
mod readarr_data_tests;
|
||||
|
||||
pub struct ReadarrData<'a> {
|
||||
pub add_author_modal: Option<AddAuthorModal>,
|
||||
pub add_author_search: Option<HorizontallyScrollableText>,
|
||||
pub add_import_list_exclusion: bool,
|
||||
pub add_root_folder_modal: Option<AddReadarrRootFolderModal>,
|
||||
pub add_searched_authors: Option<StatefulTable<AddAuthorSearchResult>>,
|
||||
pub author_history: StatefulTable<ReadarrHistoryItem>,
|
||||
pub author_info_tabs: TabState,
|
||||
pub author_releases: StatefulTable<ReadarrRelease>,
|
||||
pub authors: StatefulTable<Author>,
|
||||
pub blocklist: StatefulTable<BlocklistItem>,
|
||||
pub book_details_modal: Option<BookDetailsModal>,
|
||||
pub books: StatefulTable<Book>,
|
||||
pub delete_files: bool,
|
||||
pub disk_space_vec: Vec<DiskSpace>,
|
||||
pub downloads: StatefulTable<DownloadRecord>,
|
||||
pub edit_author_modal: Option<EditAuthorModal>,
|
||||
pub edit_indexer_modal: Option<EditIndexerModal>,
|
||||
pub history: StatefulTable<ReadarrHistoryItem>,
|
||||
pub indexer_settings: Option<IndexerSettings>,
|
||||
pub indexer_test_all_results: Option<StatefulTable<IndexerTestResultModalItem>>,
|
||||
pub indexer_test_errors: Option<String>,
|
||||
pub indexers: StatefulTable<Indexer>,
|
||||
pub log_details: StatefulList<HorizontallyScrollableText>,
|
||||
pub logs: StatefulList<HorizontallyScrollableText>,
|
||||
pub main_tabs: TabState,
|
||||
pub metadata_profile_map: BiMap<i64, String>,
|
||||
pub prompt_confirm: bool,
|
||||
pub prompt_confirm_action: Option<ReadarrEvent>,
|
||||
pub quality_profile_map: BiMap<i64, String>,
|
||||
pub queued_events: StatefulTable<QueueEvent>,
|
||||
pub root_folders: StatefulTable<RootFolder>,
|
||||
pub selected_block: BlockSelectionState<'a, ActiveReadarrBlock>,
|
||||
pub start_time: DateTime<Utc>,
|
||||
pub tags_map: BiMap<i64, String>,
|
||||
pub tasks: StatefulTable<ReadarrTask>,
|
||||
pub updates: ScrollableText,
|
||||
pub version: String,
|
||||
}
|
||||
|
||||
impl ReadarrData<'_> {
|
||||
pub fn reset_delete_preferences(&mut self) {
|
||||
self.delete_files = false;
|
||||
self.add_import_list_exclusion = false;
|
||||
}
|
||||
|
||||
pub fn reset_author_info_tabs(&mut self) {
|
||||
self.books = StatefulTable::default();
|
||||
self.author_releases = StatefulTable::default();
|
||||
self.author_history = StatefulTable::default();
|
||||
self.author_info_tabs.index = 0;
|
||||
}
|
||||
|
||||
pub fn tag_ids_to_display(&self, tag_ids: &[Number]) -> String {
|
||||
tag_ids
|
||||
.iter()
|
||||
.filter_map(|id| {
|
||||
let id = id.as_i64()?;
|
||||
self.tags_map.get_by_left(&id).cloned()
|
||||
})
|
||||
.collect::<Vec<String>>()
|
||||
.join(", ")
|
||||
}
|
||||
|
||||
pub fn sorted_quality_profile_names(&self) -> Vec<String> {
|
||||
self
|
||||
.quality_profile_map
|
||||
.iter()
|
||||
.sorted_by_key(|(id, _)| *id)
|
||||
.map(|(_, name)| name)
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn sorted_metadata_profile_names(&self) -> Vec<String> {
|
||||
self
|
||||
.metadata_profile_map
|
||||
.iter()
|
||||
.sorted_by_key(|(id, _)| *id)
|
||||
.map(|(_, name)| name)
|
||||
.cloned()
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Default for ReadarrData<'a> {
|
||||
fn default() -> ReadarrData<'a> {
|
||||
ReadarrData {
|
||||
add_author_modal: None,
|
||||
add_author_search: None,
|
||||
add_import_list_exclusion: false,
|
||||
add_root_folder_modal: None,
|
||||
add_searched_authors: None,
|
||||
author_history: StatefulTable::default(),
|
||||
author_releases: StatefulTable::default(),
|
||||
authors: StatefulTable::default(),
|
||||
blocklist: StatefulTable::default(),
|
||||
book_details_modal: None,
|
||||
books: StatefulTable::default(),
|
||||
delete_files: false,
|
||||
disk_space_vec: Vec::new(),
|
||||
downloads: StatefulTable::default(),
|
||||
edit_author_modal: None,
|
||||
edit_indexer_modal: None,
|
||||
history: StatefulTable::default(),
|
||||
indexer_settings: None,
|
||||
indexer_test_all_results: None,
|
||||
indexer_test_errors: None,
|
||||
indexers: StatefulTable::default(),
|
||||
log_details: StatefulList::default(),
|
||||
logs: StatefulList::default(),
|
||||
metadata_profile_map: BiMap::new(),
|
||||
prompt_confirm: false,
|
||||
prompt_confirm_action: None,
|
||||
quality_profile_map: BiMap::new(),
|
||||
queued_events: StatefulTable::default(),
|
||||
root_folders: StatefulTable::default(),
|
||||
selected_block: BlockSelectionState::default(),
|
||||
start_time: DateTime::default(),
|
||||
tags_map: BiMap::new(),
|
||||
tasks: StatefulTable::default(),
|
||||
updates: ScrollableText::default(),
|
||||
version: String::new(),
|
||||
main_tabs: TabState::new(vec![
|
||||
TabRoute {
|
||||
title: "Library".to_string(),
|
||||
route: ActiveReadarrBlock::Authors.into(),
|
||||
contextual_help: Some(&AUTHORS_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "Downloads".to_string(),
|
||||
route: ActiveReadarrBlock::Downloads.into(),
|
||||
contextual_help: Some(&DOWNLOADS_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "Blocklist".to_string(),
|
||||
route: ActiveReadarrBlock::Blocklist.into(),
|
||||
contextual_help: Some(&BLOCKLIST_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "History".to_string(),
|
||||
route: ActiveReadarrBlock::History.into(),
|
||||
contextual_help: Some(&HISTORY_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "Root Folders".to_string(),
|
||||
route: ActiveReadarrBlock::RootFolders.into(),
|
||||
contextual_help: Some(&ROOT_FOLDERS_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "Indexers".to_string(),
|
||||
route: ActiveReadarrBlock::Indexers.into(),
|
||||
contextual_help: Some(&INDEXERS_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "System".to_string(),
|
||||
route: ActiveReadarrBlock::System.into(),
|
||||
contextual_help: Some(&SYSTEM_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
]),
|
||||
author_info_tabs: TabState::new(vec![
|
||||
TabRoute {
|
||||
title: "Books".to_string(),
|
||||
route: ActiveReadarrBlock::AuthorDetails.into(),
|
||||
contextual_help: Some(&AUTHOR_DETAILS_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "History".to_string(),
|
||||
route: ActiveReadarrBlock::AuthorHistory.into(),
|
||||
contextual_help: Some(&AUTHOR_HISTORY_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
TabRoute {
|
||||
title: "Author Search".to_string(),
|
||||
route: ActiveReadarrBlock::ManualAuthorSearch.into(),
|
||||
contextual_help: Some(&MANUAL_AUTHOR_SEARCH_CONTEXT_CLUES),
|
||||
config: None,
|
||||
},
|
||||
]),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
impl ReadarrData<'_> {
|
||||
pub fn test_default_fully_populated() -> Self {
|
||||
let quality_profile_map = BiMap::from_iter([(1i64, "Standard".to_owned())]);
|
||||
let metadata_profile_map = BiMap::from_iter([(1i64, "Standard".to_owned())]);
|
||||
let tags_map = BiMap::from_iter([(1i64, "alex".to_owned())]);
|
||||
let root_folder = RootFolder {
|
||||
id: 1,
|
||||
path: "/nfs".to_owned(),
|
||||
accessible: true,
|
||||
free_space: 219902325555200,
|
||||
unmapped_folders: None,
|
||||
};
|
||||
let quality = QualityWrapper {
|
||||
quality: Quality {
|
||||
name: "EPUB".to_owned(),
|
||||
},
|
||||
};
|
||||
let date = DateTime::from(DateTime::parse_from_rfc3339("2023-05-20T21:29:16Z").unwrap());
|
||||
let author = Author {
|
||||
id: 1,
|
||||
author_name: "Test Author".into(),
|
||||
foreign_author_id: "test-foreign-id".to_owned(),
|
||||
status: AuthorStatus::Continuing,
|
||||
overview: Some("some interesting description of the author".to_owned()),
|
||||
path: "/nfs/books/Test Author".to_owned(),
|
||||
quality_profile_id: 1,
|
||||
metadata_profile_id: 1,
|
||||
monitored: true,
|
||||
monitor_new_items: NewItemMonitorType::All,
|
||||
genres: vec!["science fiction".to_owned()],
|
||||
tags: vec![Number::from(1)],
|
||||
..Author::default()
|
||||
};
|
||||
let book = Book {
|
||||
id: 1,
|
||||
title: "Test Book".into(),
|
||||
author_id: 1,
|
||||
foreign_book_id: "test-foreign-book-id".to_owned(),
|
||||
monitored: true,
|
||||
any_edition_ok: true,
|
||||
page_count: Some(288),
|
||||
release_date: Some(date),
|
||||
..Book::default()
|
||||
};
|
||||
let readarr_history_item = ReadarrHistoryItem {
|
||||
id: 1,
|
||||
author_id: 1,
|
||||
book_id: 1,
|
||||
source_title: "Test Source Title".into(),
|
||||
quality: quality.clone(),
|
||||
date,
|
||||
event_type: ReadarrHistoryEventType::Grabbed,
|
||||
..ReadarrHistoryItem::default()
|
||||
};
|
||||
let torrent_release = ReadarrRelease {
|
||||
guid: "1234".to_owned(),
|
||||
protocol: "torrent".to_owned(),
|
||||
age: 1,
|
||||
title: "Test Torrent Release".into(),
|
||||
author_name: Some("Test Author".to_owned()),
|
||||
book_title: Some("Test Book".to_owned()),
|
||||
indexer: "kickass torrents".to_owned(),
|
||||
indexer_id: 1,
|
||||
size: 1234,
|
||||
rejected: true,
|
||||
rejections: Some(vec!["Unknown quality profile".to_owned()]),
|
||||
seeders: Some(Number::from(2)),
|
||||
leechers: Some(Number::from(1)),
|
||||
quality: quality.clone(),
|
||||
};
|
||||
let usenet_release = ReadarrRelease {
|
||||
guid: "5678".to_owned(),
|
||||
protocol: "usenet".to_owned(),
|
||||
title: "Test Usenet Release".into(),
|
||||
indexer: "DrunkenSlug".to_owned(),
|
||||
indexer_id: 2,
|
||||
seeders: None,
|
||||
leechers: None,
|
||||
..torrent_release.clone()
|
||||
};
|
||||
let blocklist_item = BlocklistItem {
|
||||
id: 1,
|
||||
author_id: 1,
|
||||
book_ids: Some(vec![Number::from(1)]),
|
||||
source_title: "Test Source Title".to_owned(),
|
||||
quality: quality.clone(),
|
||||
date,
|
||||
protocol: "usenet".to_owned(),
|
||||
indexer: "DrunkenSlug".to_owned(),
|
||||
message: "test message".to_owned(),
|
||||
author: author.clone(),
|
||||
};
|
||||
let download_record = DownloadRecord {
|
||||
title: "Test Download Title".to_owned(),
|
||||
status: DownloadStatus::Downloading,
|
||||
id: 1,
|
||||
book_id: Some(Number::from(1)),
|
||||
author_id: Some(Number::from(1)),
|
||||
size: 3543348019f64,
|
||||
sizeleft: 1771674009f64,
|
||||
output_path: Some("/nfs/books/Test Author".into()),
|
||||
indexer: "kickass torrents".to_owned(),
|
||||
download_client: Some("transmission".to_owned()),
|
||||
};
|
||||
let indexer = Indexer {
|
||||
id: 1,
|
||||
name: Some("Test Indexer".to_owned()),
|
||||
implementation: Some("Torznab".to_owned()),
|
||||
implementation_name: Some("Torznab".to_owned()),
|
||||
config_contract: Some("TorznabSettings".to_owned()),
|
||||
supports_rss: true,
|
||||
supports_search: true,
|
||||
enable_rss: true,
|
||||
enable_automatic_search: true,
|
||||
enable_interactive_search: true,
|
||||
protocol: "torrent".to_owned(),
|
||||
priority: 25,
|
||||
download_client_id: 0,
|
||||
tags: vec![Number::from(1)],
|
||||
fields: Some(vec![
|
||||
IndexerField {
|
||||
name: Some("baseUrl".to_owned()),
|
||||
value: Some(json!("https://test.com")),
|
||||
},
|
||||
IndexerField {
|
||||
name: Some("apiKey".to_owned()),
|
||||
value: Some(json!("")),
|
||||
},
|
||||
IndexerField {
|
||||
name: Some("seedCriteria.seedRatio".to_owned()),
|
||||
value: Some(json!("1.2")),
|
||||
},
|
||||
]),
|
||||
};
|
||||
let add_author_search_result = AddAuthorSearchResult {
|
||||
foreign_author_id: "test-foreign-id".to_owned(),
|
||||
author_name: "Test Author".into(),
|
||||
status: AuthorStatus::Continuing,
|
||||
overview: Some("some interesting description of the author".to_owned()),
|
||||
genres: vec!["science fiction".to_owned()],
|
||||
..AddAuthorSearchResult::default()
|
||||
};
|
||||
let task = ReadarrTask {
|
||||
name: "Backup".to_owned(),
|
||||
task_name: ReadarrTaskName::Backup,
|
||||
interval: 60,
|
||||
last_execution: date,
|
||||
last_duration: "00:00:00.5111547".to_owned(),
|
||||
next_execution: DateTime::from(DateTime::parse_from_rfc3339("2023-05-20T22:29:16Z").unwrap()),
|
||||
};
|
||||
let log_line = "2025-12-16 16:40:59 UTC|INFO|ImportListSyncService|No list items to process";
|
||||
|
||||
let mut add_author_modal = AddAuthorModal {
|
||||
tags: "usenet, testing".into(),
|
||||
..AddAuthorModal::default()
|
||||
};
|
||||
add_author_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(MonitorType::iter()));
|
||||
add_author_modal
|
||||
.monitor_new_items_list
|
||||
.set_items(Vec::from_iter(NewItemMonitorType::iter()));
|
||||
add_author_modal
|
||||
.metadata_profile_list
|
||||
.set_items(vec!["Standard".to_owned()]);
|
||||
add_author_modal
|
||||
.quality_profile_list
|
||||
.set_items(vec!["Standard".to_owned()]);
|
||||
add_author_modal
|
||||
.root_folder_list
|
||||
.set_items(vec![root_folder.clone()]);
|
||||
|
||||
let mut edit_author_modal = EditAuthorModal {
|
||||
monitored: Some(true),
|
||||
path: "/nfs/books".into(),
|
||||
tags: "alex".into(),
|
||||
..EditAuthorModal::default()
|
||||
};
|
||||
edit_author_modal
|
||||
.monitor_list
|
||||
.set_items(NewItemMonitorType::iter().collect());
|
||||
edit_author_modal
|
||||
.quality_profile_list
|
||||
.set_items(vec!["Standard".to_owned()]);
|
||||
edit_author_modal
|
||||
.metadata_profile_list
|
||||
.set_items(vec!["Standard".to_owned()]);
|
||||
|
||||
let mut add_root_folder_modal = AddReadarrRootFolderModal {
|
||||
name: "Test Root Folder".into(),
|
||||
path: "/nfs/books".into(),
|
||||
tags: "test".into(),
|
||||
..AddReadarrRootFolderModal::default()
|
||||
};
|
||||
add_root_folder_modal
|
||||
.monitor_list
|
||||
.set_items(Vec::from_iter(MonitorType::iter()));
|
||||
add_root_folder_modal
|
||||
.monitor_new_items_list
|
||||
.set_items(Vec::from_iter(NewItemMonitorType::iter()));
|
||||
add_root_folder_modal
|
||||
.quality_profile_list
|
||||
.set_items(vec!["Standard".to_owned()]);
|
||||
add_root_folder_modal
|
||||
.metadata_profile_list
|
||||
.set_items(vec!["Standard".to_owned()]);
|
||||
|
||||
let edition_details_modal = EditionDetailsModal {
|
||||
edition_details: ScrollableText::with_string("Some details".to_owned()),
|
||||
};
|
||||
|
||||
let mut book_details_modal = BookDetailsModal {
|
||||
edition_details_modal: Some(edition_details_modal),
|
||||
..BookDetailsModal::default()
|
||||
};
|
||||
book_details_modal.editions.set_items(vec![Edition {
|
||||
id: 1,
|
||||
book_id: 1,
|
||||
foreign_edition_id: "test-foreign-edition-id".to_owned(),
|
||||
monitored: true,
|
||||
is_ebook: true,
|
||||
title: "Test Edition".to_owned(),
|
||||
page_count: Some(288),
|
||||
release_date: Some(date),
|
||||
..Edition::default()
|
||||
}]);
|
||||
book_details_modal.editions.search = Some("edition search".into());
|
||||
book_details_modal.book_files.set_items(vec![BookFile {
|
||||
id: 1,
|
||||
author_id: 1,
|
||||
book_id: 1,
|
||||
path: "/nfs/books/Test Author/Test Book.epub".to_owned(),
|
||||
size: 3543348019,
|
||||
date_added: date,
|
||||
quality: quality.clone(),
|
||||
media_info: None,
|
||||
quality_cutoff_not_met: false,
|
||||
}]);
|
||||
book_details_modal
|
||||
.book_history
|
||||
.set_items(vec![readarr_history_item.clone()]);
|
||||
book_details_modal.book_history.search = Some("book history search".into());
|
||||
book_details_modal.book_history.filter = Some("book history filter".into());
|
||||
book_details_modal
|
||||
.book_history
|
||||
.sorting(vec![sort_option!(id)]);
|
||||
book_details_modal
|
||||
.book_releases
|
||||
.set_items(vec![torrent_release.clone(), usenet_release.clone()]);
|
||||
book_details_modal
|
||||
.book_releases
|
||||
.sorting(vec![sort_option!(indexer_id)]);
|
||||
|
||||
let edit_indexer_modal = EditIndexerModal {
|
||||
name: "DrunkenSlug".into(),
|
||||
enable_rss: Some(true),
|
||||
enable_automatic_search: Some(true),
|
||||
enable_interactive_search: Some(true),
|
||||
url: "http://127.0.0.1:9696/1/".into(),
|
||||
api_key: "someApiKey".into(),
|
||||
seed_ratio: "ratio".into(),
|
||||
tags: "25".into(),
|
||||
priority: 1,
|
||||
};
|
||||
|
||||
let mut indexer_test_all_results = StatefulTable::default();
|
||||
indexer_test_all_results.set_items(vec![indexer_test_result()]);
|
||||
|
||||
let mut readarr_data = ReadarrData {
|
||||
add_author_modal: Some(add_author_modal),
|
||||
add_root_folder_modal: Some(add_root_folder_modal),
|
||||
book_details_modal: Some(book_details_modal),
|
||||
delete_files: true,
|
||||
disk_space_vec: vec![diskspace()],
|
||||
edit_author_modal: Some(edit_author_modal),
|
||||
edit_indexer_modal: Some(edit_indexer_modal),
|
||||
indexer_settings: Some(indexer_settings()),
|
||||
indexer_test_all_results: Some(indexer_test_all_results),
|
||||
indexer_test_errors: Some("error".to_string()),
|
||||
metadata_profile_map,
|
||||
quality_profile_map,
|
||||
start_time: date,
|
||||
tags_map,
|
||||
updates: updates(),
|
||||
version: "1.2.3.4".to_owned(),
|
||||
..ReadarrData::default()
|
||||
};
|
||||
readarr_data
|
||||
.author_history
|
||||
.set_items(vec![readarr_history_item.clone()]);
|
||||
readarr_data.author_history.sorting(vec![sort_option!(id)]);
|
||||
readarr_data.author_history.search = Some("author history search".into());
|
||||
readarr_data.author_history.filter = Some("author history filter".into());
|
||||
readarr_data
|
||||
.author_releases
|
||||
.set_items(vec![torrent_release, usenet_release]);
|
||||
readarr_data
|
||||
.author_releases
|
||||
.sorting(vec![sort_option!(indexer_id)]);
|
||||
readarr_data.authors.set_items(vec![author]);
|
||||
readarr_data.authors.sorting(vec![SortOption {
|
||||
name: "Name",
|
||||
cmp_fn: Some(|a: &Author, b: &Author| a.author_name.text.cmp(&b.author_name.text)),
|
||||
}]);
|
||||
readarr_data.authors.search = Some("author search".into());
|
||||
readarr_data.authors.filter = Some("author filter".into());
|
||||
readarr_data.blocklist.set_items(vec![blocklist_item]);
|
||||
readarr_data.blocklist.sorting(vec![sort_option!(id)]);
|
||||
readarr_data.books.set_items(vec![book]);
|
||||
readarr_data.books.search = Some("book search".into());
|
||||
readarr_data.downloads.set_items(vec![download_record]);
|
||||
readarr_data.history.set_items(vec![readarr_history_item]);
|
||||
readarr_data.history.sorting(vec![SortOption {
|
||||
name: "Date",
|
||||
cmp_fn: Some(|a: &ReadarrHistoryItem, b: &ReadarrHistoryItem| a.date.cmp(&b.date)),
|
||||
}]);
|
||||
readarr_data.history.search = Some("test search".into());
|
||||
readarr_data.history.filter = Some("test filter".into());
|
||||
readarr_data.indexers.set_items(vec![indexer]);
|
||||
readarr_data.root_folders.set_items(vec![root_folder]);
|
||||
readarr_data.queued_events.set_items(vec![queued_event()]);
|
||||
readarr_data.add_author_search = Some("Test Author".into());
|
||||
let mut add_searched_authors = StatefulTable::default();
|
||||
add_searched_authors.set_items(vec![add_author_search_result]);
|
||||
readarr_data.add_searched_authors = Some(add_searched_authors);
|
||||
readarr_data.logs.set_items(vec![log_line.into()]);
|
||||
readarr_data.log_details.set_items(vec![log_line.into()]);
|
||||
readarr_data.tasks.set_items(vec![task]);
|
||||
|
||||
readarr_data
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default, EnumIter)]
|
||||
#[cfg_attr(test, derive(Display, EnumString))]
|
||||
pub enum ActiveReadarrBlock {
|
||||
#[default]
|
||||
Authors,
|
||||
AddAuthorAlreadyInLibrary,
|
||||
AddAuthorConfirmPrompt,
|
||||
AddAuthorEmptySearchResults,
|
||||
AddAuthorPrompt,
|
||||
AddAuthorSearchInput,
|
||||
AddAuthorSearchResults,
|
||||
AddAuthorSelectMetadataProfile,
|
||||
AddAuthorSelectMonitor,
|
||||
AddAuthorSelectMonitorNewItems,
|
||||
AddAuthorSelectQualityProfile,
|
||||
AddAuthorSelectRootFolder,
|
||||
AddAuthorTagsInput,
|
||||
AddRootFolderConfirmPrompt,
|
||||
AddRootFolderNameInput,
|
||||
AddRootFolderPathInput,
|
||||
AddRootFolderPrompt,
|
||||
AddRootFolderSelectMetadataProfile,
|
||||
AddRootFolderSelectMonitor,
|
||||
AddRootFolderSelectMonitorNewItems,
|
||||
AddRootFolderSelectQualityProfile,
|
||||
AddRootFolderTagsInput,
|
||||
AllIndexerSettingsPrompt,
|
||||
AuthorDetails,
|
||||
AuthorHistory,
|
||||
AuthorHistoryDetails,
|
||||
AuthorHistorySortPrompt,
|
||||
AuthorsSortPrompt,
|
||||
AutomaticallySearchAuthorPrompt,
|
||||
AutomaticallySearchBookPrompt,
|
||||
Blocklist,
|
||||
BlocklistClearAllItemsPrompt,
|
||||
BlocklistItemDetails,
|
||||
BlocklistSortPrompt,
|
||||
BookDetails,
|
||||
BookEditionDetails,
|
||||
BookFileInfo,
|
||||
BookHistory,
|
||||
BookHistoryDetails,
|
||||
BookHistorySortPrompt,
|
||||
DeleteAuthorConfirmPrompt,
|
||||
DeleteAuthorPrompt,
|
||||
DeleteAuthorToggleAddListExclusion,
|
||||
DeleteAuthorToggleDeleteFile,
|
||||
DeleteBlocklistItemPrompt,
|
||||
DeleteBookConfirmPrompt,
|
||||
DeleteBookFilePrompt,
|
||||
DeleteBookPrompt,
|
||||
DeleteBookToggleAddListExclusion,
|
||||
DeleteBookToggleDeleteFile,
|
||||
DeleteDownloadPrompt,
|
||||
DeleteIndexerPrompt,
|
||||
DeleteRootFolderPrompt,
|
||||
Downloads,
|
||||
EditAuthorConfirmPrompt,
|
||||
EditAuthorPathInput,
|
||||
EditAuthorPrompt,
|
||||
EditAuthorSelectMetadataProfile,
|
||||
EditAuthorSelectMonitorNewItems,
|
||||
EditAuthorSelectQualityProfile,
|
||||
EditAuthorTagsInput,
|
||||
EditAuthorToggleMonitored,
|
||||
EditIndexerApiKeyInput,
|
||||
EditIndexerConfirmPrompt,
|
||||
EditIndexerNameInput,
|
||||
EditIndexerPriorityInput,
|
||||
EditIndexerPrompt,
|
||||
EditIndexerSeedRatioInput,
|
||||
EditIndexerTagsInput,
|
||||
EditIndexerToggleEnableAutomaticSearch,
|
||||
EditIndexerToggleEnableInteractiveSearch,
|
||||
EditIndexerToggleEnableRss,
|
||||
EditIndexerUrlInput,
|
||||
FilterAuthorHistory,
|
||||
FilterAuthorHistoryError,
|
||||
FilterAuthors,
|
||||
FilterAuthorsError,
|
||||
FilterBookHistory,
|
||||
FilterBookHistoryError,
|
||||
FilterHistory,
|
||||
FilterHistoryError,
|
||||
History,
|
||||
HistoryItemDetails,
|
||||
HistorySortPrompt,
|
||||
Indexers,
|
||||
IndexerSettingsConfirmPrompt,
|
||||
IndexerSettingsMaximumSizeInput,
|
||||
IndexerSettingsMinimumAgeInput,
|
||||
IndexerSettingsRetentionInput,
|
||||
IndexerSettingsRssSyncIntervalInput,
|
||||
ManualAuthorSearch,
|
||||
ManualAuthorSearchConfirmPrompt,
|
||||
ManualAuthorSearchSortPrompt,
|
||||
ManualBookSearch,
|
||||
ManualBookSearchConfirmPrompt,
|
||||
ManualBookSearchSortPrompt,
|
||||
RootFolders,
|
||||
SearchAuthorHistory,
|
||||
SearchAuthorHistoryError,
|
||||
SearchAuthors,
|
||||
SearchAuthorsError,
|
||||
SearchBookHistory,
|
||||
SearchBookHistoryError,
|
||||
SearchBooks,
|
||||
SearchBooksError,
|
||||
SearchEditions,
|
||||
SearchEditionsError,
|
||||
SearchHistory,
|
||||
SearchHistoryError,
|
||||
System,
|
||||
SystemLogs,
|
||||
SystemQueuedEvents,
|
||||
SystemTasks,
|
||||
SystemTaskStartConfirmPrompt,
|
||||
SystemUpdates,
|
||||
TestAllIndexers,
|
||||
TestIndexer,
|
||||
UpdateAllAuthorsPrompt,
|
||||
UpdateAndScanAuthorPrompt,
|
||||
UpdateDownloadsPrompt,
|
||||
}
|
||||
|
||||
pub static LIBRARY_BLOCKS: [ActiveReadarrBlock; 7] = [
|
||||
ActiveReadarrBlock::Authors,
|
||||
ActiveReadarrBlock::AuthorsSortPrompt,
|
||||
ActiveReadarrBlock::FilterAuthors,
|
||||
ActiveReadarrBlock::FilterAuthorsError,
|
||||
ActiveReadarrBlock::SearchAuthors,
|
||||
ActiveReadarrBlock::SearchAuthorsError,
|
||||
ActiveReadarrBlock::UpdateAllAuthorsPrompt,
|
||||
];
|
||||
|
||||
pub static AUTHOR_DETAILS_BLOCKS: [ActiveReadarrBlock; 15] = [
|
||||
ActiveReadarrBlock::AuthorDetails,
|
||||
ActiveReadarrBlock::AuthorHistory,
|
||||
ActiveReadarrBlock::AuthorHistoryDetails,
|
||||
ActiveReadarrBlock::AuthorHistorySortPrompt,
|
||||
ActiveReadarrBlock::AutomaticallySearchAuthorPrompt,
|
||||
ActiveReadarrBlock::FilterAuthorHistory,
|
||||
ActiveReadarrBlock::FilterAuthorHistoryError,
|
||||
ActiveReadarrBlock::ManualAuthorSearch,
|
||||
ActiveReadarrBlock::ManualAuthorSearchConfirmPrompt,
|
||||
ActiveReadarrBlock::ManualAuthorSearchSortPrompt,
|
||||
ActiveReadarrBlock::SearchBooks,
|
||||
ActiveReadarrBlock::SearchBooksError,
|
||||
ActiveReadarrBlock::SearchAuthorHistory,
|
||||
ActiveReadarrBlock::SearchAuthorHistoryError,
|
||||
ActiveReadarrBlock::UpdateAndScanAuthorPrompt,
|
||||
];
|
||||
|
||||
pub static BOOK_DETAILS_BLOCKS: [ActiveReadarrBlock; 16] = [
|
||||
ActiveReadarrBlock::BookDetails,
|
||||
ActiveReadarrBlock::BookHistory,
|
||||
ActiveReadarrBlock::BookHistoryDetails,
|
||||
ActiveReadarrBlock::BookHistorySortPrompt,
|
||||
ActiveReadarrBlock::AutomaticallySearchBookPrompt,
|
||||
ActiveReadarrBlock::DeleteBookFilePrompt,
|
||||
ActiveReadarrBlock::FilterBookHistory,
|
||||
ActiveReadarrBlock::FilterBookHistoryError,
|
||||
ActiveReadarrBlock::BookFileInfo,
|
||||
ActiveReadarrBlock::ManualBookSearch,
|
||||
ActiveReadarrBlock::ManualBookSearchConfirmPrompt,
|
||||
ActiveReadarrBlock::ManualBookSearchSortPrompt,
|
||||
ActiveReadarrBlock::SearchBookHistory,
|
||||
ActiveReadarrBlock::SearchBookHistoryError,
|
||||
ActiveReadarrBlock::SearchEditions,
|
||||
ActiveReadarrBlock::SearchEditionsError,
|
||||
];
|
||||
|
||||
pub static EDITION_DETAILS_BLOCKS: [ActiveReadarrBlock; 1] =
|
||||
[ActiveReadarrBlock::BookEditionDetails];
|
||||
|
||||
pub static ADD_AUTHOR_BLOCKS: [ActiveReadarrBlock; 12] = [
|
||||
ActiveReadarrBlock::AddAuthorAlreadyInLibrary,
|
||||
ActiveReadarrBlock::AddAuthorConfirmPrompt,
|
||||
ActiveReadarrBlock::AddAuthorEmptySearchResults,
|
||||
ActiveReadarrBlock::AddAuthorPrompt,
|
||||
ActiveReadarrBlock::AddAuthorSearchInput,
|
||||
ActiveReadarrBlock::AddAuthorSearchResults,
|
||||
ActiveReadarrBlock::AddAuthorSelectMetadataProfile,
|
||||
ActiveReadarrBlock::AddAuthorSelectMonitor,
|
||||
ActiveReadarrBlock::AddAuthorSelectMonitorNewItems,
|
||||
ActiveReadarrBlock::AddAuthorSelectQualityProfile,
|
||||
ActiveReadarrBlock::AddAuthorSelectRootFolder,
|
||||
ActiveReadarrBlock::AddAuthorTagsInput,
|
||||
];
|
||||
|
||||
pub const ADD_AUTHOR_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[ActiveReadarrBlock::AddAuthorSelectRootFolder],
|
||||
&[ActiveReadarrBlock::AddAuthorSelectMonitor],
|
||||
&[ActiveReadarrBlock::AddAuthorSelectMonitorNewItems],
|
||||
&[ActiveReadarrBlock::AddAuthorSelectQualityProfile],
|
||||
&[ActiveReadarrBlock::AddAuthorSelectMetadataProfile],
|
||||
&[ActiveReadarrBlock::AddAuthorTagsInput],
|
||||
&[ActiveReadarrBlock::AddAuthorConfirmPrompt],
|
||||
];
|
||||
|
||||
pub static DELETE_AUTHOR_BLOCKS: [ActiveReadarrBlock; 4] = [
|
||||
ActiveReadarrBlock::DeleteAuthorPrompt,
|
||||
ActiveReadarrBlock::DeleteAuthorConfirmPrompt,
|
||||
ActiveReadarrBlock::DeleteAuthorToggleDeleteFile,
|
||||
ActiveReadarrBlock::DeleteAuthorToggleAddListExclusion,
|
||||
];
|
||||
|
||||
pub const DELETE_AUTHOR_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[ActiveReadarrBlock::DeleteAuthorToggleDeleteFile],
|
||||
&[ActiveReadarrBlock::DeleteAuthorToggleAddListExclusion],
|
||||
&[ActiveReadarrBlock::DeleteAuthorConfirmPrompt],
|
||||
];
|
||||
|
||||
pub static DELETE_BOOK_BLOCKS: [ActiveReadarrBlock; 4] = [
|
||||
ActiveReadarrBlock::DeleteBookPrompt,
|
||||
ActiveReadarrBlock::DeleteBookConfirmPrompt,
|
||||
ActiveReadarrBlock::DeleteBookToggleDeleteFile,
|
||||
ActiveReadarrBlock::DeleteBookToggleAddListExclusion,
|
||||
];
|
||||
|
||||
pub const DELETE_BOOK_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[ActiveReadarrBlock::DeleteBookToggleDeleteFile],
|
||||
&[ActiveReadarrBlock::DeleteBookToggleAddListExclusion],
|
||||
&[ActiveReadarrBlock::DeleteBookConfirmPrompt],
|
||||
];
|
||||
|
||||
pub static EDIT_AUTHOR_BLOCKS: [ActiveReadarrBlock; 8] = [
|
||||
ActiveReadarrBlock::EditAuthorPrompt,
|
||||
ActiveReadarrBlock::EditAuthorConfirmPrompt,
|
||||
ActiveReadarrBlock::EditAuthorPathInput,
|
||||
ActiveReadarrBlock::EditAuthorSelectMetadataProfile,
|
||||
ActiveReadarrBlock::EditAuthorSelectMonitorNewItems,
|
||||
ActiveReadarrBlock::EditAuthorSelectQualityProfile,
|
||||
ActiveReadarrBlock::EditAuthorTagsInput,
|
||||
ActiveReadarrBlock::EditAuthorToggleMonitored,
|
||||
];
|
||||
|
||||
pub const EDIT_AUTHOR_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[ActiveReadarrBlock::EditAuthorToggleMonitored],
|
||||
&[ActiveReadarrBlock::EditAuthorSelectMonitorNewItems],
|
||||
&[ActiveReadarrBlock::EditAuthorSelectQualityProfile],
|
||||
&[ActiveReadarrBlock::EditAuthorSelectMetadataProfile],
|
||||
&[ActiveReadarrBlock::EditAuthorPathInput],
|
||||
&[ActiveReadarrBlock::EditAuthorTagsInput],
|
||||
&[ActiveReadarrBlock::EditAuthorConfirmPrompt],
|
||||
];
|
||||
|
||||
pub static ADD_ROOT_FOLDER_BLOCKS: [ActiveReadarrBlock; 9] = [
|
||||
ActiveReadarrBlock::AddRootFolderPrompt,
|
||||
ActiveReadarrBlock::AddRootFolderConfirmPrompt,
|
||||
ActiveReadarrBlock::AddRootFolderNameInput,
|
||||
ActiveReadarrBlock::AddRootFolderPathInput,
|
||||
ActiveReadarrBlock::AddRootFolderSelectMonitor,
|
||||
ActiveReadarrBlock::AddRootFolderSelectMonitorNewItems,
|
||||
ActiveReadarrBlock::AddRootFolderSelectQualityProfile,
|
||||
ActiveReadarrBlock::AddRootFolderSelectMetadataProfile,
|
||||
ActiveReadarrBlock::AddRootFolderTagsInput,
|
||||
];
|
||||
|
||||
pub const ADD_ROOT_FOLDER_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[ActiveReadarrBlock::AddRootFolderNameInput],
|
||||
&[ActiveReadarrBlock::AddRootFolderPathInput],
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectMonitor],
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectMonitorNewItems],
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectQualityProfile],
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectMetadataProfile],
|
||||
&[ActiveReadarrBlock::AddRootFolderTagsInput],
|
||||
&[ActiveReadarrBlock::AddRootFolderConfirmPrompt],
|
||||
];
|
||||
|
||||
pub static ROOT_FOLDERS_BLOCKS: [ActiveReadarrBlock; 2] = [
|
||||
ActiveReadarrBlock::RootFolders,
|
||||
ActiveReadarrBlock::DeleteRootFolderPrompt,
|
||||
];
|
||||
|
||||
pub static BLOCKLIST_BLOCKS: [ActiveReadarrBlock; 5] = [
|
||||
ActiveReadarrBlock::Blocklist,
|
||||
ActiveReadarrBlock::BlocklistItemDetails,
|
||||
ActiveReadarrBlock::DeleteBlocklistItemPrompt,
|
||||
ActiveReadarrBlock::BlocklistClearAllItemsPrompt,
|
||||
ActiveReadarrBlock::BlocklistSortPrompt,
|
||||
];
|
||||
|
||||
pub static DOWNLOADS_BLOCKS: [ActiveReadarrBlock; 3] = [
|
||||
ActiveReadarrBlock::Downloads,
|
||||
ActiveReadarrBlock::DeleteDownloadPrompt,
|
||||
ActiveReadarrBlock::UpdateDownloadsPrompt,
|
||||
];
|
||||
|
||||
pub static HISTORY_BLOCKS: [ActiveReadarrBlock; 7] = [
|
||||
ActiveReadarrBlock::History,
|
||||
ActiveReadarrBlock::HistoryItemDetails,
|
||||
ActiveReadarrBlock::HistorySortPrompt,
|
||||
ActiveReadarrBlock::SearchHistory,
|
||||
ActiveReadarrBlock::SearchHistoryError,
|
||||
ActiveReadarrBlock::FilterHistory,
|
||||
ActiveReadarrBlock::FilterHistoryError,
|
||||
];
|
||||
|
||||
pub static EDIT_INDEXER_BLOCKS: [ActiveReadarrBlock; 11] = [
|
||||
ActiveReadarrBlock::EditIndexerPrompt,
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
ActiveReadarrBlock::EditIndexerApiKeyInput,
|
||||
ActiveReadarrBlock::EditIndexerNameInput,
|
||||
ActiveReadarrBlock::EditIndexerSeedRatioInput,
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableRss,
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch,
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch,
|
||||
ActiveReadarrBlock::EditIndexerPriorityInput,
|
||||
ActiveReadarrBlock::EditIndexerUrlInput,
|
||||
ActiveReadarrBlock::EditIndexerTagsInput,
|
||||
];
|
||||
|
||||
pub const EDIT_INDEXER_TORRENT_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerNameInput,
|
||||
ActiveReadarrBlock::EditIndexerUrlInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableRss,
|
||||
ActiveReadarrBlock::EditIndexerApiKeyInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch,
|
||||
ActiveReadarrBlock::EditIndexerSeedRatioInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch,
|
||||
ActiveReadarrBlock::EditIndexerTagsInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerPriorityInput,
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
],
|
||||
];
|
||||
|
||||
pub const EDIT_INDEXER_NZB_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerNameInput,
|
||||
ActiveReadarrBlock::EditIndexerUrlInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableRss,
|
||||
ActiveReadarrBlock::EditIndexerApiKeyInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch,
|
||||
ActiveReadarrBlock::EditIndexerTagsInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch,
|
||||
ActiveReadarrBlock::EditIndexerPriorityInput,
|
||||
],
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
],
|
||||
];
|
||||
|
||||
pub static INDEXER_SETTINGS_BLOCKS: [ActiveReadarrBlock; 6] = [
|
||||
ActiveReadarrBlock::AllIndexerSettingsPrompt,
|
||||
ActiveReadarrBlock::IndexerSettingsConfirmPrompt,
|
||||
ActiveReadarrBlock::IndexerSettingsMaximumSizeInput,
|
||||
ActiveReadarrBlock::IndexerSettingsMinimumAgeInput,
|
||||
ActiveReadarrBlock::IndexerSettingsRetentionInput,
|
||||
ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput,
|
||||
];
|
||||
|
||||
pub const INDEXER_SETTINGS_SELECTION_BLOCKS: &[&[ActiveReadarrBlock]] = &[
|
||||
&[ActiveReadarrBlock::IndexerSettingsMinimumAgeInput],
|
||||
&[ActiveReadarrBlock::IndexerSettingsRetentionInput],
|
||||
&[ActiveReadarrBlock::IndexerSettingsMaximumSizeInput],
|
||||
&[ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput],
|
||||
&[ActiveReadarrBlock::IndexerSettingsConfirmPrompt],
|
||||
];
|
||||
|
||||
pub static INDEXERS_BLOCKS: [ActiveReadarrBlock; 3] = [
|
||||
ActiveReadarrBlock::Indexers,
|
||||
ActiveReadarrBlock::DeleteIndexerPrompt,
|
||||
ActiveReadarrBlock::TestIndexer,
|
||||
];
|
||||
|
||||
pub static SYSTEM_DETAILS_BLOCKS: [ActiveReadarrBlock; 5] = [
|
||||
ActiveReadarrBlock::SystemLogs,
|
||||
ActiveReadarrBlock::SystemQueuedEvents,
|
||||
ActiveReadarrBlock::SystemTasks,
|
||||
ActiveReadarrBlock::SystemTaskStartConfirmPrompt,
|
||||
ActiveReadarrBlock::SystemUpdates,
|
||||
];
|
||||
|
||||
impl From<ActiveReadarrBlock> for Route {
|
||||
fn from(active_readarr_block: ActiveReadarrBlock) -> Route {
|
||||
Route::Readarr(active_readarr_block, None)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<(ActiveReadarrBlock, Option<ActiveReadarrBlock>)> for Route {
|
||||
fn from(value: (ActiveReadarrBlock, Option<ActiveReadarrBlock>)) -> Route {
|
||||
Route::Readarr(value.0, value.1)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,789 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::app::context_clues::{
|
||||
BLOCKLIST_CONTEXT_CLUES, DOWNLOADS_CONTEXT_CLUES, HISTORY_CONTEXT_CLUES,
|
||||
INDEXERS_CONTEXT_CLUES, ROOT_FOLDERS_CONTEXT_CLUES, SYSTEM_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::app::readarr::readarr_context_clues::{
|
||||
AUTHOR_DETAILS_CONTEXT_CLUES, AUTHOR_HISTORY_CONTEXT_CLUES, AUTHORS_CONTEXT_CLUES,
|
||||
MANUAL_AUTHOR_SEARCH_CONTEXT_CLUES,
|
||||
};
|
||||
use crate::models::readarr_models::{Book, ReadarrHistoryItem, ReadarrRelease};
|
||||
use crate::models::servarr_data::readarr::readarr_data::{
|
||||
ADD_AUTHOR_BLOCKS, ADD_AUTHOR_SELECTION_BLOCKS, ADD_ROOT_FOLDER_BLOCKS,
|
||||
ADD_ROOT_FOLDER_SELECTION_BLOCKS, AUTHOR_DETAILS_BLOCKS, ActiveReadarrBlock, BLOCKLIST_BLOCKS,
|
||||
BOOK_DETAILS_BLOCKS, DELETE_AUTHOR_BLOCKS, DELETE_AUTHOR_SELECTION_BLOCKS, DELETE_BOOK_BLOCKS,
|
||||
DELETE_BOOK_SELECTION_BLOCKS, DOWNLOADS_BLOCKS, EDIT_AUTHOR_BLOCKS,
|
||||
EDIT_AUTHOR_SELECTION_BLOCKS, EDIT_INDEXER_BLOCKS, EDIT_INDEXER_NZB_SELECTION_BLOCKS,
|
||||
EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, EDITION_DETAILS_BLOCKS, HISTORY_BLOCKS,
|
||||
INDEXER_SETTINGS_BLOCKS, INDEXER_SETTINGS_SELECTION_BLOCKS, INDEXERS_BLOCKS, LIBRARY_BLOCKS,
|
||||
ROOT_FOLDERS_BLOCKS, ReadarrData, SYSTEM_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::models::{BlockSelectionState, Route};
|
||||
use bimap::BiMap;
|
||||
use chrono::{DateTime, Utc};
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
use serde_json::Number;
|
||||
|
||||
#[test]
|
||||
fn test_from_active_readarr_block_to_route() {
|
||||
assert_eq!(
|
||||
Route::from(ActiveReadarrBlock::Authors),
|
||||
Route::Readarr(ActiveReadarrBlock::Authors, None)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_from_tuple_to_route_with_context() {
|
||||
assert_eq!(
|
||||
Route::from((
|
||||
ActiveReadarrBlock::Authors,
|
||||
Some(ActiveReadarrBlock::Authors)
|
||||
)),
|
||||
Route::Readarr(
|
||||
ActiveReadarrBlock::Authors,
|
||||
Some(ActiveReadarrBlock::Authors),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reset_delete_preferences() {
|
||||
let mut readarr_data = ReadarrData {
|
||||
delete_files: true,
|
||||
add_import_list_exclusion: true,
|
||||
..ReadarrData::default()
|
||||
};
|
||||
|
||||
readarr_data.reset_delete_preferences();
|
||||
|
||||
assert!(!readarr_data.delete_files);
|
||||
assert!(!readarr_data.add_import_list_exclusion);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_reset_author_info_tabs() {
|
||||
let mut readarr_data = ReadarrData::default();
|
||||
readarr_data.books.set_items(vec![Book::default()]);
|
||||
readarr_data
|
||||
.author_releases
|
||||
.set_items(vec![ReadarrRelease::default()]);
|
||||
readarr_data
|
||||
.author_history
|
||||
.set_items(vec![ReadarrHistoryItem::default()]);
|
||||
readarr_data.author_info_tabs.index = 1;
|
||||
|
||||
readarr_data.reset_author_info_tabs();
|
||||
|
||||
assert_is_empty!(readarr_data.books);
|
||||
assert_is_empty!(readarr_data.author_releases);
|
||||
assert_is_empty!(readarr_data.author_history);
|
||||
assert_eq!(readarr_data.author_info_tabs.index, 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tag_ids_to_display() {
|
||||
let mut tags_map = BiMap::new();
|
||||
tags_map.insert(3, "test 3".to_owned());
|
||||
tags_map.insert(2, "test 2".to_owned());
|
||||
tags_map.insert(1, "test 1".to_owned());
|
||||
let readarr_data = ReadarrData {
|
||||
tags_map,
|
||||
..ReadarrData::default()
|
||||
};
|
||||
|
||||
assert_str_eq!(
|
||||
readarr_data.tag_ids_to_display(&[Number::from(1), Number::from(2)]),
|
||||
"test 1, test 2"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sorted_quality_profile_names() {
|
||||
let mut quality_profile_map = BiMap::new();
|
||||
quality_profile_map.insert(3, "test 1".to_owned());
|
||||
quality_profile_map.insert(2, "test 2".to_owned());
|
||||
quality_profile_map.insert(1, "test 3".to_owned());
|
||||
let readarr_data = ReadarrData {
|
||||
quality_profile_map,
|
||||
..ReadarrData::default()
|
||||
};
|
||||
let expected_quality_profile_vec = vec![
|
||||
"test 3".to_owned(),
|
||||
"test 2".to_owned(),
|
||||
"test 1".to_owned(),
|
||||
];
|
||||
|
||||
assert_iter_eq!(
|
||||
readarr_data.sorted_quality_profile_names(),
|
||||
expected_quality_profile_vec
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sorted_metadata_profile_names() {
|
||||
let mut metadata_profile_map = BiMap::new();
|
||||
metadata_profile_map.insert(3, "test 1".to_owned());
|
||||
metadata_profile_map.insert(2, "test 2".to_owned());
|
||||
metadata_profile_map.insert(1, "test 3".to_owned());
|
||||
let readarr_data = ReadarrData {
|
||||
metadata_profile_map,
|
||||
..ReadarrData::default()
|
||||
};
|
||||
let expected_metadata_profile_vec = vec![
|
||||
"test 3".to_owned(),
|
||||
"test 2".to_owned(),
|
||||
"test 1".to_owned(),
|
||||
];
|
||||
|
||||
assert_iter_eq!(
|
||||
readarr_data.sorted_metadata_profile_names(),
|
||||
expected_metadata_profile_vec
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_readarr_data_default() {
|
||||
let readarr_data = ReadarrData::default();
|
||||
|
||||
assert_none!(readarr_data.add_author_modal);
|
||||
assert_none!(readarr_data.add_author_search);
|
||||
assert!(!readarr_data.add_import_list_exclusion);
|
||||
assert_none!(readarr_data.add_root_folder_modal);
|
||||
assert_none!(readarr_data.add_searched_authors);
|
||||
assert_is_empty!(readarr_data.author_history);
|
||||
assert_is_empty!(readarr_data.author_releases);
|
||||
assert_is_empty!(readarr_data.authors);
|
||||
assert_is_empty!(readarr_data.blocklist);
|
||||
assert_none!(readarr_data.book_details_modal);
|
||||
assert_is_empty!(readarr_data.books);
|
||||
assert!(!readarr_data.delete_files);
|
||||
assert_is_empty!(readarr_data.disk_space_vec);
|
||||
assert_is_empty!(readarr_data.downloads);
|
||||
assert_none!(readarr_data.edit_author_modal);
|
||||
assert_none!(readarr_data.edit_indexer_modal);
|
||||
assert_is_empty!(readarr_data.history);
|
||||
assert_none!(readarr_data.indexer_settings);
|
||||
assert_none!(readarr_data.indexer_test_all_results);
|
||||
assert_none!(readarr_data.indexer_test_errors);
|
||||
assert_is_empty!(readarr_data.indexers);
|
||||
assert_is_empty!(readarr_data.log_details);
|
||||
assert_is_empty!(readarr_data.logs);
|
||||
assert_is_empty!(readarr_data.metadata_profile_map);
|
||||
assert!(!readarr_data.prompt_confirm);
|
||||
assert_none!(readarr_data.prompt_confirm_action);
|
||||
assert_is_empty!(readarr_data.quality_profile_map);
|
||||
assert_is_empty!(readarr_data.queued_events);
|
||||
assert_is_empty!(readarr_data.root_folders);
|
||||
assert_eq!(readarr_data.selected_block, BlockSelectionState::default());
|
||||
assert_eq!(readarr_data.start_time, <DateTime<Utc>>::default());
|
||||
assert_is_empty!(readarr_data.tags_map);
|
||||
assert_is_empty!(readarr_data.tasks);
|
||||
assert_is_empty!(readarr_data.updates);
|
||||
assert_is_empty!(readarr_data.version);
|
||||
|
||||
assert_eq!(readarr_data.main_tabs.tabs.len(), 7);
|
||||
|
||||
assert_str_eq!(readarr_data.main_tabs.tabs[0].title, "Library");
|
||||
assert_eq!(
|
||||
readarr_data.main_tabs.tabs[0].route,
|
||||
ActiveReadarrBlock::Authors.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.main_tabs.tabs[0].contextual_help,
|
||||
&AUTHORS_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.main_tabs.tabs[0].config);
|
||||
|
||||
assert_str_eq!(readarr_data.main_tabs.tabs[1].title, "Downloads");
|
||||
assert_eq!(
|
||||
readarr_data.main_tabs.tabs[1].route,
|
||||
ActiveReadarrBlock::Downloads.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.main_tabs.tabs[1].contextual_help,
|
||||
&DOWNLOADS_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.main_tabs.tabs[1].config);
|
||||
|
||||
assert_str_eq!(readarr_data.main_tabs.tabs[2].title, "Blocklist");
|
||||
assert_eq!(
|
||||
readarr_data.main_tabs.tabs[2].route,
|
||||
ActiveReadarrBlock::Blocklist.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.main_tabs.tabs[2].contextual_help,
|
||||
&BLOCKLIST_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.main_tabs.tabs[2].config);
|
||||
|
||||
assert_str_eq!(readarr_data.main_tabs.tabs[3].title, "History");
|
||||
assert_eq!(
|
||||
readarr_data.main_tabs.tabs[3].route,
|
||||
ActiveReadarrBlock::History.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.main_tabs.tabs[3].contextual_help,
|
||||
&HISTORY_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.main_tabs.tabs[3].config);
|
||||
|
||||
assert_str_eq!(readarr_data.main_tabs.tabs[4].title, "Root Folders");
|
||||
assert_eq!(
|
||||
readarr_data.main_tabs.tabs[4].route,
|
||||
ActiveReadarrBlock::RootFolders.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.main_tabs.tabs[4].contextual_help,
|
||||
&ROOT_FOLDERS_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.main_tabs.tabs[4].config);
|
||||
|
||||
assert_str_eq!(readarr_data.main_tabs.tabs[5].title, "Indexers");
|
||||
assert_eq!(
|
||||
readarr_data.main_tabs.tabs[5].route,
|
||||
ActiveReadarrBlock::Indexers.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.main_tabs.tabs[5].contextual_help,
|
||||
&INDEXERS_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.main_tabs.tabs[5].config);
|
||||
|
||||
assert_str_eq!(readarr_data.main_tabs.tabs[6].title, "System");
|
||||
assert_eq!(
|
||||
readarr_data.main_tabs.tabs[6].route,
|
||||
ActiveReadarrBlock::System.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.main_tabs.tabs[6].contextual_help,
|
||||
&SYSTEM_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.main_tabs.tabs[6].config);
|
||||
|
||||
assert_eq!(readarr_data.author_info_tabs.tabs.len(), 3);
|
||||
|
||||
assert_str_eq!(readarr_data.author_info_tabs.tabs[0].title, "Books");
|
||||
assert_eq!(
|
||||
readarr_data.author_info_tabs.tabs[0].route,
|
||||
ActiveReadarrBlock::AuthorDetails.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.author_info_tabs.tabs[0].contextual_help,
|
||||
&AUTHOR_DETAILS_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.author_info_tabs.tabs[0].config);
|
||||
|
||||
assert_str_eq!(readarr_data.author_info_tabs.tabs[1].title, "History");
|
||||
assert_eq!(
|
||||
readarr_data.author_info_tabs.tabs[1].route,
|
||||
ActiveReadarrBlock::AuthorHistory.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.author_info_tabs.tabs[1].contextual_help,
|
||||
&AUTHOR_HISTORY_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.author_info_tabs.tabs[1].config);
|
||||
|
||||
assert_str_eq!(readarr_data.author_info_tabs.tabs[2].title, "Author Search");
|
||||
assert_eq!(
|
||||
readarr_data.author_info_tabs.tabs[2].route,
|
||||
ActiveReadarrBlock::ManualAuthorSearch.into()
|
||||
);
|
||||
assert_some_eq_x!(
|
||||
&readarr_data.author_info_tabs.tabs[2].contextual_help,
|
||||
&MANUAL_AUTHOR_SEARCH_CONTEXT_CLUES
|
||||
);
|
||||
assert_none!(readarr_data.author_info_tabs.tabs[2].config);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_library_blocks_contains_expected_blocks() {
|
||||
assert_eq!(LIBRARY_BLOCKS.len(), 7);
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveReadarrBlock::Authors));
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveReadarrBlock::AuthorsSortPrompt));
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveReadarrBlock::FilterAuthors));
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveReadarrBlock::FilterAuthorsError));
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveReadarrBlock::SearchAuthors));
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveReadarrBlock::SearchAuthorsError));
|
||||
assert!(LIBRARY_BLOCKS.contains(&ActiveReadarrBlock::UpdateAllAuthorsPrompt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_author_details_blocks_contains_expected_blocks() {
|
||||
assert_eq!(AUTHOR_DETAILS_BLOCKS.len(), 15);
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::AuthorDetails));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::AuthorHistory));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::AuthorHistoryDetails));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::AuthorHistorySortPrompt));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::AutomaticallySearchAuthorPrompt));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::FilterAuthorHistory));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::FilterAuthorHistoryError));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::ManualAuthorSearch));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::ManualAuthorSearchConfirmPrompt));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::ManualAuthorSearchSortPrompt));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchBooks));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchBooksError));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchAuthorHistory));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchAuthorHistoryError));
|
||||
assert!(AUTHOR_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::UpdateAndScanAuthorPrompt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_book_details_blocks_contents() {
|
||||
assert_eq!(BOOK_DETAILS_BLOCKS.len(), 16);
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::BookDetails));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::BookHistory));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::BookHistoryDetails));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::BookHistorySortPrompt));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::AutomaticallySearchBookPrompt));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::DeleteBookFilePrompt));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::FilterBookHistory));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::FilterBookHistoryError));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::BookFileInfo));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::ManualBookSearch));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::ManualBookSearchConfirmPrompt));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::ManualBookSearchSortPrompt));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchBookHistory));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchBookHistoryError));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchEditions));
|
||||
assert!(BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SearchEditionsError));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_book_details_blocks_excludes_book_edition_details() {
|
||||
assert!(!BOOK_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::BookEditionDetails));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_blocks_contents() {
|
||||
assert_eq!(EDITION_DETAILS_BLOCKS.len(), 1);
|
||||
assert!(EDITION_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::BookEditionDetails));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_blocklist_blocks_contents() {
|
||||
assert_eq!(BLOCKLIST_BLOCKS.len(), 5);
|
||||
assert!(BLOCKLIST_BLOCKS.contains(&ActiveReadarrBlock::Blocklist));
|
||||
assert!(BLOCKLIST_BLOCKS.contains(&ActiveReadarrBlock::BlocklistItemDetails));
|
||||
assert!(BLOCKLIST_BLOCKS.contains(&ActiveReadarrBlock::DeleteBlocklistItemPrompt));
|
||||
assert!(BLOCKLIST_BLOCKS.contains(&ActiveReadarrBlock::BlocklistClearAllItemsPrompt));
|
||||
assert!(BLOCKLIST_BLOCKS.contains(&ActiveReadarrBlock::BlocklistSortPrompt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_downloads_blocks_contains_expected_blocks() {
|
||||
assert_eq!(DOWNLOADS_BLOCKS.len(), 3);
|
||||
assert!(DOWNLOADS_BLOCKS.contains(&ActiveReadarrBlock::Downloads));
|
||||
assert!(DOWNLOADS_BLOCKS.contains(&ActiveReadarrBlock::DeleteDownloadPrompt));
|
||||
assert!(DOWNLOADS_BLOCKS.contains(&ActiveReadarrBlock::UpdateDownloadsPrompt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_history_blocks_contains_expected_blocks() {
|
||||
assert_eq!(HISTORY_BLOCKS.len(), 7);
|
||||
assert!(HISTORY_BLOCKS.contains(&ActiveReadarrBlock::History));
|
||||
assert!(HISTORY_BLOCKS.contains(&ActiveReadarrBlock::HistoryItemDetails));
|
||||
assert!(HISTORY_BLOCKS.contains(&ActiveReadarrBlock::HistorySortPrompt));
|
||||
assert!(HISTORY_BLOCKS.contains(&ActiveReadarrBlock::SearchHistory));
|
||||
assert!(HISTORY_BLOCKS.contains(&ActiveReadarrBlock::SearchHistoryError));
|
||||
assert!(HISTORY_BLOCKS.contains(&ActiveReadarrBlock::FilterHistory));
|
||||
assert!(HISTORY_BLOCKS.contains(&ActiveReadarrBlock::FilterHistoryError));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_author_blocks_contents() {
|
||||
assert_eq!(ADD_AUTHOR_BLOCKS.len(), 12);
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorAlreadyInLibrary));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorConfirmPrompt));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorEmptySearchResults));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorPrompt));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorSearchInput));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorSearchResults));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorSelectMetadataProfile));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorSelectMonitor));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorSelectMonitorNewItems));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorSelectQualityProfile));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorSelectRootFolder));
|
||||
assert!(ADD_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::AddAuthorTagsInput));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_author_selection_blocks_ordering() {
|
||||
let mut add_author_block_iter = ADD_AUTHOR_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
add_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddAuthorSelectRootFolder]
|
||||
);
|
||||
assert_eq!(
|
||||
add_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddAuthorSelectMonitor]
|
||||
);
|
||||
assert_eq!(
|
||||
add_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddAuthorSelectMonitorNewItems]
|
||||
);
|
||||
assert_eq!(
|
||||
add_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddAuthorSelectQualityProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
add_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddAuthorSelectMetadataProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
add_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddAuthorTagsInput]
|
||||
);
|
||||
assert_eq!(
|
||||
add_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddAuthorConfirmPrompt]
|
||||
);
|
||||
assert_none!(add_author_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_author_blocks_contents() {
|
||||
assert_eq!(DELETE_AUTHOR_BLOCKS.len(), 4);
|
||||
assert!(DELETE_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::DeleteAuthorPrompt));
|
||||
assert!(DELETE_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::DeleteAuthorConfirmPrompt));
|
||||
assert!(DELETE_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::DeleteAuthorToggleDeleteFile));
|
||||
assert!(DELETE_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::DeleteAuthorToggleAddListExclusion));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_author_selection_blocks_ordering() {
|
||||
let mut delete_author_block_iter = DELETE_AUTHOR_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
delete_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::DeleteAuthorToggleDeleteFile]
|
||||
);
|
||||
assert_eq!(
|
||||
delete_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::DeleteAuthorToggleAddListExclusion]
|
||||
);
|
||||
assert_eq!(
|
||||
delete_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::DeleteAuthorConfirmPrompt]
|
||||
);
|
||||
assert_none!(delete_author_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_book_blocks_contents() {
|
||||
assert_eq!(DELETE_BOOK_BLOCKS.len(), 4);
|
||||
assert!(DELETE_BOOK_BLOCKS.contains(&ActiveReadarrBlock::DeleteBookPrompt));
|
||||
assert!(DELETE_BOOK_BLOCKS.contains(&ActiveReadarrBlock::DeleteBookConfirmPrompt));
|
||||
assert!(DELETE_BOOK_BLOCKS.contains(&ActiveReadarrBlock::DeleteBookToggleDeleteFile));
|
||||
assert!(DELETE_BOOK_BLOCKS.contains(&ActiveReadarrBlock::DeleteBookToggleAddListExclusion));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_book_selection_blocks_ordering() {
|
||||
let mut delete_book_block_iter = DELETE_BOOK_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
delete_book_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::DeleteBookToggleDeleteFile]
|
||||
);
|
||||
assert_eq!(
|
||||
delete_book_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::DeleteBookToggleAddListExclusion]
|
||||
);
|
||||
assert_eq!(
|
||||
delete_book_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::DeleteBookConfirmPrompt]
|
||||
);
|
||||
assert_none!(delete_book_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_author_blocks() {
|
||||
assert_eq!(EDIT_AUTHOR_BLOCKS.len(), 8);
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorPrompt));
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorConfirmPrompt));
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorPathInput));
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorSelectMetadataProfile));
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorSelectMonitorNewItems));
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorSelectQualityProfile));
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorTagsInput));
|
||||
assert!(EDIT_AUTHOR_BLOCKS.contains(&ActiveReadarrBlock::EditAuthorToggleMonitored));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_author_selection_blocks_ordering() {
|
||||
let mut edit_author_block_iter = EDIT_AUTHOR_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
edit_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::EditAuthorToggleMonitored]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::EditAuthorSelectMonitorNewItems]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::EditAuthorSelectQualityProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::EditAuthorSelectMetadataProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::EditAuthorPathInput]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::EditAuthorTagsInput]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_author_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::EditAuthorConfirmPrompt]
|
||||
);
|
||||
assert_none!(edit_author_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_root_folders_blocks_contents() {
|
||||
assert_eq!(ROOT_FOLDERS_BLOCKS.len(), 2);
|
||||
assert!(ROOT_FOLDERS_BLOCKS.contains(&ActiveReadarrBlock::RootFolders));
|
||||
assert!(ROOT_FOLDERS_BLOCKS.contains(&ActiveReadarrBlock::DeleteRootFolderPrompt));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_root_folder_blocks_contents() {
|
||||
assert_eq!(ADD_ROOT_FOLDER_BLOCKS.len(), 9);
|
||||
assert!(ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderPrompt));
|
||||
assert!(ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderConfirmPrompt));
|
||||
assert!(ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderNameInput));
|
||||
assert!(ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderPathInput));
|
||||
assert!(ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderSelectMonitor));
|
||||
assert!(
|
||||
ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderSelectMonitorNewItems)
|
||||
);
|
||||
assert!(
|
||||
ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderSelectQualityProfile)
|
||||
);
|
||||
assert!(
|
||||
ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderSelectMetadataProfile)
|
||||
);
|
||||
assert!(ADD_ROOT_FOLDER_BLOCKS.contains(&ActiveReadarrBlock::AddRootFolderTagsInput));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_root_folder_selection_blocks_ordering() {
|
||||
let mut add_root_folder_block_iter = ADD_ROOT_FOLDER_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderNameInput]
|
||||
);
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderPathInput]
|
||||
);
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectMonitor]
|
||||
);
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectMonitorNewItems]
|
||||
);
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectQualityProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderSelectMetadataProfile]
|
||||
);
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderTagsInput]
|
||||
);
|
||||
assert_eq!(
|
||||
add_root_folder_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::AddRootFolderConfirmPrompt]
|
||||
);
|
||||
assert_none!(add_root_folder_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_indexer_blocks_contents() {
|
||||
assert_eq!(EDIT_INDEXER_BLOCKS.len(), 11);
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerPrompt));
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerConfirmPrompt));
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerApiKeyInput));
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerNameInput));
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerSeedRatioInput));
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerToggleEnableRss));
|
||||
assert!(
|
||||
EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch)
|
||||
);
|
||||
assert!(
|
||||
EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch)
|
||||
);
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerPriorityInput));
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerUrlInput));
|
||||
assert!(EDIT_INDEXER_BLOCKS.contains(&ActiveReadarrBlock::EditIndexerTagsInput));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_indexer_torrent_selection_blocks_ordering() {
|
||||
let mut edit_indexer_block_iter = EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerNameInput,
|
||||
ActiveReadarrBlock::EditIndexerUrlInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableRss,
|
||||
ActiveReadarrBlock::EditIndexerApiKeyInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch,
|
||||
ActiveReadarrBlock::EditIndexerSeedRatioInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch,
|
||||
ActiveReadarrBlock::EditIndexerTagsInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerPriorityInput,
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt
|
||||
]
|
||||
);
|
||||
assert_none!(edit_indexer_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edit_indexer_nzb_selection_blocks_ordering() {
|
||||
let mut edit_indexer_block_iter = EDIT_INDEXER_NZB_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerNameInput,
|
||||
ActiveReadarrBlock::EditIndexerUrlInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableRss,
|
||||
ActiveReadarrBlock::EditIndexerApiKeyInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch,
|
||||
ActiveReadarrBlock::EditIndexerTagsInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch,
|
||||
ActiveReadarrBlock::EditIndexerPriorityInput
|
||||
]
|
||||
);
|
||||
assert_eq!(
|
||||
edit_indexer_block_iter.next().unwrap(),
|
||||
&[
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt,
|
||||
ActiveReadarrBlock::EditIndexerConfirmPrompt
|
||||
]
|
||||
);
|
||||
assert_none!(edit_indexer_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_indexer_settings_blocks_contents() {
|
||||
assert_eq!(INDEXER_SETTINGS_BLOCKS.len(), 6);
|
||||
assert!(INDEXER_SETTINGS_BLOCKS.contains(&ActiveReadarrBlock::AllIndexerSettingsPrompt));
|
||||
assert!(INDEXER_SETTINGS_BLOCKS.contains(&ActiveReadarrBlock::IndexerSettingsConfirmPrompt));
|
||||
assert!(INDEXER_SETTINGS_BLOCKS.contains(&ActiveReadarrBlock::IndexerSettingsMaximumSizeInput));
|
||||
assert!(INDEXER_SETTINGS_BLOCKS.contains(&ActiveReadarrBlock::IndexerSettingsMinimumAgeInput));
|
||||
assert!(INDEXER_SETTINGS_BLOCKS.contains(&ActiveReadarrBlock::IndexerSettingsRetentionInput));
|
||||
assert!(
|
||||
INDEXER_SETTINGS_BLOCKS.contains(&ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_indexer_settings_selection_blocks_ordering() {
|
||||
let mut indexer_settings_block_iter = INDEXER_SETTINGS_SELECTION_BLOCKS.iter();
|
||||
|
||||
assert_eq!(
|
||||
indexer_settings_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::IndexerSettingsMinimumAgeInput]
|
||||
);
|
||||
assert_eq!(
|
||||
indexer_settings_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::IndexerSettingsRetentionInput]
|
||||
);
|
||||
assert_eq!(
|
||||
indexer_settings_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::IndexerSettingsMaximumSizeInput]
|
||||
);
|
||||
assert_eq!(
|
||||
indexer_settings_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput]
|
||||
);
|
||||
assert_eq!(
|
||||
indexer_settings_block_iter.next().unwrap(),
|
||||
&[ActiveReadarrBlock::IndexerSettingsConfirmPrompt]
|
||||
);
|
||||
assert_none!(indexer_settings_block_iter.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_indexers_blocks_contents() {
|
||||
assert_eq!(INDEXERS_BLOCKS.len(), 3);
|
||||
assert!(INDEXERS_BLOCKS.contains(&ActiveReadarrBlock::Indexers));
|
||||
assert!(INDEXERS_BLOCKS.contains(&ActiveReadarrBlock::DeleteIndexerPrompt));
|
||||
assert!(INDEXERS_BLOCKS.contains(&ActiveReadarrBlock::TestIndexer));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_indexers_blocks_excludes_test_all_indexers() {
|
||||
assert!(!INDEXERS_BLOCKS.contains(&ActiveReadarrBlock::TestAllIndexers));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_system_details_blocks_contents() {
|
||||
assert_eq!(SYSTEM_DETAILS_BLOCKS.len(), 5);
|
||||
assert!(SYSTEM_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SystemLogs));
|
||||
assert!(SYSTEM_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SystemQueuedEvents));
|
||||
assert!(SYSTEM_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SystemTasks));
|
||||
assert!(SYSTEM_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SystemTaskStartConfirmPrompt));
|
||||
assert!(SYSTEM_DETAILS_BLOCKS.contains(&ActiveReadarrBlock::SystemUpdates));
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user