From cef1ad13af94d3d3c1f05d6bd853bcb54a8e5ca8 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Wed, 9 Sep 2026 16:22:51 -0600 Subject: [PATCH] test(readarr): pin table search, filter and selection behaviour Readarr handler tests never asserted which block the search and filter keys push, so transposing searching_block and filtering_block in a TableHandlingConfig went undetected. History already had both tests; add the five missing search key tests and the three missing filter key tests, covering the authors, books, author history, editions and book history tables. The books and editions tables configure no filtering_block, so they get no filter test. No test moved a table or list selection off index 0 either, which made current_selection() and items[0] indistinguishable. Select a non-zero index in the tests covering every handler that reads a selected row, adding a decoy entry at index 0 so existing expected values stay meaningful. The profile, monitor and root folder lists inside the add author, edit author and add root folder prompts are a separate gap that a table-only sweep misses, so those are covered too, as are the book files, editions and releases tables held on the book details modal. Several fixtures also asserted against a default value, so the expected result was indistinguishable from an unset field. The add author, edit author and add root folder bodies now expect non-default monitor options, and the quality and metadata profile ids are drawn from disjoint id pairs so the two lookups cannot be transposed. --- .../library/add_author_handler_tests.rs | 169 ++++++++++++++---- .../library/author_details_handler_tests.rs | 97 +++++++++- .../library/book_details_handler_tests.rs | 128 ++++++++++--- .../library/delete_author_handler_tests.rs | 22 ++- .../library/delete_book_handler_tests.rs | 22 ++- .../library/edit_author_handler_tests.rs | 30 +++- .../library/library_handler_tests.rs | 43 ++++- .../add_root_folder_handler_tests.rs | 25 ++- 8 files changed, 447 insertions(+), 89 deletions(-) diff --git a/src/handlers/readarr_handlers/library/add_author_handler_tests.rs b/src/handlers/readarr_handlers/library/add_author_handler_tests.rs index e76ef7e9..562f3c5b 100644 --- a/src/handlers/readarr_handlers/library/add_author_handler_tests.rs +++ b/src/handlers/readarr_handlers/library/add_author_handler_tests.rs @@ -947,10 +947,16 @@ mod tests { let mut app = App::test_default(); app.push_navigation_stack(ActiveReadarrBlock::AddAuthorSearchResults.into()); let mut add_searched_authors = StatefulTable::default(); - add_searched_authors.set_items(vec![add_author_search_result()]); + let mut decoy_search_result = add_author_search_result(); + decoy_search_result.foreign_author_id = "decoy-foreign-id".to_owned(); + decoy_search_result.author_name = "Decoy Author".into(); + add_searched_authors.set_items(vec![decoy_search_result, add_author_search_result()]); + add_searched_authors.select_index(Some(1)); app.data.readarr_data.add_searched_authors = Some(add_searched_authors); - app.data.readarr_data.quality_profile_map = BiMap::from_iter([(1, "Test".to_owned())]); - app.data.readarr_data.metadata_profile_map = BiMap::from_iter([(1, "Test".to_owned())]); + app.data.readarr_data.quality_profile_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "eBook".to_owned())]); + app.data.readarr_data.metadata_profile_map = + BiMap::from_iter([(3333, "None".to_owned()), (4444, "Standard".to_owned())]); AddAuthorHandler::new( SUBMIT_KEY, @@ -1021,7 +1027,11 @@ mod tests { let mut app = App::test_default(); app.push_navigation_stack(ActiveReadarrBlock::AddAuthorSearchResults.into()); let mut add_searched_authors = StatefulTable::default(); - add_searched_authors.set_items(vec![add_author_search_result()]); + let mut decoy_search_result = add_author_search_result(); + decoy_search_result.foreign_author_id = "decoy-foreign-id".to_owned(); + decoy_search_result.author_name = "Decoy Author".into(); + add_searched_authors.set_items(vec![decoy_search_result, add_author_search_result()]); + add_searched_authors.select_index(Some(1)); app.data.readarr_data.add_searched_authors = Some(add_searched_authors); app .data @@ -1046,7 +1056,11 @@ mod tests { let mut app = App::test_default(); app.push_navigation_stack(ActiveReadarrBlock::AddAuthorSearchResults.into()); let mut add_searched_authors = StatefulTable::default(); - add_searched_authors.set_items(vec![add_author_search_result()]); + let mut decoy_search_result = add_author_search_result(); + decoy_search_result.foreign_author_id = OTHER_FOREIGN_AUTHOR_ID.to_owned(); + decoy_search_result.author_name = "Decoy Author".into(); + add_searched_authors.set_items(vec![decoy_search_result, add_author_search_result()]); + add_searched_authors.select_index(Some(1)); app.data.readarr_data.add_searched_authors = Some(add_searched_authors); app .data @@ -1107,10 +1121,16 @@ mod tests { .set_index(0, ADD_AUTHOR_SELECTION_BLOCKS.len() - 1); app.data.readarr_data.prompt_confirm = true; let mut add_searched_authors = StatefulTable::default(); - add_searched_authors.set_items(vec![add_author_search_result()]); + let mut decoy_search_result = add_author_search_result(); + decoy_search_result.foreign_author_id = "decoy-foreign-id".to_owned(); + decoy_search_result.author_name = "Decoy Author".into(); + add_searched_authors.set_items(vec![decoy_search_result, add_author_search_result()]); + add_searched_authors.select_index(Some(1)); app.data.readarr_data.add_searched_authors = Some(add_searched_authors); - app.data.readarr_data.quality_profile_map = BiMap::from_iter([(1, "Test".to_owned())]); - app.data.readarr_data.metadata_profile_map = BiMap::from_iter([(1, "Test".to_owned())]); + app.data.readarr_data.quality_profile_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "eBook".to_owned())]); + app.data.readarr_data.metadata_profile_map = + BiMap::from_iter([(3333, "None".to_owned()), (4444, "Standard".to_owned())]); app.data.readarr_data.add_author_modal = Some(AddAuthorModal { tags: "usenet, testing".into(), ..AddAuthorModal::default() @@ -1123,6 +1143,15 @@ mod tests { .unwrap() .monitor_list .set_items(Vec::from_iter(MonitorType::iter())); + app + .data + .readarr_data + .add_author_modal + .as_mut() + .unwrap() + .monitor_list + .state + .select(Some(1)); app .data .readarr_data @@ -1131,6 +1160,15 @@ mod tests { .unwrap() .monitor_new_items_list .set_items(Vec::from_iter(NewItemMonitorType::iter())); + app + .data + .readarr_data + .add_author_modal + .as_mut() + .unwrap() + .monitor_new_items_list + .state + .select(Some(1)); app .data .readarr_data @@ -1138,7 +1176,16 @@ mod tests { .as_mut() .unwrap() .quality_profile_list - .set_items(vec!["Test".to_owned()]); + .set_items(vec!["Any".to_owned(), "eBook".to_owned()]); + app + .data + .readarr_data + .add_author_modal + .as_mut() + .unwrap() + .quality_profile_list + .state + .select(Some(1)); app .data .readarr_data @@ -1146,7 +1193,16 @@ mod tests { .as_mut() .unwrap() .metadata_profile_list - .set_items(vec!["Test".to_owned()]); + .set_items(vec!["None".to_owned(), "Standard".to_owned()]); + app + .data + .readarr_data + .add_author_modal + .as_mut() + .unwrap() + .metadata_profile_list + .state + .select(Some(1)); app .data .readarr_data @@ -1154,22 +1210,37 @@ mod tests { .as_mut() .unwrap() .root_folder_list - .set_items(vec![RootFolder { - path: "/books".to_owned(), - ..RootFolder::default() - }]); + .set_items(vec![ + RootFolder { + path: "/decoy".to_owned(), + ..RootFolder::default() + }, + RootFolder { + path: "/books".to_owned(), + ..RootFolder::default() + }, + ]); + app + .data + .readarr_data + .add_author_modal + .as_mut() + .unwrap() + .root_folder_list + .state + .select(Some(1)); let expected_add_author_body = AddAuthorBody { foreign_author_id: SEARCHED_FOREIGN_AUTHOR_ID.to_string(), author_name: "Test Author".to_string(), monitored: true, root_folder_path: "/books".to_string(), - quality_profile_id: 1, - metadata_profile_id: 1, + quality_profile_id: 2222, + metadata_profile_id: 4444, tags: Vec::default(), tag_input_string: Some("usenet, testing".to_owned()), add_options: AddAuthorOptions { - monitor: MonitorType::All, - monitor_new_items: NewItemMonitorType::All, + monitor: MonitorType::Future, + monitor_new_items: NewItemMonitorType::None, search_for_missing_books: true, }, }; @@ -1498,10 +1569,16 @@ mod tests { .selected_block .set_index(0, ADD_AUTHOR_SELECTION_BLOCKS.len() - 1); let mut add_searched_authors = StatefulTable::default(); - add_searched_authors.set_items(vec![add_author_search_result()]); + let mut decoy_search_result = add_author_search_result(); + decoy_search_result.foreign_author_id = "decoy-foreign-id".to_owned(); + decoy_search_result.author_name = "Decoy Author".into(); + add_searched_authors.set_items(vec![decoy_search_result, add_author_search_result()]); + add_searched_authors.select_index(Some(1)); app.data.readarr_data.add_searched_authors = Some(add_searched_authors); - app.data.readarr_data.quality_profile_map = BiMap::from_iter([(1, "Test".to_owned())]); - app.data.readarr_data.metadata_profile_map = BiMap::from_iter([(1, "Test".to_owned())]); + app.data.readarr_data.quality_profile_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "eBook".to_owned())]); + app.data.readarr_data.metadata_profile_map = + BiMap::from_iter([(3333, "None".to_owned()), (4444, "Standard".to_owned())]); let mut add_author_modal = AddAuthorModal { tags: "usenet, testing".into(), ..AddAuthorModal::default() @@ -1509,15 +1586,22 @@ mod tests { add_author_modal .monitor_list .set_items(Vec::from_iter(MonitorType::iter())); + add_author_modal.monitor_list.state.select(Some(1)); add_author_modal .monitor_new_items_list .set_items(Vec::from_iter(NewItemMonitorType::iter())); + add_author_modal + .monitor_new_items_list + .state + .select(Some(1)); add_author_modal .quality_profile_list - .set_items(vec!["Test".to_owned()]); + .set_items(vec!["Any".to_owned(), "eBook".to_owned()]); + add_author_modal.quality_profile_list.state.select(Some(1)); add_author_modal .metadata_profile_list - .set_items(vec!["Test".to_owned()]); + .set_items(vec!["None".to_owned(), "Standard".to_owned()]); + add_author_modal.metadata_profile_list.state.select(Some(1)); add_author_modal.root_folder_list.set_items(vec![ RootFolder { id: 1, @@ -1541,13 +1625,13 @@ mod tests { author_name: "Test Author".to_string(), monitored: true, root_folder_path: "/nfs2".to_string(), - quality_profile_id: 1, - metadata_profile_id: 1, + quality_profile_id: 2222, + metadata_profile_id: 4444, tags: Vec::default(), tag_input_string: Some("usenet, testing".to_owned()), add_options: AddAuthorOptions { - monitor: Default::default(), - monitor_new_items: Default::default(), + monitor: MonitorType::Future, + monitor_new_items: NewItemMonitorType::None, search_for_missing_books: true, }, }; @@ -1674,34 +1758,47 @@ mod tests { add_author_modal.root_folder_list.state.select(Some(1)); add_author_modal .quality_profile_list - .set_items(vec!["Any".to_owned()]); + .set_items(vec!["Any".to_owned(), "eBook".to_owned()]); + add_author_modal.quality_profile_list.state.select(Some(1)); add_author_modal .metadata_profile_list - .set_items(vec!["Standard".to_owned()]); + .set_items(vec!["None".to_owned(), "Standard".to_owned()]); + add_author_modal.metadata_profile_list.state.select(Some(1)); add_author_modal .monitor_list .set_items(Vec::from_iter(MonitorType::iter())); + add_author_modal.monitor_list.state.select(Some(1)); add_author_modal .monitor_new_items_list .set_items(Vec::from_iter(NewItemMonitorType::iter())); + add_author_modal + .monitor_new_items_list + .state + .select(Some(1)); app.data.readarr_data.add_author_modal = Some(add_author_modal); - app.data.readarr_data.quality_profile_map = BiMap::from_iter([(1, "Any".to_owned())]); - app.data.readarr_data.metadata_profile_map = BiMap::from_iter([(1, "Standard".to_owned())]); + app.data.readarr_data.quality_profile_map = + BiMap::from_iter([(1111, "Any".to_owned()), (2222, "eBook".to_owned())]); + app.data.readarr_data.metadata_profile_map = + BiMap::from_iter([(3333, "None".to_owned()), (4444, "Standard".to_owned())]); let mut add_searched_authors = StatefulTable::default(); - add_searched_authors.set_items(vec![add_author_search_result()]); + let mut decoy_search_result = add_author_search_result(); + decoy_search_result.foreign_author_id = "decoy-foreign-id".to_owned(); + decoy_search_result.author_name = "Decoy Author".into(); + add_searched_authors.set_items(vec![decoy_search_result, add_author_search_result()]); + add_searched_authors.select_index(Some(1)); app.data.readarr_data.add_searched_authors = Some(add_searched_authors); let expected_add_author_body = AddAuthorBody { foreign_author_id: SEARCHED_FOREIGN_AUTHOR_ID.to_string(), author_name: "Test Author".into(), monitored: true, root_folder_path: "/nfs2".to_string(), - quality_profile_id: 1, - metadata_profile_id: 1, + quality_profile_id: 2222, + metadata_profile_id: 4444, tags: Vec::default(), tag_input_string: Some("usenet, testing".to_owned()), add_options: AddAuthorOptions { - monitor: Default::default(), - monitor_new_items: Default::default(), + monitor: MonitorType::Future, + monitor_new_items: NewItemMonitorType::None, search_for_missing_books: true, }, }; diff --git a/src/handlers/readarr_handlers/library/author_details_handler_tests.rs b/src/handlers/readarr_handlers/library/author_details_handler_tests.rs index 180aab68..034da500 100644 --- a/src/handlers/readarr_handlers/library/author_details_handler_tests.rs +++ b/src/handlers/readarr_handlers/library/author_details_handler_tests.rs @@ -301,11 +301,15 @@ mod tests { fn test_manual_author_search_confirm_prompt_confirm_submit() { let mut app = App::test_default(); let release = torrent_release(); + let mut decoy_release = torrent_release(); + decoy_release.guid = "decoy-guid".to_owned(); + decoy_release.indexer_id = 999; app .data .readarr_data .author_releases - .set_items(vec![release.clone()]); + .set_items(vec![decoy_release, release.clone()]); + app.data.readarr_data.author_releases.select_index(Some(1)); app.data.readarr_data.prompt_confirm = true; let expected_action = ReadarrEvent::DownloadRelease(ReleaseDownloadBody { guid: release.guid, @@ -562,6 +566,16 @@ mod tests { fn test_author_details_view_key_builds_the_overview_from_the_selected_author() { let mut app = App::test_default_fully_populated(); app.data.readarr_data.author_overview_modal = None; + let author = app.data.readarr_data.authors.current_selection().clone(); + let mut decoy_author = author.clone(); + decoy_author.id = 999; + decoy_author.overview = Some("decoy author overview".to_owned()); + app + .data + .readarr_data + .authors + .set_items(vec![decoy_author, author]); + app.data.readarr_data.authors.select_index(Some(1)); app.push_navigation_stack(ActiveReadarrBlock::AuthorDetails.into()); AuthorDetailsHandler::new( @@ -698,6 +712,15 @@ mod tests { #[test] fn test_author_details_toggle_monitoring_key() { let mut app = App::test_default_fully_populated(); + let book = app.data.readarr_data.books.current_selection().clone(); + let mut decoy_book = book.clone(); + decoy_book.id = 999; + app + .data + .readarr_data + .books + .set_items(vec![decoy_book, book]); + app.data.readarr_data.books.select_index(Some(1)); app.is_routing = false; app.push_navigation_stack(ActiveReadarrBlock::Authors.into()); app.push_navigation_stack(ActiveReadarrBlock::AuthorDetails.into()); @@ -954,11 +977,15 @@ mod tests { fn test_manual_author_search_confirm_prompt_confirm_key() { let mut app = App::test_default(); let release = torrent_release(); + let mut decoy_release = torrent_release(); + decoy_release.guid = "decoy-guid".to_owned(); + decoy_release.indexer_id = 999; app .data .readarr_data .author_releases - .set_items(vec![release.clone()]); + .set_items(vec![decoy_release, release.clone()]); + app.data.readarr_data.author_releases.select_index(Some(1)); let expected_action = ReadarrEvent::DownloadRelease(ReleaseDownloadBody { guid: release.guid, indexer_id: release.indexer_id, @@ -981,6 +1008,54 @@ mod tests { &expected_action ); } + + #[test] + fn test_search_books_key() { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveReadarrBlock::AuthorDetails.into()); + + AuthorDetailsHandler::new( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveReadarrBlock::AuthorDetails, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::SearchBooks.into()); + } + + #[test] + fn test_search_author_history_key() { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveReadarrBlock::AuthorHistory.into()); + + AuthorDetailsHandler::new( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveReadarrBlock::AuthorHistory, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::SearchAuthorHistory.into()); + } + + #[test] + fn test_filter_author_history_key() { + let mut app = App::test_default_fully_populated(); + app.push_navigation_stack(ActiveReadarrBlock::AuthorHistory.into()); + + AuthorDetailsHandler::new( + DEFAULT_KEYBINDINGS.filter.key, + &mut app, + ActiveReadarrBlock::AuthorHistory, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::FilterAuthorHistory.into()); + } } #[test] @@ -1012,6 +1087,15 @@ mod tests { #[test] fn test_extract_author_id() { let mut app = App::test_default_fully_populated(); + let author = app.data.readarr_data.authors.current_selection().clone(); + let mut decoy_author = author.clone(); + decoy_author.id = 999; + app + .data + .readarr_data + .authors + .set_items(vec![decoy_author, author]); + app.data.readarr_data.authors.select_index(Some(1)); let author_id = AuthorDetailsHandler::new( DEFAULT_KEYBINDINGS.esc.key, @@ -1027,6 +1111,15 @@ mod tests { #[test] fn test_extract_book_id() { let mut app = App::test_default_fully_populated(); + let book = app.data.readarr_data.books.current_selection().clone(); + let mut decoy_book = book.clone(); + decoy_book.id = 999; + app + .data + .readarr_data + .books + .set_items(vec![decoy_book, book]); + app.data.readarr_data.books.select_index(Some(1)); let book_id = AuthorDetailsHandler::new( DEFAULT_KEYBINDINGS.esc.key, diff --git a/src/handlers/readarr_handlers/library/book_details_handler_tests.rs b/src/handlers/readarr_handlers/library/book_details_handler_tests.rs index e092410c..cfdf6808 100644 --- a/src/handlers/readarr_handlers/library/book_details_handler_tests.rs +++ b/src/handlers/readarr_handlers/library/book_details_handler_tests.rs @@ -494,7 +494,9 @@ mod tests { fn test_manual_book_search_confirm_prompt_submit() { let mut app = App::test_default(); app.data.readarr_data.prompt_confirm = true; - app.data.readarr_data.book_details_modal = Some(book_details_modal()); + let mut modal = book_details_modal(); + modal.book_releases.select_index(Some(1)); + app.data.readarr_data.book_details_modal = Some(modal); app.push_navigation_stack(ActiveReadarrBlock::ManualBookSearch.into()); app.push_navigation_stack(ActiveReadarrBlock::ManualBookSearchConfirmPrompt.into()); @@ -509,8 +511,8 @@ mod tests { assert_eq!( app.data.readarr_data.prompt_confirm_action, Some(ReadarrEvent::DownloadRelease(ReleaseDownloadBody { - guid: "guid-1".to_owned(), - indexer_id: 1, + guid: "guid-2".to_owned(), + indexer_id: 2, })) ); assert_navigation_pushed!(app, ActiveReadarrBlock::ManualBookSearch.into()); @@ -540,6 +542,7 @@ mod tests { let mut app = App::test_default(); app.data.readarr_data.prompt_confirm = true; app.data.readarr_data.books.set_items(books_vec()); + app.data.readarr_data.books.select_index(Some(1)); app.data.readarr_data.book_details_modal = Some(book_details_modal()); app.push_navigation_stack(ActiveReadarrBlock::BookDetails.into()); app.push_navigation_stack(ActiveReadarrBlock::AutomaticallySearchBookPrompt.into()); @@ -583,7 +586,9 @@ mod tests { fn test_delete_book_file_prompt_submit() { let mut app = App::test_default(); app.data.readarr_data.prompt_confirm = true; - app.data.readarr_data.book_details_modal = Some(book_details_modal()); + let mut modal = book_details_modal(); + modal.book_files.select_index(Some(1)); + app.data.readarr_data.book_details_modal = Some(modal); app.push_navigation_stack(ActiveReadarrBlock::BookDetails.into()); app.push_navigation_stack(ActiveReadarrBlock::DeleteBookFilePrompt.into()); @@ -810,6 +815,7 @@ mod tests { fn test_automatically_search_book_prompt_confirm() { let mut app = App::test_default(); app.data.readarr_data.books.set_items(books_vec()); + app.data.readarr_data.books.select_index(Some(1)); app.data.readarr_data.book_details_modal = Some(book_details_modal()); app.push_navigation_stack(ActiveReadarrBlock::BookDetails.into()); app.push_navigation_stack(ActiveReadarrBlock::AutomaticallySearchBookPrompt.into()); @@ -833,7 +839,9 @@ mod tests { #[test] fn test_delete_book_file_prompt_confirm() { let mut app = App::test_default(); - app.data.readarr_data.book_details_modal = Some(book_details_modal()); + let mut modal = book_details_modal(); + modal.book_files.select_index(Some(1)); + app.data.readarr_data.book_details_modal = Some(modal); app.push_navigation_stack(ActiveReadarrBlock::BookDetails.into()); app.push_navigation_stack(ActiveReadarrBlock::DeleteBookFilePrompt.into()); @@ -856,7 +864,9 @@ mod tests { #[test] fn test_manual_book_search_confirm_prompt_confirm() { let mut app = App::test_default(); - app.data.readarr_data.book_details_modal = Some(book_details_modal()); + let mut modal = book_details_modal(); + modal.book_releases.select_index(Some(1)); + app.data.readarr_data.book_details_modal = Some(modal); app.push_navigation_stack(ActiveReadarrBlock::ManualBookSearch.into()); app.push_navigation_stack(ActiveReadarrBlock::ManualBookSearchConfirmPrompt.into()); @@ -872,12 +882,63 @@ mod tests { assert_eq!( app.data.readarr_data.prompt_confirm_action, Some(ReadarrEvent::DownloadRelease(ReleaseDownloadBody { - guid: "guid-1".to_owned(), - indexer_id: 1, + guid: "guid-2".to_owned(), + indexer_id: 2, })) ); assert_navigation_popped!(app, ActiveReadarrBlock::ManualBookSearch.into()); } + + #[test] + fn test_search_editions_key() { + let mut app = App::test_default(); + app.data.readarr_data.book_details_modal = Some(book_details_modal()); + app.push_navigation_stack(ActiveReadarrBlock::BookDetails.into()); + + BookDetailsHandler::new( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveReadarrBlock::BookDetails, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::SearchEditions.into()); + } + + #[test] + fn test_search_book_history_key() { + let mut app = App::test_default(); + app.data.readarr_data.book_details_modal = Some(book_details_modal()); + app.push_navigation_stack(ActiveReadarrBlock::BookHistory.into()); + + BookDetailsHandler::new( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveReadarrBlock::BookHistory, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::SearchBookHistory.into()); + } + + #[test] + fn test_filter_book_history_key() { + let mut app = App::test_default(); + app.data.readarr_data.book_details_modal = Some(book_details_modal()); + app.push_navigation_stack(ActiveReadarrBlock::BookHistory.into()); + + BookDetailsHandler::new( + DEFAULT_KEYBINDINGS.filter.key, + &mut app, + ActiveReadarrBlock::BookHistory, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::FilterBookHistory.into()); + } } #[test] @@ -1057,26 +1118,47 @@ mod tests { } fn book_files_vec() -> Vec { - vec![BookFile { - id: 11, - author_id: 1, - book_id: 1, - path: "/nfs/books/Test Author/Test Book.epub".to_owned(), - size: 1024, - quality: QualityWrapper { - quality: Quality { - name: "EPUB".to_owned(), + vec![ + BookFile { + id: 999, + author_id: 1, + book_id: 1, + path: "/nfs/books/Test Author/Decoy Book.epub".to_owned(), + size: 2048, + quality: QualityWrapper { + quality: Quality { + name: "MOBI".to_owned(), + }, }, + ..BookFile::default() }, - ..BookFile::default() - }] + BookFile { + id: 11, + author_id: 1, + book_id: 1, + path: "/nfs/books/Test Author/Test Book.epub".to_owned(), + size: 1024, + quality: QualityWrapper { + quality: Quality { + name: "EPUB".to_owned(), + }, + }, + ..BookFile::default() + }, + ] } fn books_vec() -> Vec { - vec![Book { - id: 7, - ..Book::default() - }] + vec![ + Book { + id: 999, + ..Book::default() + }, + Book { + id: 7, + ..Book::default() + }, + ] } fn history_vec() -> Vec { diff --git a/src/handlers/readarr_handlers/library/delete_author_handler_tests.rs b/src/handlers/readarr_handlers/library/delete_author_handler_tests.rs index ef7d7c7a..fcd4eef0 100644 --- a/src/handlers/readarr_handlers/library/delete_author_handler_tests.rs +++ b/src/handlers/readarr_handlers/library/delete_author_handler_tests.rs @@ -138,7 +138,8 @@ mod tests { app.data.readarr_data.prompt_confirm = true; app.data.readarr_data.delete_files = false; app.data.readarr_data.add_import_list_exclusion = true; - app.data.readarr_data.authors.set_items(vec![author()]); + app.data.readarr_data.authors.set_items(authors_vec()); + app.data.readarr_data.authors.select_index(Some(1)); let expected_delete_author_params = DeleteParams { id: 42, delete_files: false, @@ -321,7 +322,8 @@ mod tests { app.push_navigation_stack(ActiveReadarrBlock::DeleteAuthorPrompt.into()); app.data.readarr_data.delete_files = true; app.data.readarr_data.add_import_list_exclusion = false; - app.data.readarr_data.authors.set_items(vec![author()]); + app.data.readarr_data.authors.set_items(authors_vec()); + app.data.readarr_data.authors.select_index(Some(1)); let expected_delete_author_params = DeleteParams { id: 42, delete_files: true, @@ -362,7 +364,8 @@ mod tests { app.push_navigation_stack(ActiveReadarrBlock::DeleteAuthorPrompt.into()); app.data.readarr_data.delete_files = true; app.data.readarr_data.add_import_list_exclusion = false; - app.data.readarr_data.authors.set_items(vec![author()]); + app.data.readarr_data.authors.set_items(authors_vec()); + app.data.readarr_data.authors.select_index(Some(1)); app.data.readarr_data.selected_block = BlockSelectionState::new(DELETE_AUTHOR_SELECTION_BLOCKS); app @@ -423,7 +426,8 @@ mod tests { #[test] fn test_build_delete_author_params() { let mut app = App::test_default(); - app.data.readarr_data.authors.set_items(vec![author()]); + app.data.readarr_data.authors.set_items(authors_vec()); + app.data.readarr_data.authors.select_index(Some(1)); app.data.readarr_data.delete_files = true; app.data.readarr_data.add_import_list_exclusion = false; let expected_delete_author_params = DeleteParams { @@ -481,4 +485,14 @@ mod tests { ..Author::default() } } + + fn authors_vec() -> Vec { + vec![ + Author { + id: 999, + ..Author::default() + }, + author(), + ] + } } diff --git a/src/handlers/readarr_handlers/library/delete_book_handler_tests.rs b/src/handlers/readarr_handlers/library/delete_book_handler_tests.rs index 064e2dee..a6b8113b 100644 --- a/src/handlers/readarr_handlers/library/delete_book_handler_tests.rs +++ b/src/handlers/readarr_handlers/library/delete_book_handler_tests.rs @@ -129,7 +129,8 @@ mod tests { app.data.readarr_data.prompt_confirm = true; app.data.readarr_data.delete_files = false; app.data.readarr_data.add_import_list_exclusion = true; - app.data.readarr_data.books.set_items(vec![book()]); + app.data.readarr_data.books.set_items(books_vec()); + app.data.readarr_data.books.select_index(Some(1)); let expected_delete_book_params = DeleteParams { id: 42, delete_files: false, @@ -309,7 +310,8 @@ mod tests { app.push_navigation_stack(ActiveReadarrBlock::DeleteBookPrompt.into()); app.data.readarr_data.delete_files = true; app.data.readarr_data.add_import_list_exclusion = false; - app.data.readarr_data.books.set_items(vec![book()]); + app.data.readarr_data.books.set_items(books_vec()); + app.data.readarr_data.books.select_index(Some(1)); let expected_delete_book_params = DeleteParams { id: 42, delete_files: true, @@ -349,7 +351,8 @@ mod tests { app.push_navigation_stack(ActiveReadarrBlock::DeleteBookPrompt.into()); app.data.readarr_data.delete_files = true; app.data.readarr_data.add_import_list_exclusion = false; - app.data.readarr_data.books.set_items(vec![book()]); + app.data.readarr_data.books.set_items(books_vec()); + app.data.readarr_data.books.select_index(Some(1)); app.data.readarr_data.selected_block = BlockSelectionState::new(DELETE_BOOK_SELECTION_BLOCKS); app .data @@ -409,7 +412,8 @@ mod tests { #[test] fn test_build_delete_book_params() { let mut app = App::test_default(); - app.data.readarr_data.books.set_items(vec![book()]); + app.data.readarr_data.books.set_items(books_vec()); + app.data.readarr_data.books.select_index(Some(1)); app.data.readarr_data.delete_files = true; app.data.readarr_data.add_import_list_exclusion = false; let expected_delete_book_params = DeleteParams { @@ -467,4 +471,14 @@ mod tests { ..Book::default() } } + + fn books_vec() -> Vec { + vec![ + Book { + id: 999, + ..Book::default() + }, + book(), + ] + } } diff --git a/src/handlers/readarr_handlers/library/edit_author_handler_tests.rs b/src/handlers/readarr_handlers/library/edit_author_handler_tests.rs index e22b0bd9..6078c466 100644 --- a/src/handlers/readarr_handlers/library/edit_author_handler_tests.rs +++ b/src/handlers/readarr_handlers/library/edit_author_handler_tests.rs @@ -1323,18 +1323,32 @@ mod tests { edit_author_modal .quality_profile_list .set_items(vec!["Lossless".to_owned(), "HD - 1080p".to_owned()]); + edit_author_modal.quality_profile_list.state.select(Some(1)); edit_author_modal .metadata_profile_list .set_items(vec!["Standard".to_owned(), "Full".to_owned()]); + edit_author_modal + .metadata_profile_list + .state + .select(Some(1)); edit_author_modal .monitor_list .set_items(Vec::from_iter(NewItemMonitorType::iter())); + edit_author_modal.monitor_list.state.select(Some(1)); app.data.readarr_data.edit_author_modal = Some(edit_author_modal); - app.data.readarr_data.authors.set_items(vec![Author { - id: 42, - monitored: false, - ..Author::default() - }]); + app.data.readarr_data.authors.set_items(vec![ + Author { + id: 999, + monitored: false, + ..Author::default() + }, + Author { + id: 42, + monitored: false, + ..Author::default() + }, + ]); + app.data.readarr_data.authors.select_index(Some(1)); app.data.readarr_data.quality_profile_map = BiMap::from_iter([ (1111, "Lossless".to_owned()), (2222, "HD - 1080p".to_owned()), @@ -1349,9 +1363,9 @@ mod tests { EditAuthorParams { author_id: 42, monitored: Some(false), - monitor_new_items: Some(NewItemMonitorType::All), - quality_profile_id: Some(1111), - metadata_profile_id: Some(3333), + monitor_new_items: Some(NewItemMonitorType::None), + quality_profile_id: Some(2222), + metadata_profile_id: Some(4444), root_folder_path: Some("/nfs/Test Path".to_owned()), tag_input_string: Some("usenet, testing".to_owned()), ..EditAuthorParams::default() diff --git a/src/handlers/readarr_handlers/library/library_handler_tests.rs b/src/handlers/readarr_handlers/library/library_handler_tests.rs index ebd1f1dd..515805c8 100644 --- a/src/handlers/readarr_handlers/library/library_handler_tests.rs +++ b/src/handlers/readarr_handlers/library/library_handler_tests.rs @@ -571,11 +571,8 @@ mod tests { #[test] fn test_toggle_monitoring_key() { let mut app = App::test_default(); - app - .data - .readarr_data - .authors - .set_items(vec![Author::default()]); + app.data.readarr_data.authors.set_items(authors_vec()); + app.data.readarr_data.authors.select_index(Some(1)); app.push_navigation_stack(ActiveReadarrBlock::Authors.into()); app.is_routing = false; @@ -592,7 +589,7 @@ mod tests { assert!(app.is_routing); assert_some_eq_x!( &app.data.readarr_data.prompt_confirm_action, - &ReadarrEvent::ToggleAuthorMonitoring(0) + &ReadarrEvent::ToggleAuthorMonitoring(2) ); } @@ -704,6 +701,40 @@ mod tests { assert!(!app.should_refresh); } + #[test] + fn test_search_authors_key() { + let mut app = App::test_default(); + app.data.readarr_data.authors.set_items(authors_vec()); + app.push_navigation_stack(ActiveReadarrBlock::Authors.into()); + + LibraryHandler::new( + DEFAULT_KEYBINDINGS.search.key, + &mut app, + ActiveReadarrBlock::Authors, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::SearchAuthors.into()); + } + + #[test] + fn test_filter_authors_key() { + let mut app = App::test_default(); + app.data.readarr_data.authors.set_items(authors_vec()); + app.push_navigation_stack(ActiveReadarrBlock::Authors.into()); + + LibraryHandler::new( + DEFAULT_KEYBINDINGS.filter.key, + &mut app, + ActiveReadarrBlock::Authors, + None, + ) + .handle(); + + assert_navigation_pushed!(app, ActiveReadarrBlock::FilterAuthors.into()); + } + #[test] fn test_update_all_authors_prompt_confirm() { let mut app = App::test_default(); diff --git a/src/handlers/readarr_handlers/root_folders/add_root_folder_handler_tests.rs b/src/handlers/readarr_handlers/root_folders/add_root_folder_handler_tests.rs index be9c5ada..c063253c 100644 --- a/src/handlers/readarr_handlers/root_folders/add_root_folder_handler_tests.rs +++ b/src/handlers/readarr_handlers/root_folders/add_root_folder_handler_tests.rs @@ -1649,8 +1649,8 @@ mod tests { ) .build_add_root_folder_body(); - assert_eq!(add_root_folder_body.default_quality_profile_id, 2222); - assert_eq!(add_root_folder_body.default_metadata_profile_id, 4444); + assert_eq!(add_root_folder_body.default_quality_profile_id, 1111); + assert_eq!(add_root_folder_body.default_metadata_profile_id, 3333); } #[test] @@ -1713,15 +1713,28 @@ mod tests { add_root_folder_modal .quality_profile_list .set_items(vec!["EPUB".to_owned(), "MOBI".to_owned()]); + add_root_folder_modal + .quality_profile_list + .state + .select(Some(1)); add_root_folder_modal .metadata_profile_list .set_items(vec!["Standard".to_owned(), "Comprehensive".to_owned()]); + add_root_folder_modal + .metadata_profile_list + .state + .select(Some(1)); add_root_folder_modal .monitor_list .set_items(Vec::from_iter(MonitorType::iter())); + add_root_folder_modal.monitor_list.state.select(Some(1)); add_root_folder_modal .monitor_new_items_list .set_items(Vec::from_iter(NewItemMonitorType::iter())); + add_root_folder_modal + .monitor_new_items_list + .state + .select(Some(1)); add_root_folder_modal } @@ -1739,10 +1752,10 @@ mod tests { AddReadarrRootFolderBody { name: "Test Name".to_owned(), path: "/nfs/Test Path".to_owned(), - default_quality_profile_id: 1111, - default_metadata_profile_id: 3333, - default_monitor_option: MonitorType::All, - default_new_item_monitor_option: NewItemMonitorType::All, + default_quality_profile_id: 2222, + default_metadata_profile_id: 4444, + default_monitor_option: MonitorType::Future, + default_new_item_monitor_option: NewItemMonitorType::None, default_tags: Vec::new(), tag_input_string: Some("usenet, testing".to_owned()), }