From 59346973fcbf90c8d15209437514404a4f347e43 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Tue, 8 Sep 2026 10:38:52 -0600 Subject: [PATCH] feat(readarr): add the indexers UI Render the indexers table with its delete and test popups, the edit indexer prompt with separate torrent and usenet field grids, the prompt for configuring all indexer settings, and the test all indexers results table. All four are dispatched from the Readarr UI. Extract indexer_flag_text, decorate_test_result_row_with_style and the two prompt highlight builders as named functions so their branches can be unit tested. Rendering to a string discards colour, so a snapshot cannot tell a success style from a failure style. --- src/ui/readarr_ui/indexers/edit_indexer_ui.rs | 202 ++++++++++++ .../indexers/edit_indexer_ui_tests.rs | 305 ++++++++++++++++++ .../indexers/indexer_settings_ui.rs | 139 ++++++++ .../indexers/indexer_settings_ui_tests.rs | 162 ++++++++++ .../readarr_ui/indexers/indexers_ui_tests.rs | 266 +++++++++++++++ src/ui/readarr_ui/indexers/mod.rs | 182 +++++++++++ ...ndexer_torrent_EditIndexerApiKeyInput.snap | 42 +++ ...exer_torrent_EditIndexerConfirmPrompt.snap | 42 +++ ..._indexer_torrent_EditIndexerNameInput.snap | 42 +++ ...exer_torrent_EditIndexerPriorityInput.snap | 42 +++ ...dit_indexer_torrent_EditIndexerPrompt.snap | 42 +++ ...xer_torrent_EditIndexerSeedRatioInput.snap | 42 +++ ..._indexer_torrent_EditIndexerTagsInput.snap | 42 +++ ...ditIndexerToggleEnableAutomaticSearch.snap | 42 +++ ...tIndexerToggleEnableInteractiveSearch.snap | 42 +++ ...er_torrent_EditIndexerToggleEnableRss.snap | 42 +++ ...t_indexer_torrent_EditIndexerUrlInput.snap | 42 +++ ...ests__edit_indexer_ui_renders_loading.snap | 42 +++ ...__edit_indexer_ui_renders_usenet_grid.snap | 42 +++ ...xer_settings_AllIndexerSettingsPrompt.snap | 40 +++ ...settings_IndexerSettingsConfirmPrompt.snap | 40 +++ ...tings_IndexerSettingsMaximumSizeInput.snap | 40 +++ ...ttings_IndexerSettingsMinimumAgeInput.snap | 40 +++ ...ettings_IndexerSettingsRetentionInput.snap | 40 +++ ...s_IndexerSettingsRssSyncIntervalInput.snap | 40 +++ ...__indexer_settings_ui_renders_loading.snap | 40 +++ ...ests__indexers_ui_DeleteIndexerPrompt.snap | 38 +++ ..._snapshot_tests__indexers_ui_Indexers.snap | 8 + ...apshot_tests__indexers_ui_TestIndexer.snap | 35 ++ ...lete_prompt_for_non_default_selection.snap | 38 +++ ...rs_edit_torrent_indexer_over_indexers.snap | 42 +++ ...ers_edit_usenet_indexer_over_indexers.snap | 42 +++ ...s__indexers_ui_renders_empty_indexers.snap | 5 + ...enders_indexer_settings_over_indexers.snap | 40 +++ ...ot_tests__indexers_ui_renders_loading.snap | 8 + ...exers_ui_renders_loading_test_results.snap | 35 ++ ...ults_when_indexer_test_errors_is_none.snap | 35 ++ ...nders_test_all_indexers_over_indexers.snap | 48 +++ ...exer_success_when_there_are_no_errors.snap | 31 ++ ...t_tests__test_all_indexers_ui_renders.snap | 48 +++ ...all_indexers_ui_renders_empty_results.snap | 48 +++ ..._ui_renders_for_non_default_selection.snap | 48 +++ ..._test_all_indexers_ui_renders_loading.snap | 48 +++ ...renders_loading_when_results_are_none.snap | 48 +++ .../indexers/test_all_indexers_ui.rs | 86 +++++ .../indexers/test_all_indexers_ui_tests.rs | 156 +++++++++ src/ui/readarr_ui/mod.rs | 3 + ...snapshot_tests__readarr_tabs_Indexers.snap | 6 +- 48 files changed, 2975 insertions(+), 3 deletions(-) create mode 100644 src/ui/readarr_ui/indexers/edit_indexer_ui.rs create mode 100644 src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs create mode 100644 src/ui/readarr_ui/indexers/indexer_settings_ui.rs create mode 100644 src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs create mode 100644 src/ui/readarr_ui/indexers/indexers_ui_tests.rs create mode 100644 src/ui/readarr_ui/indexers/mod.rs create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerApiKeyInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerConfirmPrompt.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerNameInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPriorityInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPrompt.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerSeedRatioInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerTagsInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableAutomaticSearch.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableInteractiveSearch.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableRss.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerUrlInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_loading.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_usenet_grid.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_AllIndexerSettingsPrompt.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsConfirmPrompt.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMaximumSizeInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMinimumAgeInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRetentionInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRssSyncIntervalInput.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_loading.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_DeleteIndexerPrompt.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_Indexers.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_TestIndexer.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_delete_prompt_for_non_default_selection.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_torrent_indexer_over_indexers.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_usenet_indexer_over_indexers.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_indexer_settings_over_indexers.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results_when_indexer_test_errors_is_none.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_all_indexers_over_indexers.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_indexer_success_when_there_are_no_errors.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_empty_results.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_for_non_default_selection.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading.snap create mode 100644 src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_when_results_are_none.snap create mode 100644 src/ui/readarr_ui/indexers/test_all_indexers_ui.rs create mode 100644 src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs diff --git a/src/ui/readarr_ui/indexers/edit_indexer_ui.rs b/src/ui/readarr_ui/indexers/edit_indexer_ui.rs new file mode 100644 index 00000000..353adf31 --- /dev/null +++ b/src/ui/readarr_ui/indexers/edit_indexer_ui.rs @@ -0,0 +1,202 @@ +use std::sync::atomic::Ordering; + +use crate::app::App; +use crate::models::Route; +use crate::models::servarr_data::readarr::readarr_data::{ActiveReadarrBlock, EDIT_INDEXER_BLOCKS}; +use crate::render_selectable_input_box; +use crate::ui::utils::title_block_centered; +use crate::ui::widgets::button::Button; +use crate::ui::widgets::checkbox::Checkbox; +use crate::ui::widgets::input_box::InputBox; +use crate::ui::widgets::loading_block::LoadingBlock; +use crate::ui::widgets::popup::Size; +use crate::ui::{DrawUi, draw_popup}; +use ratatui::Frame; +use ratatui::layout::{Constraint, Flex, Layout, Rect}; + +#[cfg(test)] +#[path = "edit_indexer_ui_tests.rs"] +mod edit_indexer_ui_tests; + +pub(super) struct EditIndexerUi; + +impl DrawUi for EditIndexerUi { + fn accepts(route: Route) -> bool { + let Route::Readarr(active_readarr_block, _) = route else { + return false; + }; + EDIT_INDEXER_BLOCKS.contains(&active_readarr_block) + } + + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup(f, app, draw_edit_indexer_prompt, Size::WideLargePrompt); + } +} + +#[derive(PartialEq, Eq)] +#[cfg_attr(test, derive(Debug))] +struct EditIndexerPromptHighlights { + name: bool, + url: bool, + api_key: bool, + seed_ratio: bool, + tags: bool, + priority: bool, + rss: bool, + automatic_search: bool, + interactive_search: bool, + confirm: bool, +} + +fn edit_indexer_prompt_highlights( + selected_block: ActiveReadarrBlock, +) -> EditIndexerPromptHighlights { + EditIndexerPromptHighlights { + name: selected_block == ActiveReadarrBlock::EditIndexerNameInput, + url: selected_block == ActiveReadarrBlock::EditIndexerUrlInput, + api_key: selected_block == ActiveReadarrBlock::EditIndexerApiKeyInput, + seed_ratio: selected_block == ActiveReadarrBlock::EditIndexerSeedRatioInput, + tags: selected_block == ActiveReadarrBlock::EditIndexerTagsInput, + priority: selected_block == ActiveReadarrBlock::EditIndexerPriorityInput, + rss: selected_block == ActiveReadarrBlock::EditIndexerToggleEnableRss, + automatic_search: selected_block == ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch, + interactive_search: selected_block + == ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch, + confirm: selected_block == ActiveReadarrBlock::EditIndexerConfirmPrompt, + } +} + +fn draw_edit_indexer_prompt(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + let block = title_block_centered("Edit Indexer"); + let yes_no_value = app.data.readarr_data.prompt_confirm; + let selected_block = app.data.readarr_data.selected_block.get_active_block(); + let highlights = edit_indexer_prompt_highlights(selected_block); + let edit_indexer_modal_option = &app.data.readarr_data.edit_indexer_modal; + let protocol = &app.data.readarr_data.indexers.current_selection().protocol; + + if edit_indexer_modal_option.is_some() { + f.render_widget(block, area); + let edit_indexer_modal = edit_indexer_modal_option.as_ref().unwrap(); + + let [settings_area, buttons_area] = + Layout::vertical([Constraint::Fill(1), Constraint::Length(3)]) + .margin(1) + .areas(area); + let [left_side_area, right_side_area] = + Layout::horizontal([Constraint::Ratio(1, 2), Constraint::Ratio(1, 2)]) + .margin(1) + .areas(settings_area); + let [ + name_area, + rss_area, + auto_search_area, + interactive_search_area, + priority_area, + ] = Layout::vertical([ + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + ]) + .areas(left_side_area); + let [url_area, api_key_area, seed_ratio_area, tags_area] = Layout::vertical([ + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + ]) + .areas(right_side_area); + + if let Route::Readarr(active_readarr_block, _) = app.get_current_route() { + let priority = edit_indexer_modal.priority.to_string(); + let name_input_box = InputBox::new(&edit_indexer_modal.name.text) + .offset(edit_indexer_modal.name.offset.load(Ordering::SeqCst)) + .label("Name") + .highlighted(highlights.name) + .selected(active_readarr_block == ActiveReadarrBlock::EditIndexerNameInput); + let url_input_box = InputBox::new(&edit_indexer_modal.url.text) + .offset(edit_indexer_modal.url.offset.load(Ordering::SeqCst)) + .label("URL") + .highlighted(highlights.url) + .selected(active_readarr_block == ActiveReadarrBlock::EditIndexerUrlInput); + let api_key_input_box = InputBox::new(&edit_indexer_modal.api_key.text) + .offset(edit_indexer_modal.api_key.offset.load(Ordering::SeqCst)) + .label("API Key") + .highlighted(highlights.api_key) + .selected(active_readarr_block == ActiveReadarrBlock::EditIndexerApiKeyInput); + let tags_input_box = InputBox::new(&edit_indexer_modal.tags.text) + .offset(edit_indexer_modal.tags.offset.load(Ordering::SeqCst)) + .label("Tags") + .highlighted(highlights.tags) + .selected(active_readarr_block == ActiveReadarrBlock::EditIndexerTagsInput); + let priority_input_box = InputBox::new(&priority) + .cursor_after_string(false) + .label("Indexer Priority ▴▾") + .highlighted(highlights.priority) + .selected(active_readarr_block == ActiveReadarrBlock::EditIndexerPriorityInput); + + render_selectable_input_box!(name_input_box, f, name_area); + render_selectable_input_box!(url_input_box, f, url_area); + render_selectable_input_box!(api_key_input_box, f, api_key_area); + + if protocol == "torrent" { + let seed_ratio_input_box = InputBox::new(&edit_indexer_modal.seed_ratio.text) + .offset(edit_indexer_modal.seed_ratio.offset.load(Ordering::SeqCst)) + .label("Seed Ratio") + .highlighted(highlights.seed_ratio) + .selected(active_readarr_block == ActiveReadarrBlock::EditIndexerSeedRatioInput); + let tags_input_box = InputBox::new(&edit_indexer_modal.tags.text) + .offset(edit_indexer_modal.tags.offset.load(Ordering::SeqCst)) + .label("Tags") + .highlighted(highlights.tags) + .selected(active_readarr_block == ActiveReadarrBlock::EditIndexerTagsInput); + + render_selectable_input_box!(seed_ratio_input_box, f, seed_ratio_area); + render_selectable_input_box!(tags_input_box, f, tags_area); + render_selectable_input_box!(priority_input_box, f, priority_area); + } else { + render_selectable_input_box!(tags_input_box, f, seed_ratio_area); + render_selectable_input_box!(priority_input_box, f, tags_area); + } + + let rss_checkbox = Checkbox::new("Enable RSS") + .checked(edit_indexer_modal.enable_rss.unwrap_or_default()) + .highlighted(highlights.rss); + let auto_search_checkbox = Checkbox::new("Enable Automatic Search") + .checked( + edit_indexer_modal + .enable_automatic_search + .unwrap_or_default(), + ) + .highlighted(highlights.automatic_search); + let interactive_search_checkbox = Checkbox::new("Enable Interactive Search") + .checked( + edit_indexer_modal + .enable_interactive_search + .unwrap_or_default(), + ) + .highlighted(highlights.interactive_search); + + let [save_area, cancel_area] = + Layout::horizontal([Constraint::Percentage(25), Constraint::Percentage(25)]) + .flex(Flex::Center) + .areas(buttons_area); + + let save_button = Button::default() + .title("Save") + .selected(yes_no_value && highlights.confirm); + let cancel_button = Button::default() + .title("Cancel") + .selected(!yes_no_value && highlights.confirm); + + f.render_widget(rss_checkbox, rss_area); + f.render_widget(auto_search_checkbox, auto_search_area); + f.render_widget(interactive_search_checkbox, interactive_search_area); + f.render_widget(save_button, save_area); + f.render_widget(cancel_button, cancel_area); + } + } else { + f.render_widget(LoadingBlock::new(app.is_loading, block), area); + } +} diff --git a/src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs b/src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs new file mode 100644 index 00000000..c2b300ef --- /dev/null +++ b/src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs @@ -0,0 +1,305 @@ +#[cfg(test)] +mod tests { + use pretty_assertions::assert_eq; + use rstest::rstest; + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::servarr_data::readarr::readarr_data::{ + ActiveReadarrBlock, EDIT_INDEXER_BLOCKS, + }; + use crate::ui::DrawUi; + use crate::ui::readarr_ui::indexers::edit_indexer_ui::{ + EditIndexerPromptHighlights, EditIndexerUi, edit_indexer_prompt_highlights, + }; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; + + #[test] + fn test_edit_indexer_ui_accepts() { + ActiveReadarrBlock::iter().for_each(|active_readarr_block| { + if EDIT_INDEXER_BLOCKS.contains(&active_readarr_block) { + assert!(EditIndexerUi::accepts(active_readarr_block.into())); + } else { + assert!(!EditIndexerUi::accepts(active_readarr_block.into())); + } + }); + } + + #[rstest] + #[case( + ActiveReadarrBlock::EditIndexerNameInput, + EditIndexerPromptHighlights { + name: true, + url: false, + api_key: false, + seed_ratio: false, + tags: false, + priority: false, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerUrlInput, + EditIndexerPromptHighlights { + name: false, + url: true, + api_key: false, + seed_ratio: false, + tags: false, + priority: false, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerApiKeyInput, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: true, + seed_ratio: false, + tags: false, + priority: false, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerSeedRatioInput, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: true, + tags: false, + priority: false, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerTagsInput, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: false, + tags: true, + priority: false, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerPriorityInput, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: false, + tags: false, + priority: true, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerToggleEnableRss, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: false, + tags: false, + priority: false, + rss: true, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: false, + tags: false, + priority: false, + rss: false, + automatic_search: true, + interactive_search: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: false, + tags: false, + priority: false, + rss: false, + automatic_search: false, + interactive_search: true, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerConfirmPrompt, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: false, + tags: false, + priority: false, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: true, + } + )] + #[case( + ActiveReadarrBlock::EditIndexerPrompt, + EditIndexerPromptHighlights { + name: false, + url: false, + api_key: false, + seed_ratio: false, + tags: false, + priority: false, + rss: false, + automatic_search: false, + interactive_search: false, + confirm: false, + } + )] + fn test_edit_indexer_prompt_highlights( + #[case] selected_block: ActiveReadarrBlock, + #[case] expected_highlights: EditIndexerPromptHighlights, + ) { + let highlights = edit_indexer_prompt_highlights(selected_block); + + assert_eq!(highlights, expected_highlights); + } + + mod snapshot_tests { + use crate::models::BlockSelectionState; + use crate::models::servarr_data::readarr::readarr_data::{ + EDIT_INDEXER_NZB_SELECTION_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, + }; + use crate::models::servarr_models::Indexer; + use crate::network::readarr_network::readarr_network_test_utils::test_utils::indexer; + use crate::ui::ui_test_utils::test_utils::TerminalSize; + + use super::*; + + fn seed_asymmetric_enable_flags( + app: &mut App<'_>, + enable_rss: bool, + enable_automatic_search: bool, + enable_interactive_search: bool, + ) { + let edit_indexer_modal = app + .data + .readarr_data + .edit_indexer_modal + .as_mut() + .expect("edit_indexer_modal must exist in this context"); + 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); + } + + fn seed_indexer_protocol(app: &mut App<'_>, protocol: &str) { + app.data.readarr_data.indexers.set_items(vec![Indexer { + protocol: protocol.to_owned(), + ..indexer() + }]); + } + + #[test] + fn test_edit_indexer_ui_renders_loading() { + let mut app = App::test_default_fully_populated(); + app.is_loading = true; + app.data.readarr_data.edit_indexer_modal = None; + app.data.readarr_data.selected_block = + BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); + app.push_navigation_stack(ActiveReadarrBlock::EditIndexerPrompt.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + EditIndexerUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[rstest] + #[case(ActiveReadarrBlock::EditIndexerPrompt, 0, 0)] + #[case(ActiveReadarrBlock::EditIndexerNameInput, 0, 0)] + #[case(ActiveReadarrBlock::EditIndexerUrlInput, 1, 0)] + #[case(ActiveReadarrBlock::EditIndexerToggleEnableRss, 0, 1)] + #[case(ActiveReadarrBlock::EditIndexerApiKeyInput, 1, 1)] + #[case(ActiveReadarrBlock::EditIndexerToggleEnableAutomaticSearch, 0, 2)] + #[case(ActiveReadarrBlock::EditIndexerSeedRatioInput, 1, 2)] + #[case(ActiveReadarrBlock::EditIndexerToggleEnableInteractiveSearch, 0, 3)] + #[case(ActiveReadarrBlock::EditIndexerTagsInput, 1, 3)] + #[case(ActiveReadarrBlock::EditIndexerPriorityInput, 0, 4)] + #[case(ActiveReadarrBlock::EditIndexerConfirmPrompt, 1, 4)] + fn test_edit_indexer_ui_renders_torrent_grid( + #[case] active_readarr_block: ActiveReadarrBlock, + #[case] x: usize, + #[case] y: usize, + ) { + let mut app = App::test_default_fully_populated(); + seed_asymmetric_enable_flags(&mut app, true, false, true); + seed_indexer_protocol(&mut app, "torrent"); + let mut selected_block = BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); + selected_block.set_index(x, y); + app.data.readarr_data.selected_block = selected_block; + app.push_navigation_stack(active_readarr_block.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + EditIndexerUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!( + format!("edit_indexer_torrent_{active_readarr_block}"), + output + ); + } + + #[test] + fn test_edit_indexer_ui_renders_usenet_grid() { + let mut app = App::test_default_fully_populated(); + seed_asymmetric_enable_flags(&mut app, false, true, true); + seed_indexer_protocol(&mut app, "usenet"); + app.data.readarr_data.selected_block = + BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS); + app.push_navigation_stack(ActiveReadarrBlock::EditIndexerPrompt.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + EditIndexerUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } +} diff --git a/src/ui/readarr_ui/indexers/indexer_settings_ui.rs b/src/ui/readarr_ui/indexers/indexer_settings_ui.rs new file mode 100644 index 00000000..3eca2f83 --- /dev/null +++ b/src/ui/readarr_ui/indexers/indexer_settings_ui.rs @@ -0,0 +1,139 @@ +use ratatui::Frame; +use ratatui::layout::{Constraint, Flex, Layout, Rect}; + +use crate::app::App; +use crate::models::Route; +use crate::models::servarr_data::readarr::readarr_data::{ + ActiveReadarrBlock, INDEXER_SETTINGS_BLOCKS, +}; +use crate::render_selectable_input_box; +use crate::ui::utils::title_block_centered; +use crate::ui::widgets::button::Button; +use crate::ui::widgets::input_box::InputBox; +use crate::ui::widgets::loading_block::LoadingBlock; +use crate::ui::widgets::popup::Size; +use crate::ui::{DrawUi, draw_popup}; + +#[cfg(test)] +#[path = "indexer_settings_ui_tests.rs"] +mod indexer_settings_ui_tests; + +pub(super) struct IndexerSettingsUi; + +impl DrawUi for IndexerSettingsUi { + fn accepts(route: Route) -> bool { + let Route::Readarr(active_readarr_block, _) = route else { + return false; + }; + INDEXER_SETTINGS_BLOCKS.contains(&active_readarr_block) + } + + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup(f, app, draw_edit_indexer_settings_prompt, Size::LargePrompt); + } +} + +#[derive(PartialEq, Eq)] +#[cfg_attr(test, derive(Debug))] +struct IndexerSettingsPromptHighlights { + minimum_age: bool, + retention: bool, + maximum_size: bool, + rss_sync_interval: bool, + confirm: bool, +} + +fn indexer_settings_prompt_highlights( + selected_block: ActiveReadarrBlock, +) -> IndexerSettingsPromptHighlights { + IndexerSettingsPromptHighlights { + minimum_age: selected_block == ActiveReadarrBlock::IndexerSettingsMinimumAgeInput, + retention: selected_block == ActiveReadarrBlock::IndexerSettingsRetentionInput, + maximum_size: selected_block == ActiveReadarrBlock::IndexerSettingsMaximumSizeInput, + rss_sync_interval: selected_block == ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput, + confirm: selected_block == ActiveReadarrBlock::IndexerSettingsConfirmPrompt, + } +} + +fn draw_edit_indexer_settings_prompt(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + let block = title_block_centered("Configure All Indexer Settings"); + let yes_no_value = app.data.readarr_data.prompt_confirm; + let selected_block = app.data.readarr_data.selected_block.get_active_block(); + let highlights = indexer_settings_prompt_highlights(selected_block); + let indexer_settings_option = &app.data.readarr_data.indexer_settings; + + if indexer_settings_option.is_some() { + f.render_widget(block, area); + let indexer_settings = indexer_settings_option.as_ref().unwrap(); + + let [ + _, + min_age_area, + retention_area, + max_size_area, + rss_sync_area, + _, + buttons_area, + ] = Layout::vertical([ + Constraint::Fill(1), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Length(3), + Constraint::Fill(1), + Constraint::Length(3), + ]) + .margin(1) + .areas(area); + + if let Route::Readarr(active_readarr_block, _) = app.get_current_route() { + let min_age = indexer_settings.minimum_age.to_string(); + let retention = indexer_settings.retention.to_string(); + let max_size = indexer_settings.maximum_size.to_string(); + let rss_sync_interval = indexer_settings.rss_sync_interval.to_string(); + + let min_age_text_box = InputBox::new(&min_age) + .cursor_after_string(false) + .label("Minimum Age (minutes) ▴▾") + .highlighted(highlights.minimum_age) + .selected(active_readarr_block == ActiveReadarrBlock::IndexerSettingsMinimumAgeInput); + let retention_input_box = InputBox::new(&retention) + .cursor_after_string(false) + .label("Retention (days) ▴▾") + .highlighted(highlights.retention) + .selected(active_readarr_block == ActiveReadarrBlock::IndexerSettingsRetentionInput); + let max_size_input_box = InputBox::new(&max_size) + .cursor_after_string(false) + .label("Maximum Size (MB) ▴▾") + .highlighted(highlights.maximum_size) + .selected(active_readarr_block == ActiveReadarrBlock::IndexerSettingsMaximumSizeInput); + let rss_sync_interval_input_box = InputBox::new(&rss_sync_interval) + .cursor_after_string(false) + .label("RSS Sync Interval (minutes) ▴▾") + .highlighted(highlights.rss_sync_interval) + .selected(active_readarr_block == ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput); + + render_selectable_input_box!(min_age_text_box, f, min_age_area); + render_selectable_input_box!(retention_input_box, f, retention_area); + render_selectable_input_box!(max_size_input_box, f, max_size_area); + render_selectable_input_box!(rss_sync_interval_input_box, f, rss_sync_area); + } + + let [save_area, cancel_area] = + Layout::horizontal([Constraint::Percentage(25), Constraint::Percentage(25)]) + .flex(Flex::Center) + .areas(buttons_area); + + let save_button = Button::default() + .title("Save") + .selected(yes_no_value && highlights.confirm); + let cancel_button = Button::default() + .title("Cancel") + .selected(!yes_no_value && highlights.confirm); + + f.render_widget(save_button, save_area); + f.render_widget(cancel_button, cancel_area); + } else { + f.render_widget(LoadingBlock::new(app.is_loading, block), area); + } +} diff --git a/src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs b/src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs new file mode 100644 index 00000000..992d26f1 --- /dev/null +++ b/src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs @@ -0,0 +1,162 @@ +#[cfg(test)] +mod tests { + use pretty_assertions::assert_eq; + use rstest::rstest; + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::servarr_data::readarr::readarr_data::{ + ActiveReadarrBlock, INDEXER_SETTINGS_BLOCKS, INDEXER_SETTINGS_SELECTION_BLOCKS, + }; + use crate::ui::DrawUi; + use crate::ui::readarr_ui::indexers::indexer_settings_ui::{ + IndexerSettingsPromptHighlights, IndexerSettingsUi, indexer_settings_prompt_highlights, + }; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; + + #[test] + fn test_indexer_settings_ui_accepts() { + ActiveReadarrBlock::iter().for_each(|active_readarr_block| { + if INDEXER_SETTINGS_BLOCKS.contains(&active_readarr_block) { + assert!(IndexerSettingsUi::accepts(active_readarr_block.into())); + } else { + assert!(!IndexerSettingsUi::accepts(active_readarr_block.into())); + } + }); + } + + #[rstest] + #[case( + ActiveReadarrBlock::IndexerSettingsMinimumAgeInput, + IndexerSettingsPromptHighlights { + minimum_age: true, + retention: false, + maximum_size: false, + rss_sync_interval: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::IndexerSettingsRetentionInput, + IndexerSettingsPromptHighlights { + minimum_age: false, + retention: true, + maximum_size: false, + rss_sync_interval: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::IndexerSettingsMaximumSizeInput, + IndexerSettingsPromptHighlights { + minimum_age: false, + retention: false, + maximum_size: true, + rss_sync_interval: false, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput, + IndexerSettingsPromptHighlights { + minimum_age: false, + retention: false, + maximum_size: false, + rss_sync_interval: true, + confirm: false, + } + )] + #[case( + ActiveReadarrBlock::IndexerSettingsConfirmPrompt, + IndexerSettingsPromptHighlights { + minimum_age: false, + retention: false, + maximum_size: false, + rss_sync_interval: false, + confirm: true, + } + )] + #[case( + ActiveReadarrBlock::AllIndexerSettingsPrompt, + IndexerSettingsPromptHighlights { + minimum_age: false, + retention: false, + maximum_size: false, + rss_sync_interval: false, + confirm: false, + } + )] + fn test_indexer_settings_prompt_highlights( + #[case] selected_block: ActiveReadarrBlock, + #[case] expected_highlights: IndexerSettingsPromptHighlights, + ) { + let highlights = indexer_settings_prompt_highlights(selected_block); + + assert_eq!(highlights, expected_highlights); + } + + #[test] + fn test_indexer_settings_prompt_highlights_covers_every_selection_step() { + for step in INDEXER_SETTINGS_SELECTION_BLOCKS { + let highlights = indexer_settings_prompt_highlights(step[0]); + + assert_ne!( + highlights, + indexer_settings_prompt_highlights(ActiveReadarrBlock::AllIndexerSettingsPrompt) + ); + } + } + + mod snapshot_tests { + use crate::network::readarr_network::readarr_network_test_utils::test_utils::indexer_settings; + use crate::ui::ui_test_utils::test_utils::TerminalSize; + + use super::*; + + fn seed_distinct_indexer_settings(app: &mut App<'_>) { + app.data.readarr_data.indexer_settings = Some(indexer_settings()); + } + + #[test] + fn test_indexer_settings_ui_renders_loading() { + let mut app = App::test_default_fully_populated(); + app.is_loading = true; + app.data.readarr_data.indexer_settings = None; + app.data.readarr_data.selected_block = + BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); + app.push_navigation_stack(ActiveReadarrBlock::AllIndexerSettingsPrompt.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexerSettingsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[rstest] + fn test_indexer_settings_ui_renders( + #[values( + ActiveReadarrBlock::AllIndexerSettingsPrompt, + ActiveReadarrBlock::IndexerSettingsConfirmPrompt, + ActiveReadarrBlock::IndexerSettingsMaximumSizeInput, + ActiveReadarrBlock::IndexerSettingsMinimumAgeInput, + ActiveReadarrBlock::IndexerSettingsRetentionInput, + ActiveReadarrBlock::IndexerSettingsRssSyncIntervalInput + )] + active_readarr_block: ActiveReadarrBlock, + ) { + let mut app = App::test_default_fully_populated(); + seed_distinct_indexer_settings(&mut app); + app.data.readarr_data.selected_block = + BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); + app.push_navigation_stack(active_readarr_block.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexerSettingsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(format!("indexer_settings_{active_readarr_block}"), output); + } + } +} diff --git a/src/ui/readarr_ui/indexers/indexers_ui_tests.rs b/src/ui/readarr_ui/indexers/indexers_ui_tests.rs new file mode 100644 index 00000000..802337a0 --- /dev/null +++ b/src/ui/readarr_ui/indexers/indexers_ui_tests.rs @@ -0,0 +1,266 @@ +#[cfg(test)] +mod tests { + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::servarr_data::readarr::readarr_data::{ + ActiveReadarrBlock, EDIT_INDEXER_BLOCKS, INDEXER_SETTINGS_BLOCKS, INDEXERS_BLOCKS, + }; + use crate::ui::DrawUi; + use crate::ui::readarr_ui::indexers::IndexersUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; + + #[test] + fn test_indexers_ui_accepts() { + let mut indexers_blocks = Vec::new(); + indexers_blocks.extend(INDEXERS_BLOCKS); + indexers_blocks.extend(INDEXER_SETTINGS_BLOCKS); + indexers_blocks.extend(EDIT_INDEXER_BLOCKS); + indexers_blocks.push(ActiveReadarrBlock::TestAllIndexers); + + ActiveReadarrBlock::iter().for_each(|active_readarr_block| { + if indexers_blocks.contains(&active_readarr_block) { + assert!(IndexersUi::accepts(active_readarr_block.into())); + } else { + assert!(!IndexersUi::accepts(active_readarr_block.into())); + } + }); + } + + mod test_indexer_flag_text { + use pretty_assertions::assert_eq; + use ratatui::text::Text; + + use crate::ui::readarr_ui::indexers::indexer_flag_text; + use crate::ui::styles::ManagarrStyle; + + #[test] + fn test_indexer_flag_text_when_the_flag_is_enabled() { + let flag_text = indexer_flag_text(true); + + assert_eq!(flag_text, Text::from("Enabled").success()); + } + + #[test] + fn test_indexer_flag_text_when_the_flag_is_disabled() { + let flag_text = indexer_flag_text(false); + + assert_eq!(flag_text, Text::from("Disabled").failure()); + } + + #[test] + fn test_indexer_flag_text_styles_the_two_branches_differently() { + let enabled_flag_text = indexer_flag_text(true); + + assert_ne!(enabled_flag_text, Text::from("Enabled").failure()); + } + } + + mod snapshot_tests { + use crate::models::BlockSelectionState; + use crate::models::Scrollable; + use crate::models::servarr_data::readarr::readarr_data::{ + EDIT_INDEXER_NZB_SELECTION_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, + INDEXER_SETTINGS_SELECTION_BLOCKS, + }; + use crate::models::servarr_models::Indexer; + use crate::network::readarr_network::readarr_network_test_utils::test_utils::{ + indexer, indexer_settings, + }; + use crate::ui::ui_test_utils::test_utils::TerminalSize; + use rstest::rstest; + use serde_json::Number; + + use super::*; + + fn seed_distinct_indexers(app: &mut App<'_>) { + app + .data + .readarr_data + .tags_map + .insert(2, "usenet-only".to_owned()); + app.data.readarr_data.indexers.set_items(vec![ + Indexer { + id: 3, + name: Some("Decoy Usenet Indexer".to_owned()), + protocol: "usenet".to_owned(), + enable_rss: false, + enable_automatic_search: true, + enable_interactive_search: true, + priority: 7, + tags: vec![Number::from(2)], + ..indexer() + }, + Indexer { + id: 8, + name: Some("Test Torrent Indexer".to_owned()), + protocol: "torrent".to_owned(), + enable_rss: true, + enable_automatic_search: true, + enable_interactive_search: false, + priority: 42, + tags: vec![Number::from(1)], + ..indexer() + }, + ]); + } + + #[test] + fn test_indexers_ui_renders_loading() { + let mut app = App::test_default_fully_populated(); + app.is_loading = true; + app.push_navigation_stack(ActiveReadarrBlock::Indexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_empty_indexers() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveReadarrBlock::Indexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_loading_test_results() { + let mut app = App::test_default_fully_populated(); + app.is_loading = true; + app.push_navigation_stack(ActiveReadarrBlock::TestIndexer.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_loading_test_results_when_indexer_test_errors_is_none() { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveReadarrBlock::TestIndexer.into()); + app.data.readarr_data.indexer_test_errors = None; + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_test_indexer_success_when_there_are_no_errors() { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveReadarrBlock::TestIndexer.into()); + app.data.readarr_data.indexer_test_errors = Some(String::new()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[rstest] + fn test_indexers_ui_renders( + #[values( + ActiveReadarrBlock::Indexers, + ActiveReadarrBlock::DeleteIndexerPrompt, + ActiveReadarrBlock::TestIndexer + )] + active_readarr_block: ActiveReadarrBlock, + ) { + let mut app = App::test_default_fully_populated(); + seed_distinct_indexers(&mut app); + app.push_navigation_stack(active_readarr_block.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(format!("indexers_ui_{active_readarr_block}"), output); + } + + #[test] + fn test_indexers_ui_renders_delete_prompt_for_non_default_selection() { + let mut app = App::test_default_fully_populated(); + seed_distinct_indexers(&mut app); + app.data.readarr_data.indexers.scroll_down(); + app.push_navigation_stack(ActiveReadarrBlock::DeleteIndexerPrompt.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_edit_usenet_indexer_over_indexers() { + let mut app = App::test_default_fully_populated(); + seed_distinct_indexers(&mut app); + app.data.readarr_data.selected_block = + BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS); + app.push_navigation_stack(ActiveReadarrBlock::EditIndexerPrompt.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_edit_torrent_indexer_over_indexers() { + let mut app = App::test_default_fully_populated(); + seed_distinct_indexers(&mut app); + app.data.readarr_data.indexers.scroll_down(); + app.data.readarr_data.selected_block = + BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); + app.push_navigation_stack(ActiveReadarrBlock::EditIndexerPrompt.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_indexer_settings_over_indexers() { + let mut app = App::test_default_fully_populated(); + seed_distinct_indexers(&mut app); + app.data.readarr_data.indexer_settings = Some(indexer_settings()); + app.data.readarr_data.selected_block = + BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); + app.push_navigation_stack(ActiveReadarrBlock::AllIndexerSettingsPrompt.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_test_all_indexers_over_indexers() { + let mut app = App::test_default_fully_populated(); + seed_distinct_indexers(&mut app); + app.push_navigation_stack(ActiveReadarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } +} diff --git a/src/ui/readarr_ui/indexers/mod.rs b/src/ui/readarr_ui/indexers/mod.rs new file mode 100644 index 00000000..e358e943 --- /dev/null +++ b/src/ui/readarr_ui/indexers/mod.rs @@ -0,0 +1,182 @@ +use crate::ui::styles::success_style; +use ratatui::Frame; +use ratatui::layout::{Constraint, Rect}; +use ratatui::text::Text; +use ratatui::widgets::{Cell, Row}; + +use crate::app::App; +use crate::models::Route; +use crate::models::servarr_data::readarr::readarr_data::{ActiveReadarrBlock, INDEXERS_BLOCKS}; +use crate::models::servarr_models::Indexer; +use crate::ui::DrawUi; +use crate::ui::readarr_ui::indexers::edit_indexer_ui::EditIndexerUi; +use crate::ui::readarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi; +use crate::ui::readarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi; +use crate::ui::styles::ManagarrStyle; +use crate::ui::utils::{layout_block_top_border, title_block}; +use crate::ui::widgets::confirmation_prompt::ConfirmationPrompt; +use crate::ui::widgets::loading_block::LoadingBlock; +use crate::ui::widgets::managarr_table::ManagarrTable; +use crate::ui::widgets::message::Message; +use crate::ui::widgets::popup::{Popup, Size}; + +mod edit_indexer_ui; +mod indexer_settings_ui; +mod test_all_indexers_ui; + +#[cfg(test)] +#[path = "indexers_ui_tests.rs"] +mod indexers_ui_tests; + +pub(super) struct IndexersUi; + +impl DrawUi for IndexersUi { + fn accepts(route: Route) -> bool { + if let Route::Readarr(active_readarr_block, _) = route { + return EditIndexerUi::accepts(route) + || IndexerSettingsUi::accepts(route) + || TestAllIndexersUi::accepts(route) + || INDEXERS_BLOCKS.contains(&active_readarr_block); + } + + false + } + + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + let route = app.get_current_route(); + draw_indexers(f, app, area); + + match route { + _ if EditIndexerUi::accepts(route) => EditIndexerUi::draw(f, app, area), + _ if IndexerSettingsUi::accepts(route) => IndexerSettingsUi::draw(f, app, area), + _ if TestAllIndexersUi::accepts(route) => TestAllIndexersUi::draw(f, app, area), + Route::Readarr(active_readarr_block, _) => match active_readarr_block { + ActiveReadarrBlock::TestIndexer => { + if let Some(result) = app + .data + .readarr_data + .indexer_test_errors + .as_ref() + .filter(|_| !app.is_loading) + { + let popup = if !result.is_empty() { + Popup::new(Message::new(result.clone())).size(Size::LargeMessage) + } else { + let message = Message::new("Indexer test succeeded!") + .title("Success") + .style(success_style().bold()); + Popup::new(message).size(Size::Message) + }; + + f.render_widget(popup, f.area()); + } else { + let loading_popup = Popup::new(LoadingBlock::new( + app.is_loading || app.data.readarr_data.indexer_test_errors.is_none(), + title_block("Testing Indexer"), + )) + .size(Size::LargeMessage); + f.render_widget(loading_popup, f.area()); + } + } + ActiveReadarrBlock::DeleteIndexerPrompt => { + let prompt = format!( + "Do you really want to delete this indexer: \n{}?", + app + .data + .readarr_data + .indexers + .current_selection() + .name + .clone() + .unwrap_or_default() + ); + let confirmation_prompt = ConfirmationPrompt::new() + .title("Delete Indexer") + .prompt(&prompt) + .yes_no_value(app.data.readarr_data.prompt_confirm); + + f.render_widget( + Popup::new(confirmation_prompt).size(Size::MediumPrompt), + f.area(), + ); + } + _ => (), + }, + _ => (), + } + } +} + +fn indexer_flag_text(flag: bool) -> Text<'static> { + if flag { + return Text::from("Enabled").success(); + } + + Text::from("Disabled").failure() +} + +fn draw_indexers(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + let indexers_row_mapping = |indexer: &'_ Indexer| { + let Indexer { + name, + enable_rss, + enable_automatic_search, + enable_interactive_search, + priority, + tags, + .. + } = indexer; + + let rss = indexer_flag_text(*enable_rss); + let automatic_search = indexer_flag_text(*enable_automatic_search); + let interactive_search = indexer_flag_text(*enable_interactive_search); + let empty_tag = String::new(); + let tags: String = tags + .iter() + .map(|tag_id| { + app + .data + .readarr_data + .tags_map + .get_by_left(&tag_id.as_i64().unwrap()) + .unwrap_or(&empty_tag) + .clone() + }) + .collect::>() + .join(", "); + + Row::new(vec![ + Cell::from(name.clone().unwrap_or_default()), + Cell::from(rss), + Cell::from(automatic_search), + Cell::from(interactive_search), + Cell::from(priority.to_string()), + Cell::from(tags), + ]) + .primary() + }; + let indexers_table = ManagarrTable::new( + Some(&mut app.data.readarr_data.indexers), + indexers_row_mapping, + ) + .block(layout_block_top_border()) + .loading(app.is_loading) + .headers([ + "Indexer", + "RSS", + "Automatic Search", + "Interactive Search", + "Priority", + "Tags", + ]) + .constraints([ + Constraint::Percentage(25), + Constraint::Percentage(13), + Constraint::Percentage(13), + Constraint::Percentage(13), + Constraint::Percentage(13), + Constraint::Percentage(23), + ]); + + f.render_widget(indexers_table, area); +} diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerApiKeyInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerApiKeyInput.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerApiKeyInput.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerConfirmPrompt.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerConfirmPrompt.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerConfirmPrompt.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerNameInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerNameInput.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerNameInput.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPriorityInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPriorityInput.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPriorityInput.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPrompt.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPrompt.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerPrompt.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerSeedRatioInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerSeedRatioInput.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerSeedRatioInput.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerTagsInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerTagsInput.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerTagsInput.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableAutomaticSearch.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableAutomaticSearch.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableAutomaticSearch.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableInteractiveSearch.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableInteractiveSearch.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableInteractiveSearch.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableRss.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableRss.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerToggleEnableRss.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerUrlInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerUrlInput.snap new file mode 100644 index 00000000..953efc1d --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_torrent_EditIndexerUrlInput.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_loading.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_loading.snap new file mode 100644 index 00000000..75906c5e --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_loading.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_usenet_grid.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_usenet_grid.snap new file mode 100644 index 00000000..a0cbe6ca --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_usenet_grid.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Indexer Priority ▴▾: │1 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_AllIndexerSettingsPrompt.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_AllIndexerSettingsPrompt.snap new file mode 100644 index 00000000..b82e8c33 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_AllIndexerSettingsPrompt.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ │ + │ ╭────────────────────────────────╮ │ + │ Minimum Age (minutes) ▴▾: │17 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Retention (days) ▴▾: │43 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │26500 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ RSS Sync Interval (minutes) ▴▾: │35 │ │ + │ ╰────────────────────────────────╯ │ + │ │ + │ │ + │ ╭────────────────╮╭────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰────────────────╯╰────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsConfirmPrompt.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsConfirmPrompt.snap new file mode 100644 index 00000000..b82e8c33 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsConfirmPrompt.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ │ + │ ╭────────────────────────────────╮ │ + │ Minimum Age (minutes) ▴▾: │17 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Retention (days) ▴▾: │43 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │26500 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ RSS Sync Interval (minutes) ▴▾: │35 │ │ + │ ╰────────────────────────────────╯ │ + │ │ + │ │ + │ ╭────────────────╮╭────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰────────────────╯╰────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMaximumSizeInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMaximumSizeInput.snap new file mode 100644 index 00000000..b82e8c33 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMaximumSizeInput.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ │ + │ ╭────────────────────────────────╮ │ + │ Minimum Age (minutes) ▴▾: │17 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Retention (days) ▴▾: │43 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │26500 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ RSS Sync Interval (minutes) ▴▾: │35 │ │ + │ ╰────────────────────────────────╯ │ + │ │ + │ │ + │ ╭────────────────╮╭────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰────────────────╯╰────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMinimumAgeInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMinimumAgeInput.snap new file mode 100644 index 00000000..b82e8c33 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsMinimumAgeInput.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ │ + │ ╭────────────────────────────────╮ │ + │ Minimum Age (minutes) ▴▾: │17 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Retention (days) ▴▾: │43 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │26500 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ RSS Sync Interval (minutes) ▴▾: │35 │ │ + │ ╰────────────────────────────────╯ │ + │ │ + │ │ + │ ╭────────────────╮╭────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰────────────────╯╰────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRetentionInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRetentionInput.snap new file mode 100644 index 00000000..b82e8c33 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRetentionInput.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ │ + │ ╭────────────────────────────────╮ │ + │ Minimum Age (minutes) ▴▾: │17 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Retention (days) ▴▾: │43 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │26500 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ RSS Sync Interval (minutes) ▴▾: │35 │ │ + │ ╰────────────────────────────────╯ │ + │ │ + │ │ + │ ╭────────────────╮╭────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰────────────────╯╰────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRssSyncIntervalInput.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRssSyncIntervalInput.snap new file mode 100644 index 00000000..b82e8c33 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_IndexerSettingsRssSyncIntervalInput.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ │ + │ ╭────────────────────────────────╮ │ + │ Minimum Age (minutes) ▴▾: │17 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Retention (days) ▴▾: │43 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │26500 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ RSS Sync Interval (minutes) ▴▾: │35 │ │ + │ ╰────────────────────────────────╯ │ + │ │ + │ │ + │ ╭────────────────╮╭────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰────────────────╯╰────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_loading.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_loading.snap new file mode 100644 index 00000000..321e6a35 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_loading.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_DeleteIndexerPrompt.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_DeleteIndexerPrompt.snap new file mode 100644 index 00000000..98cd8000 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_DeleteIndexerPrompt.snap @@ -0,0 +1,38 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only + Test Torrent Indexer Enabled Enabled Disabled 42 alex + + + + + + + + + + + + + ╭──────────────────── Delete Indexer ─────────────────────╮ + │ Do you really want to delete this indexer: │ + │ Decoy Usenet Indexer? │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │╭────────────────────────────╮╭───────────────────────────╮│ + ││ Yes ││ No ││ + │╰────────────────────────────╯╰───────────────────────────╯│ + ╰───────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_Indexers.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_Indexers.snap new file mode 100644 index 00000000..70e39648 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_Indexers.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only + Test Torrent Indexer Enabled Enabled Disabled 42 alex diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_TestIndexer.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_TestIndexer.snap new file mode 100644 index 00000000..165a3765 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_TestIndexer.snap @@ -0,0 +1,35 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only + Test Torrent Indexer Enabled Enabled Disabled 42 alex + + + + + + + + + + + + + + + + ╭─────────────── Error ───────────────╮ + │ error │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰───────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_delete_prompt_for_non_default_selection.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_delete_prompt_for_non_default_selection.snap new file mode 100644 index 00000000..62f2d669 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_delete_prompt_for_non_default_selection.snap @@ -0,0 +1,38 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags + Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only +=> Test Torrent Indexer Enabled Enabled Disabled 42 alex + + + + + + + + + + + + + ╭──────────────────── Delete Indexer ─────────────────────╮ + │ Do you really want to delete this indexer: │ + │ Test Torrent Indexer? │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │╭────────────────────────────╮╭───────────────────────────╮│ + ││ Yes ││ No ││ + │╰────────────────────────────╯╰───────────────────────────╯│ + ╰───────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_torrent_indexer_over_indexers.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_torrent_indexer_over_indexers.snap new file mode 100644 index 00000000..b2d2bedf --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_torrent_indexer_over_indexers.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags + Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only +=> Test Torrent Indexer Enabled Enabled Disabled 42 alex + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ ✔ │ Seed Ratio: │ratio │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭─────────────────────────╮ │ + │ Indexer Priority ▴▾: │1 │ │ + │ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_usenet_indexer_over_indexers.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_usenet_indexer_over_indexers.snap new file mode 100644 index 00000000..18e13888 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_edit_usenet_indexer_over_indexers.snap @@ -0,0 +1,42 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only + Test Torrent Indexer Enabled Enabled Disabled 42 alex + + + + + + + + + + ╭──────────────────────────────────────────────── Edit Indexer ─────────────────────────────────────────────────╮ + │ │ + │ ╭─────────────────────────╮ ╭─────────────────────────╮ │ + │ Name: │DrunkenSlug │ URL: │http://127.0.0.1:9696/1/ │ │ + │ ╰─────────────────────────╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable RSS: │ ✔ │ API Key: │someApiKey │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Automatic Search: │ ✔ │ Tags: │25 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ ╭───╮ ╭─────────────────────────╮ │ + │ Enable Interactive Search: │ ✔ │ Indexer Priority ▴▾: │1 │ │ + │ ╰───╯ ╰─────────────────────────╯ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ ╭───────────────────────────╮╭──────────────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰───────────────────────────╯╰──────────────────────────╯ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap new file mode 100644 index 00000000..20e686c5 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_indexer_settings_over_indexers.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_indexer_settings_over_indexers.snap new file mode 100644 index 00000000..ff32ac41 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_indexer_settings_over_indexers.snap @@ -0,0 +1,40 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only + Test Torrent Indexer Enabled Enabled Disabled 42 alex + + + + + + + + + + + ╭─────────────────── Configure All Indexer Settings ───────────────────╮ + │ │ + │ │ + │ │ + │ ╭────────────────────────────────╮ │ + │ Minimum Age (minutes) ▴▾: │17 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Retention (days) ▴▾: │43 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │26500 │ │ + │ ╰────────────────────────────────╯ │ + │ ╭────────────────────────────────╮ │ + │ RSS Sync Interval (minutes) ▴▾: │35 │ │ + │ ╰────────────────────────────────╯ │ + │ │ + │ │ + │ ╭────────────────╮╭────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰────────────────╯╰────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading.snap new file mode 100644 index 00000000..1c8ab1cd --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results.snap new file mode 100644 index 00000000..9bad23a3 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results.snap @@ -0,0 +1,35 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... + + + + + + + + + + + + + + + + ╭ Testing Indexer ────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰───────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results_when_indexer_test_errors_is_none.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results_when_indexer_test_errors_is_none.snap new file mode 100644 index 00000000..0d598c66 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_test_results_when_indexer_test_errors_is_none.snap @@ -0,0 +1,35 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Test Indexer Enabled Enabled Enabled 25 alex + + + + + + + + + + + + + + + + + ╭ Testing Indexer ────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰───────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_all_indexers_over_indexers.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_all_indexers_over_indexers.snap new file mode 100644 index 00000000..bacce06a --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_all_indexers_over_indexers.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Decoy Usenet Indexer Disabled Enabled Enabled 7 usenet-only + Test Torrent Indexer Enabled Enabled Disabled 42 alex + + + ╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │ Indexer Pass/Fail Failure Messages │ + │=> DrunkenSlug x Some failure │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_indexer_success_when_there_are_no_errors.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_indexer_success_when_there_are_no_errors.snap new file mode 100644 index 00000000..4999ebfe --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_test_indexer_success_when_there_are_no_errors.snap @@ -0,0 +1,31 @@ +--- +source: src/ui/readarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Search Priority Tags +=> Test Indexer Enabled Enabled Enabled 25 alex + + + + + + + + + + + + + + + + + + + + + ╭────────────── Success ──────────────╮ + │ Indexer test succeeded! │ + │ │ + ╰───────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders.snap new file mode 100644 index 00000000..f1693108 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │ Indexer Pass/Fail Failure Messages │ + │=> Test Indexer + │ + │ Other Indexer x Failure for field 'baseUrl': Unable to connect to indexer, Failure for field 'apiKe│ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_empty_results.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_empty_results.snap new file mode 100644 index 00000000..a719b4db --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_empty_results.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_for_non_default_selection.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_for_non_default_selection.snap new file mode 100644 index 00000000..d29cf306 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_for_non_default_selection.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │ Indexer Pass/Fail Failure Messages │ + │ Test Indexer + │ + │=> Other Indexer x Failure for field 'baseUrl': Unable to connect to indexer, Failure for field 'apiKe│ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading.snap new file mode 100644 index 00000000..2f9c8657 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_when_results_are_none.snap b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_when_results_are_none.snap new file mode 100644 index 00000000..2f9c8657 --- /dev/null +++ b/src/ui/readarr_ui/indexers/snapshots/managarr__ui__readarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_when_results_are_none.snap @@ -0,0 +1,48 @@ +--- +source: src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs +expression: output +--- + + + + + + + ╭ Test All Indexers ─────────────────────────────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/readarr_ui/indexers/test_all_indexers_ui.rs b/src/ui/readarr_ui/indexers/test_all_indexers_ui.rs new file mode 100644 index 00000000..d25919f2 --- /dev/null +++ b/src/ui/readarr_ui/indexers/test_all_indexers_ui.rs @@ -0,0 +1,86 @@ +use crate::app::App; +use crate::models::Route; +use crate::models::servarr_data::modals::IndexerTestResultModalItem; +use crate::models::servarr_data::readarr::readarr_data::ActiveReadarrBlock; +use crate::ui::styles::ManagarrStyle; +use crate::ui::utils::{get_width_from_percentage, title_block}; +use crate::ui::widgets::managarr_table::ManagarrTable; +use crate::ui::widgets::popup::Size; +use crate::ui::{DrawUi, draw_popup}; +use ratatui::Frame; +use ratatui::layout::{Constraint, Rect}; +use ratatui::widgets::{Cell, Row}; + +#[cfg(test)] +#[path = "test_all_indexers_ui_tests.rs"] +mod test_all_indexers_ui_tests; + +pub(super) struct TestAllIndexersUi; + +impl DrawUi for TestAllIndexersUi { + fn accepts(route: Route) -> bool { + if let Route::Readarr(active_readarr_block, _) = route { + return active_readarr_block == ActiveReadarrBlock::TestAllIndexers; + } + + false + } + + fn draw(f: &mut Frame<'_>, app: &mut App<'_>, _area: Rect) { + draw_popup(f, app, draw_test_all_indexers_test_results, Size::Large); + } +} + +fn decorate_test_result_row_with_style<'a>( + result: &IndexerTestResultModalItem, + row: Row<'a>, +) -> Row<'a> { + if result.is_valid { + row.success() + } else { + row.failure() + } +} + +fn draw_test_all_indexers_test_results(f: &mut Frame<'_>, app: &mut App<'_>, area: Rect) { + let is_loading = app.is_loading || app.data.readarr_data.indexer_test_all_results.is_none(); + let current_selection = if let Some(test_all_results) = + app.data.readarr_data.indexer_test_all_results.as_ref() + && !test_all_results.is_empty() + { + test_all_results.current_selection().clone() + } else { + IndexerTestResultModalItem::default() + }; + f.render_widget(title_block("Test All Indexers"), area); + let test_results_row_mapping = |result: &IndexerTestResultModalItem| { + result.validation_failures.scroll_left_or_reset( + get_width_from_percentage(area, 86), + *result == current_selection, + app.should_text_scroll, + ); + let pass_fail = if result.is_valid { "+" } else { "x" }; + let row = Row::new(vec![ + Cell::from(result.name.to_owned()), + Cell::from(pass_fail.to_owned()), + Cell::from(result.validation_failures.to_string()), + ]); + + decorate_test_result_row_with_style(result, row) + }; + + let indexers_test_results_table = ManagarrTable::new( + app.data.readarr_data.indexer_test_all_results.as_mut(), + test_results_row_mapping, + ) + .loading(is_loading) + .margin(1) + .headers(["Indexer", "Pass/Fail", "Failure Messages"]) + .constraints([ + Constraint::Percentage(20), + Constraint::Percentage(10), + Constraint::Percentage(70), + ]); + + f.render_widget(indexers_test_results_table, area); +} diff --git a/src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs b/src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs new file mode 100644 index 00000000..512bb2d8 --- /dev/null +++ b/src/ui/readarr_ui/indexers/test_all_indexers_ui_tests.rs @@ -0,0 +1,156 @@ +#[cfg(test)] +mod tests { + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::servarr_data::readarr::readarr_data::ActiveReadarrBlock; + use crate::ui::DrawUi; + use crate::ui::readarr_ui::indexers::test_all_indexers_ui::TestAllIndexersUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; + + #[test] + fn test_test_all_indexers_ui_accepts() { + ActiveReadarrBlock::iter().for_each(|active_readarr_block| { + if active_readarr_block == ActiveReadarrBlock::TestAllIndexers { + assert!(TestAllIndexersUi::accepts(active_readarr_block.into())); + } else { + assert!(!TestAllIndexersUi::accepts(active_readarr_block.into())); + } + }); + } + + mod test_decorate_test_result_row_with_style { + use pretty_assertions::assert_eq; + use ratatui::widgets::{Cell, Row}; + + use crate::models::servarr_data::modals::IndexerTestResultModalItem; + use crate::ui::readarr_ui::indexers::test_all_indexers_ui::decorate_test_result_row_with_style; + use crate::ui::styles::ManagarrStyle; + + fn indexer_test_result(is_valid: bool) -> IndexerTestResultModalItem { + IndexerTestResultModalItem { + name: "Test Indexer".to_owned(), + is_valid, + validation_failures: "Unable to connect to indexer".into(), + } + } + + #[test] + fn test_decorate_test_result_row_with_style_when_the_result_is_valid() { + let row = Row::new(vec![Cell::from("Test Indexer")]); + + let decorated_row = + decorate_test_result_row_with_style(&indexer_test_result(true), row.clone()); + + assert_eq!(decorated_row, row.success()); + } + + #[test] + fn test_decorate_test_result_row_with_style_when_the_result_is_invalid() { + let row = Row::new(vec![Cell::from("Test Indexer")]); + + let decorated_row = + decorate_test_result_row_with_style(&indexer_test_result(false), row.clone()); + + assert_eq!(decorated_row, row.failure()); + } + + #[test] + fn test_decorate_test_result_row_with_style_styles_the_two_branches_differently() { + let row = Row::new(vec![Cell::from("Test Indexer")]); + + let decorated_row = + decorate_test_result_row_with_style(&indexer_test_result(true), row.clone()); + + assert_ne!(decorated_row, row.failure()); + } + } + + mod snapshot_tests { + use crate::models::Scrollable; + use crate::models::stateful_table::StatefulTable; + use crate::network::readarr_network::readarr_network_test_utils::test_utils::indexer_test_results; + use crate::ui::ui_test_utils::test_utils::TerminalSize; + + use super::*; + + fn seed_distinct_test_results(app: &mut App<'_>) { + let mut indexer_test_all_results = StatefulTable::default(); + indexer_test_all_results.set_items(indexer_test_results()); + app.data.readarr_data.indexer_test_all_results = Some(indexer_test_all_results); + } + + #[test] + fn test_test_all_indexers_ui_renders_loading() { + let mut app = App::test_default_fully_populated(); + seed_distinct_test_results(&mut app); + app.is_loading = true; + app.push_navigation_stack(ActiveReadarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + TestAllIndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_test_all_indexers_ui_renders_loading_when_results_are_none() { + let mut app = App::test_default_fully_populated(); + app.data.readarr_data.indexer_test_all_results = None; + app.push_navigation_stack(ActiveReadarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + TestAllIndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_test_all_indexers_ui_renders_empty_results() { + let mut app = App::test_default_fully_populated(); + app.data.readarr_data.indexer_test_all_results = Some(StatefulTable::default()); + app.push_navigation_stack(ActiveReadarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + TestAllIndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_test_all_indexers_ui_renders() { + let mut app = App::test_default_fully_populated(); + seed_distinct_test_results(&mut app); + app.push_navigation_stack(ActiveReadarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + TestAllIndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_test_all_indexers_ui_renders_for_non_default_selection() { + let mut app = App::test_default_fully_populated(); + seed_distinct_test_results(&mut app); + app + .data + .readarr_data + .indexer_test_all_results + .as_mut() + .expect("indexer_test_all_results must exist in this context") + .scroll_down(); + app.push_navigation_stack(ActiveReadarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + TestAllIndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } +} diff --git a/src/ui/readarr_ui/mod.rs b/src/ui/readarr_ui/mod.rs index a1e68c53..3b6b7712 100644 --- a/src/ui/readarr_ui/mod.rs +++ b/src/ui/readarr_ui/mod.rs @@ -24,6 +24,7 @@ use super::{ }; use crate::ui::readarr_ui::blocklist::BlocklistUi; use crate::ui::readarr_ui::downloads::DownloadsUi; +use crate::ui::readarr_ui::indexers::IndexersUi; use crate::ui::readarr_ui::root_folders::RootFoldersUi; use crate::ui::readarr_ui::system::SystemUi; use crate::ui::utils::{extract_monitored_disk_space_vec, extract_monitored_root_folders}; @@ -42,6 +43,7 @@ use crate::{ mod blocklist; mod downloads; mod history; +mod indexers; mod library; mod readarr_ui_utils; mod root_folders; @@ -68,6 +70,7 @@ impl DrawUi for ReadarrUi { _ if BlocklistUi::accepts(route) => BlocklistUi::draw(f, app, content_area), _ if HistoryUi::accepts(route) => HistoryUi::draw(f, app, content_area), _ if RootFoldersUi::accepts(route) => RootFoldersUi::draw(f, app, content_area), + _ if IndexersUi::accepts(route) => IndexersUi::draw(f, app, content_area), _ if SystemUi::accepts(route) => SystemUi::draw(f, app, content_area), _ => (), } diff --git a/src/ui/readarr_ui/snapshots/managarr__ui__readarr_ui__readarr_ui_tests__tests__snapshot_tests__readarr_tabs_Indexers.snap b/src/ui/readarr_ui/snapshots/managarr__ui__readarr_ui__readarr_ui_tests__tests__snapshot_tests__readarr_tabs_Indexers.snap index d3f01721..de20de5f 100644 --- a/src/ui/readarr_ui/snapshots/managarr__ui__readarr_ui__readarr_ui_tests__tests__snapshot_tests__readarr_tabs_Indexers.snap +++ b/src/ui/readarr_ui/snapshots/managarr__ui__readarr_ui__readarr_ui_tests__tests__snapshot_tests__readarr_tabs_Indexers.snap @@ -4,9 +4,9 @@ expression: output --- ╭ Authors ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ Library │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ -│ │ -│ │ -│ │ +│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ Indexer RSS Automatic Search Interactive Search Priority Tags │ +│=> Test Indexer Enabled Enabled Enabled 25 alex │ │ │ │ │ │ │