feat(readarr): scroll and dismiss the edition details popup
Add EditionDetailsHandler, the single block popup opened from the editions table. It owns the arrow, Home and End scrolling over its ScrollableText body, and the Esc that pops the popup and clears the edition details modal. The handler is nested under BookDetailsHandler, which claims the block ahead of its own tables. It never sees the keypress that opens it, so it performs no build, and it dispatches no network events: the popup is assembled from an already loaded row. Scrolling is implemented rather than stubbed. The body is mostly the edition overview, which routinely overflows the popup, so empty scroll methods would leave the arrow keys dead on the longest text in the view.
This commit is contained in:
6 files changed
+577
-4
No files matched your search
@@ -13,6 +13,7 @@ use crate::network::readarr_network::ReadarrEvent;
|
||||
use indoc::formatdoc;
|
||||
|
||||
use super::author_details_handler::releases_sorting_options;
|
||||
use super::edition_details_handler::EditionDetailsHandler;
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "book_details_handler_tests.rs"]
|
||||
@@ -133,6 +134,16 @@ impl BookDetailsHandler<'_, '_> {
|
||||
|
||||
impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveReadarrBlock> for BookDetailsHandler<'a, 'b> {
|
||||
fn handle(&mut self) {
|
||||
if EditionDetailsHandler::accepts(self.active_readarr_block) {
|
||||
return EditionDetailsHandler::new(
|
||||
self.key,
|
||||
self.app,
|
||||
self.active_readarr_block,
|
||||
self._context,
|
||||
)
|
||||
.handle();
|
||||
}
|
||||
|
||||
let editions_table_handling_config =
|
||||
TableHandlingConfig::new(ActiveReadarrBlock::BookDetails.into())
|
||||
.searching_block(ActiveReadarrBlock::SearchEditions.into())
|
||||
@@ -197,7 +208,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveReadarrBlock> for BookDetailsHandler<
|
||||
}
|
||||
|
||||
fn accepts(active_block: ActiveReadarrBlock) -> bool {
|
||||
BOOK_DETAILS_BLOCKS.contains(&active_block)
|
||||
EditionDetailsHandler::accepts(active_block) || BOOK_DETAILS_BLOCKS.contains(&active_block)
|
||||
}
|
||||
|
||||
fn ignore_special_keys(&self) -> bool {
|
||||
|
||||
@@ -13,9 +13,10 @@ mod tests {
|
||||
};
|
||||
use crate::models::servarr_data::readarr::modals::BookDetailsModal;
|
||||
use crate::models::servarr_data::readarr::readarr_data::{
|
||||
ActiveReadarrBlock, BOOK_DETAILS_BLOCKS,
|
||||
ActiveReadarrBlock, BOOK_DETAILS_BLOCKS, EDITION_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::models::servarr_models::{Quality, QualityWrapper};
|
||||
use crate::test_handler_delegation;
|
||||
|
||||
mod test_handle_scroll_up_and_down {
|
||||
use super::*;
|
||||
@@ -866,8 +867,12 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn test_book_details_handler_accepts() {
|
||||
let mut book_details_handler_blocks = Vec::new();
|
||||
book_details_handler_blocks.extend(BOOK_DETAILS_BLOCKS);
|
||||
book_details_handler_blocks.extend(EDITION_DETAILS_BLOCKS);
|
||||
|
||||
ActiveReadarrBlock::iter().for_each(|active_readarr_block| {
|
||||
if BOOK_DETAILS_BLOCKS.contains(&active_readarr_block) {
|
||||
if book_details_handler_blocks.contains(&active_readarr_block) {
|
||||
assert!(
|
||||
BookDetailsHandler::accepts(active_readarr_block),
|
||||
"{active_readarr_block} is not accepted by the BookDetailsHandler"
|
||||
@@ -881,6 +886,15 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delegates_edition_details_blocks_to_edition_details_handler() {
|
||||
test_handler_delegation!(
|
||||
BookDetailsHandler,
|
||||
ActiveReadarrBlock::BookDetails,
|
||||
ActiveReadarrBlock::BookEditionDetails
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_book_details_handler_is_not_ready_when_loading() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
use crate::app::App;
|
||||
use crate::event::Key;
|
||||
use crate::handlers::KeyEventHandler;
|
||||
use crate::matches_key;
|
||||
use crate::models::servarr_data::readarr::readarr_data::{
|
||||
ActiveReadarrBlock, EDITION_DETAILS_BLOCKS,
|
||||
};
|
||||
use crate::models::{Route, Scrollable, ScrollableText};
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "edition_details_handler_tests.rs"]
|
||||
mod edition_details_handler_tests;
|
||||
|
||||
pub(super) struct EditionDetailsHandler<'a, 'b> {
|
||||
key: Key,
|
||||
app: &'a mut App<'b>,
|
||||
active_readarr_block: ActiveReadarrBlock,
|
||||
_context: Option<ActiveReadarrBlock>,
|
||||
}
|
||||
|
||||
impl EditionDetailsHandler<'_, '_> {
|
||||
fn edition_details(&mut self) -> &mut ScrollableText {
|
||||
&mut self
|
||||
.app
|
||||
.data
|
||||
.readarr_data
|
||||
.book_details_modal
|
||||
.as_mut()
|
||||
.expect("Book details modal is undefined")
|
||||
.edition_details_modal
|
||||
.as_mut()
|
||||
.expect("Edition details modal is undefined")
|
||||
.edition_details
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveReadarrBlock> for EditionDetailsHandler<'a, 'b> {
|
||||
fn accepts(active_block: ActiveReadarrBlock) -> bool {
|
||||
EDITION_DETAILS_BLOCKS.contains(&active_block)
|
||||
}
|
||||
|
||||
fn ignore_special_keys(&self) -> bool {
|
||||
self.app.ignore_special_keys_for_textbox_input
|
||||
}
|
||||
|
||||
fn new(
|
||||
key: Key,
|
||||
app: &'a mut App<'b>,
|
||||
active_block: ActiveReadarrBlock,
|
||||
_context: Option<ActiveReadarrBlock>,
|
||||
) -> EditionDetailsHandler<'a, 'b> {
|
||||
EditionDetailsHandler {
|
||||
key,
|
||||
app,
|
||||
active_readarr_block: active_block,
|
||||
_context,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_key(&self) -> Key {
|
||||
self.key
|
||||
}
|
||||
|
||||
fn is_ready(&self) -> bool {
|
||||
if self.app.is_loading {
|
||||
return false;
|
||||
}
|
||||
|
||||
let Some(book_details_modal) = &self.app.data.readarr_data.book_details_modal else {
|
||||
return false;
|
||||
};
|
||||
|
||||
book_details_modal.edition_details_modal.is_some()
|
||||
}
|
||||
|
||||
fn handle_scroll_up(&mut self) {
|
||||
self.edition_details().scroll_up();
|
||||
}
|
||||
|
||||
fn handle_scroll_down(&mut self) {
|
||||
self.edition_details().scroll_down();
|
||||
}
|
||||
|
||||
fn handle_home(&mut self) {
|
||||
self.edition_details().scroll_to_top();
|
||||
}
|
||||
|
||||
fn handle_end(&mut self) {
|
||||
self.edition_details().scroll_to_bottom();
|
||||
}
|
||||
|
||||
fn handle_delete(&mut self) {}
|
||||
|
||||
fn handle_left_right_action(&mut self) {}
|
||||
|
||||
fn handle_submit(&mut self) {}
|
||||
|
||||
fn handle_esc(&mut self) {
|
||||
self.app.pop_navigation_stack();
|
||||
self
|
||||
.app
|
||||
.data
|
||||
.readarr_data
|
||||
.book_details_modal
|
||||
.as_mut()
|
||||
.expect("Book details modal is undefined")
|
||||
.edition_details_modal = None;
|
||||
}
|
||||
|
||||
fn handle_char_key_event(&mut self) {
|
||||
if matches_key!(refresh, self.key) {
|
||||
self
|
||||
.app
|
||||
.pop_and_push_navigation_stack(self.active_readarr_block.into());
|
||||
}
|
||||
}
|
||||
|
||||
fn app_mut(&mut self) -> &mut App<'b> {
|
||||
self.app
|
||||
}
|
||||
|
||||
fn current_route(&self) -> Route {
|
||||
self.app.get_current_route()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
use crate::app::App;
|
||||
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
|
||||
use crate::handlers::KeyEventHandler;
|
||||
use crate::handlers::readarr_handlers::library::edition_details_handler::EditionDetailsHandler;
|
||||
use crate::models::ScrollableText;
|
||||
use crate::models::servarr_data::readarr::modals::{BookDetailsModal, EditionDetailsModal};
|
||||
use crate::models::servarr_data::readarr::readarr_data::{
|
||||
ActiveReadarrBlock, EDITION_DETAILS_BLOCKS,
|
||||
};
|
||||
|
||||
mod test_handle_scroll_up_and_down {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_scroll_down() {
|
||||
let mut app = app_with_edition_details();
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.down.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_scroll_up() {
|
||||
let mut app = app_with_edition_details();
|
||||
set_offset(&mut app, 2);
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_scroll_down_no_op_when_not_ready() {
|
||||
let mut app = app_with_edition_details();
|
||||
app.is_loading = true;
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.down.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_scroll_up_no_op_when_not_ready() {
|
||||
let mut app = app_with_edition_details();
|
||||
set_offset(&mut app, 2);
|
||||
app.is_loading = true;
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_scrolls_past_the_first_screen() {
|
||||
let mut app = app_with_edition_details();
|
||||
|
||||
for _ in 0..4 {
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.down.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
}
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 4);
|
||||
}
|
||||
}
|
||||
|
||||
mod test_handle_home_end {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_end() {
|
||||
let mut app = app_with_edition_details();
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.end.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 5);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_home() {
|
||||
let mut app = app_with_edition_details();
|
||||
set_offset(&mut app, 4);
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.home.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_end_no_op_when_not_ready() {
|
||||
let mut app = app_with_edition_details();
|
||||
app.is_loading = true;
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.end.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_home_no_op_when_not_ready() {
|
||||
let mut app = app_with_edition_details();
|
||||
set_offset(&mut app, 4);
|
||||
app.is_loading = true;
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.home.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_eq!(edition_details_offset(&app), 4);
|
||||
}
|
||||
}
|
||||
|
||||
mod test_handle_esc {
|
||||
use super::*;
|
||||
use crate::{assert_modal_absent, assert_modal_present, assert_navigation_popped};
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_esc_tears_down_the_edition_details_modal() {
|
||||
let mut app = app_with_edition_details();
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_navigation_popped!(app, ActiveReadarrBlock::BookDetails.into());
|
||||
assert_modal_absent!(
|
||||
app
|
||||
.data
|
||||
.readarr_data
|
||||
.book_details_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.edition_details_modal
|
||||
);
|
||||
assert_modal_present!(app.data.readarr_data.book_details_modal);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_esc_tears_down_the_modal_even_when_loading() {
|
||||
let mut app = app_with_edition_details();
|
||||
app.is_loading = true;
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.esc.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_navigation_popped!(app, ActiveReadarrBlock::BookDetails.into());
|
||||
assert_modal_absent!(
|
||||
app
|
||||
.data
|
||||
.readarr_data
|
||||
.book_details_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.edition_details_modal
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
mod test_handle_key_char {
|
||||
use super::*;
|
||||
use crate::assert_navigation_pushed;
|
||||
|
||||
#[test]
|
||||
fn test_refresh_key() {
|
||||
let mut app = app_with_edition_details();
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.refresh.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_navigation_pushed!(app, ActiveReadarrBlock::BookEditionDetails.into());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_refresh_key_no_op_when_not_ready() {
|
||||
let mut app = app_with_edition_details();
|
||||
app.is_loading = true;
|
||||
app.push_navigation_stack(ActiveReadarrBlock::BookHistory.into());
|
||||
|
||||
EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.refresh.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
)
|
||||
.handle();
|
||||
|
||||
assert_navigation_pushed!(app, ActiveReadarrBlock::BookHistory.into());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_handler_accepts() {
|
||||
ActiveReadarrBlock::iter().for_each(|active_readarr_block| {
|
||||
if EDITION_DETAILS_BLOCKS.contains(&active_readarr_block) {
|
||||
assert!(
|
||||
EditionDetailsHandler::accepts(active_readarr_block),
|
||||
"{active_readarr_block} is not accepted by the EditionDetailsHandler"
|
||||
);
|
||||
} else {
|
||||
assert!(
|
||||
!EditionDetailsHandler::accepts(active_readarr_block),
|
||||
"{active_readarr_block} is wrongly accepted by the EditionDetailsHandler"
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_handler_dispatches_no_network_events() {
|
||||
let mut app = app_with_edition_details();
|
||||
|
||||
for key in [
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
DEFAULT_KEYBINDINGS.down.key,
|
||||
DEFAULT_KEYBINDINGS.home.key,
|
||||
DEFAULT_KEYBINDINGS.end.key,
|
||||
DEFAULT_KEYBINDINGS.delete.key,
|
||||
DEFAULT_KEYBINDINGS.left.key,
|
||||
DEFAULT_KEYBINDINGS.right.key,
|
||||
DEFAULT_KEYBINDINGS.submit.key,
|
||||
DEFAULT_KEYBINDINGS.refresh.key,
|
||||
] {
|
||||
EditionDetailsHandler::new(key, &mut app, ActiveReadarrBlock::BookEditionDetails, None)
|
||||
.handle();
|
||||
|
||||
assert_none!(app.data.readarr_data.prompt_confirm_action);
|
||||
assert!(!app.data.readarr_data.prompt_confirm);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_handler_is_not_ready_when_loading() {
|
||||
let mut app = app_with_edition_details();
|
||||
app.is_loading = true;
|
||||
|
||||
let handler = EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
);
|
||||
|
||||
assert!(!handler.is_ready());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_handler_is_not_ready_when_the_book_details_modal_is_absent() {
|
||||
let mut app = App::test_default();
|
||||
|
||||
let handler = EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
);
|
||||
|
||||
assert!(!handler.is_ready());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_handler_is_not_ready_when_the_edition_details_modal_is_absent() {
|
||||
let mut app = App::test_default();
|
||||
app.data.readarr_data.book_details_modal = Some(BookDetailsModal::default());
|
||||
|
||||
let handler = EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
);
|
||||
|
||||
assert!(!handler.is_ready());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_handler_is_ready() {
|
||||
let mut app = app_with_edition_details();
|
||||
|
||||
let handler = EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
);
|
||||
|
||||
assert!(handler.is_ready());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_edition_details_handler_ignores_special_keys_for_textbox_input() {
|
||||
let mut app = app_with_edition_details();
|
||||
app.ignore_special_keys_for_textbox_input = true;
|
||||
|
||||
let handler = EditionDetailsHandler::new(
|
||||
DEFAULT_KEYBINDINGS.up.key,
|
||||
&mut app,
|
||||
ActiveReadarrBlock::BookEditionDetails,
|
||||
None,
|
||||
);
|
||||
|
||||
assert!(handler.ignore_special_keys());
|
||||
}
|
||||
|
||||
fn app_with_edition_details() -> App<'static> {
|
||||
let mut app = App::test_default();
|
||||
let book_details_modal = BookDetailsModal {
|
||||
edition_details_modal: Some(EditionDetailsModal {
|
||||
edition_details: ScrollableText::with_string(
|
||||
"Title: Test Edition\nFormat: Paperback\nLanguage: eng\nPublisher: Test\nPage Count: 662\nOverview: A long overview"
|
||||
.to_owned(),
|
||||
),
|
||||
}),
|
||||
..BookDetailsModal::default()
|
||||
};
|
||||
app.data.readarr_data.book_details_modal = Some(book_details_modal);
|
||||
app.push_navigation_stack(ActiveReadarrBlock::BookDetails.into());
|
||||
app.push_navigation_stack(ActiveReadarrBlock::BookEditionDetails.into());
|
||||
|
||||
app
|
||||
}
|
||||
|
||||
fn edition_details_offset(app: &App<'_>) -> u16 {
|
||||
app
|
||||
.data
|
||||
.readarr_data
|
||||
.book_details_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.edition_details_modal
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.edition_details
|
||||
.offset
|
||||
}
|
||||
|
||||
fn set_offset(app: &mut App<'_>, offset: u16) {
|
||||
app
|
||||
.data
|
||||
.readarr_data
|
||||
.book_details_modal
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.edition_details_modal
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.edition_details
|
||||
.offset = offset;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,8 @@ mod tests {
|
||||
use crate::models::HorizontallyScrollableText;
|
||||
use crate::models::readarr_models::{Author, AuthorStatistics, AuthorStatus};
|
||||
use crate::models::servarr_data::readarr::readarr_data::{
|
||||
AUTHOR_DETAILS_BLOCKS, ActiveReadarrBlock, BOOK_DETAILS_BLOCKS, LIBRARY_BLOCKS,
|
||||
AUTHOR_DETAILS_BLOCKS, ActiveReadarrBlock, BOOK_DETAILS_BLOCKS, EDITION_DETAILS_BLOCKS,
|
||||
LIBRARY_BLOCKS,
|
||||
};
|
||||
use crate::test_handler_delegation;
|
||||
|
||||
@@ -894,6 +895,7 @@ mod tests {
|
||||
library_handler_blocks.extend(LIBRARY_BLOCKS);
|
||||
library_handler_blocks.extend(AUTHOR_DETAILS_BLOCKS);
|
||||
library_handler_blocks.extend(BOOK_DETAILS_BLOCKS);
|
||||
library_handler_blocks.extend(EDITION_DETAILS_BLOCKS);
|
||||
|
||||
ActiveReadarrBlock::iter().for_each(|readarr_block| {
|
||||
if library_handler_blocks.contains(&readarr_block) {
|
||||
|
||||
@@ -21,6 +21,7 @@ use crate::models::Route;
|
||||
|
||||
mod author_details_handler;
|
||||
mod book_details_handler;
|
||||
mod edition_details_handler;
|
||||
|
||||
pub(in crate::handlers::readarr_handlers) use {
|
||||
author_details_handler::AuthorDetailsHandler, book_details_handler::BookDetailsHandler,
|
||||
|
||||
Reference in new issue
Block a user