From 82f30f126daaa75275b5ca9c5fa4dd7165a4de14 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Fri, 12 Dec 2025 15:44:11 -0700 Subject: [PATCH] test: Implemented UI snapshot tests --- Cargo.lock | 12 + Cargo.toml | 1 + proptest-regressions/ui/ui_property_tests.txt | 9 + src/handlers/mod.rs | 10 - src/network/network_tests.rs | 14 - src/ui/mod.rs | 4 + .../radarr_ui/blocklist/blocklist_ui_tests.rs | 58 +++- ..._blocklist_ui_renders_empty_blocklist.snap | 5 + ...s__blocklist_ui_renders_loading_state.snap | 8 + ...klist_ui_renders_with_blocklist_items.snap | 8 + .../collection_details_ui_tests.rs | 29 ++ .../collections/collections_ui_tests.rs | 30 ++ .../collections/edit_collection_ui_tests.rs | 34 ++- ...details_ui_renders_collection_details.snap | 30 ++ ...lections_ui_renders_empty_collections.snap | 8 + ..._collections_ui_renders_loading_state.snap | 8 + ...tion_ui_renders_edit_collection_modal.snap | 28 ++ .../radarr_ui/downloads/downloads_ui_tests.rs | 63 ++++ ..._downloads_ui_renders_empty_downloads.snap | 5 + ...s__downloads_ui_renders_loading_state.snap | 8 + ...__downloads_ui_renders_with_downloads.snap | 8 + .../indexers/edit_indexer_ui_tests.rs | 51 +++- .../indexers/indexer_settings_ui_tests.rs | 21 +- .../radarr_ui/indexers/indexers_ui_tests.rs | 60 ++++ ...indexer_ui_renders_edit_indexer_modal.snap | 27 ++ ..._settings_ui_renders_indexer_settings.snap | 27 ++ ...s__indexers_ui_renders_empty_indexers.snap | 5 + ...ts__indexers_ui_renders_loading_state.snap | 8 + ...ts__indexers_ui_renders_with_indexers.snap | 8 + ...all_indexers_ui_renders_loading_state.snap | 30 ++ .../indexers/test_all_indexers_ui_tests.rs | 19 ++ .../radarr_ui/library/add_movie_ui_tests.rs | 30 ++ .../library/delete_movie_ui_tests.rs | 31 +- .../radarr_ui/library/edit_movie_ui_tests.rs | 35 ++- .../library/movie_details_ui_tests.rs | 101 +++++++ ...s__add_movie_ui_renders_loading_state.snap | 29 ++ ...ts__add_movie_ui_renders_search_input.snap | 29 ++ ..._movie_ui_renders_delete_movie_prompt.snap | 24 ++ ...dit_movie_ui_renders_edit_movie_modal.snap | 28 ++ ...ovie_details_ui_renders_loading_state.snap | 30 ++ ..._details_ui_renders_manual_search_tab.snap | 30 ++ ..._details_ui_renders_movie_details_tab.snap | 30 ++ ..._details_ui_renders_movie_history_tab.snap | 30 ++ src/ui/radarr_ui/mod.rs | 4 + src/ui/radarr_ui/radarr_ui_tests.rs | 81 +++++- .../root_folders/root_folders_ui_tests.rs | 72 +++++ ...ot_folders_ui_renders_add_root_folder.snap | 20 ++ ...folders_ui_renders_empty_root_folders.snap | 5 + ...root_folders_ui_renders_loading_state.snap | 8 + ..._folders_ui_renders_with_root_folders.snap | 8 + ...ests__radarr_ui_renders_downloads_tab.snap | 34 +++ ...radarr_ui_renders_downloads_tab_empty.snap | 34 +++ ..._tests__radarr_ui_renders_library_tab.snap | 34 +++ ...stem_details_ui_renders_loading_tasks.snap | 30 ++ ...tests__system_details_ui_renders_logs.snap | 30 ++ ...ests__system_ui_renders_loading_state.snap | 34 +++ ..._tests__system_ui_renders_system_menu.snap | 34 +++ .../system/system_details_ui_tests.rs | 36 +++ src/ui/radarr_ui/system/system_ui_tests.rs | 27 ++ .../sonarr_ui/blocklist/blocklist_ui_tests.rs | 62 +++- ..._blocklist_ui_renders_empty_blocklist.snap | 5 + ...s__blocklist_ui_renders_loading_state.snap | 8 + ...klist_ui_renders_with_blocklist_items.snap | 8 + .../sonarr_ui/downloads/downloads_ui_tests.rs | 65 +++++ ..._downloads_ui_renders_empty_downloads.snap | 5 + ...s__downloads_ui_renders_loading_state.snap | 8 + ...__downloads_ui_renders_with_downloads.snap | 8 + src/ui/sonarr_ui/history/history_ui_tests.rs | 62 +++- ...sts__history_ui_renders_empty_history.snap | 5 + ...sts__history_ui_renders_loading_state.snap | 8 + ...history_ui_renders_with_history_items.snap | 8 + .../indexers/edit_indexer_ui_tests.rs | 55 +++- .../indexers/indexer_settings_ui_tests.rs | 25 +- .../sonarr_ui/indexers/indexers_ui_tests.rs | 64 +++++ ...indexer_ui_renders_edit_indexer_modal.snap | 27 ++ ..._settings_ui_renders_indexer_settings.snap | 26 ++ ...s__indexers_ui_renders_empty_indexers.snap | 5 + ...ts__indexers_ui_renders_loading_state.snap | 8 + ...ts__indexers_ui_renders_with_indexers.snap | 8 + ...all_indexers_ui_renders_loading_state.snap | 30 ++ .../indexers/test_all_indexers_ui_tests.rs | 19 ++ .../sonarr_ui/library/add_series_ui_tests.rs | 34 +++ .../library/delete_series_ui_tests.rs | 33 ++- .../sonarr_ui/library/edit_series_ui_tests.rs | 41 ++- .../library/episode_details_ui_tests.rs | 115 +++++++- src/ui/sonarr_ui/library/library_ui_tests.rs | 37 +++ .../library/season_details_ui_tests.rs | 123 ++++++++ .../library/series_details_ui_tests.rs | 34 +++ ...__add_series_ui_renders_loading_state.snap | 29 ++ ...s__add_series_ui_renders_search_input.snap | 29 ++ ...eries_ui_renders_delete_series_toggle.snap | 24 ++ ...t_series_ui_renders_edit_series_modal.snap | 30 ++ ...etails_ui_renders_episode_details_tab.snap | 30 ++ ...etails_ui_renders_episode_history_tab.snap | 30 ++ ...sode_details_ui_renders_loading_state.snap | 5 + ..._details_ui_renders_manual_search_tab.snap | 30 ++ ...ests__library_ui_renders_empty_series.snap | 5 + ...sts__library_ui_renders_loading_state.snap | 8 + ...eason_details_ui_renders_episodes_tab.snap | 5 + ...ason_details_ui_renders_loading_state.snap | 5 + ..._details_ui_renders_manual_search_tab.snap | 31 ++ ...details_ui_renders_season_history_tab.snap | 31 ++ ...ies_details_ui_renders_series_details.snap | 33 +++ .../root_folders/root_folders_ui_tests.rs | 76 +++++ ...ot_folders_ui_renders_add_root_folder.snap | 20 ++ ...folders_ui_renders_empty_root_folders.snap | 5 + ...root_folders_ui_renders_loading_state.snap | 8 + ..._folders_ui_renders_with_root_folders.snap | 8 + ...ests__sonarr_ui_renders_downloads_tab.snap | 34 +++ ..._tests__sonarr_ui_renders_history_tab.snap | 34 +++ ..._tests__sonarr_ui_renders_library_tab.snap | 34 +++ src/ui/sonarr_ui/sonarr_ui_tests.rs | 94 +++++- ...stem_details_ui_renders_loading_tasks.snap | 30 ++ ...tests__system_details_ui_renders_logs.snap | 30 ++ ...ests__system_details_ui_renders_tasks.snap | 30 ++ ...ests__system_ui_renders_loading_state.snap | 34 +++ ..._tests__system_ui_renders_system_menu.snap | 34 +++ .../system/system_details_ui_tests.rs | 52 ++++ src/ui/sonarr_ui/system/system_ui_tests.rs | 31 ++ src/ui/ui_property_tests.rs | 268 ++++++++++++++++++ src/ui/ui_test_utils.rs | 126 ++++++++ 121 files changed, 3720 insertions(+), 43 deletions(-) create mode 100644 proptest-regressions/ui/ui_property_tests.txt create mode 100644 src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_empty_blocklist.snap create mode 100644 src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_with_blocklist_items.snap create mode 100644 src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__collection_details_ui_renders_collection_details.snap create mode 100644 src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_empty_collections.snap create mode 100644 src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__edit_collection_ui__edit_collection_ui_tests__tests__edit_collection_ui_renders_edit_collection_modal.snap create mode 100644 src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_empty_downloads.snap create mode 100644 src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_with_downloads.snap create mode 100644 src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__edit_indexer_ui_renders_edit_indexer_modal.snap create mode 100644 src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__indexer_settings_ui_renders_indexer_settings.snap create mode 100644 src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_empty_indexers.snap create mode 100644 src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_with_indexers.snap create mode 100644 src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_search_input.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__delete_movie_ui__delete_movie_ui_tests__tests__delete_movie_ui_renders_delete_movie_prompt.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__edit_movie_ui__edit_movie_ui_tests__tests__edit_movie_ui_renders_edit_movie_modal.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_manual_search_tab.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_details_tab.snap create mode 100644 src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_history_tab.snap create mode 100644 src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_add_root_folder.snap create mode 100644 src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_empty_root_folders.snap create mode 100644 src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_with_root_folders.snap create mode 100644 src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab.snap create mode 100644 src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab_empty.snap create mode 100644 src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_library_tab.snap create mode 100644 src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_loading_tasks.snap create mode 100644 src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_logs.snap create mode 100644 src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_loading_state.snap create mode 100644 src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_system_menu.snap create mode 100644 src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_empty_blocklist.snap create mode 100644 src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_with_blocklist_items.snap create mode 100644 src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_empty_downloads.snap create mode 100644 src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_with_downloads.snap create mode 100644 src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_empty_history.snap create mode 100644 src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_with_history_items.snap create mode 100644 src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_edit_indexer_modal.snap create mode 100644 src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_indexer_settings.snap create mode 100644 src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap create mode 100644 src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_with_indexers.snap create mode 100644 src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_search_input.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__delete_series_ui__delete_series_ui_tests__tests__snapshot_tests__delete_series_ui_renders_delete_series_toggle.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__edit_series_ui__edit_series_ui_tests__tests__snapshot_tests__edit_series_ui_renders_edit_series_modal.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_details_tab.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_history_tab.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_manual_search_tab.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_empty_series.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_episodes_tab.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_manual_search_tab.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_season_history_tab.snap create mode 100644 src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__series_details_ui__series_details_ui_tests__tests__snapshot_tests__series_details_ui_renders_series_details.snap create mode 100644 src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_add_root_folder.snap create mode 100644 src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_empty_root_folders.snap create mode 100644 src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_with_root_folders.snap create mode 100644 src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_downloads_tab.snap create mode 100644 src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_history_tab.snap create mode 100644 src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_library_tab.snap create mode 100644 src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_loading_tasks.snap create mode 100644 src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_logs.snap create mode 100644 src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_tasks.snap create mode 100644 src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_loading_state.snap create mode 100644 src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_system_menu.snap create mode 100644 src/ui/ui_property_tests.rs create mode 100644 src/ui/ui_test_utils.rs diff --git a/Cargo.lock b/Cargo.lock index 6982bea..8f47762 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1199,6 +1199,17 @@ version = "2.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" +[[package]] +name = "insta" +version = "1.44.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5c943d4415edd8153251b6f197de5eb1640e56d84e8d9159bea190421c73698" +dependencies = [ + "console", + "once_cell", + "similar", +] + [[package]] name = "instability" version = "0.3.9" @@ -1401,6 +1412,7 @@ dependencies = [ "human-panic", "indicatif", "indoc", + "insta", "itertools 0.14.0", "log", "log4rs", diff --git a/Cargo.toml b/Cargo.toml index f076d6a..774ad50 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -77,6 +77,7 @@ proptest = "1.6.0" rstest = "0.25.0" serial_test = "3.2.0" assertables = "9.8.2" +insta = "1.41.1" [dev-dependencies.cargo-husky] version = "1" diff --git a/proptest-regressions/ui/ui_property_tests.txt b/proptest-regressions/ui/ui_property_tests.txt new file mode 100644 index 0000000..621f11a --- /dev/null +++ b/proptest-regressions/ui/ui_property_tests.txt @@ -0,0 +1,9 @@ +# Seeds for failure cases proptest has generated in the past. It is +# automatically read and these particular cases re-run before any +# novel cases are generated. +# +# It is recommended to check this file in to source control so that +# everyone who runs the test benefits from these saved cases. +cc 24ae243412a324cb46c36cb4f629ddd4c9326b1479d1186d9b5545ac5e86dbba # shrinks to num_scroll_attempts = 0 +cc c06a1cc1e4740b2498c50d7be64715bf09ef3ac4cf3bb3642f960578a3e06c74 # shrinks to is_loading = false, num_items = 1 +cc 930207899afea2d389c7fa3974e31c2eb1803e71bcbd8179246c795903905ec7 # shrinks to parent_width = 20, parent_height = 12, percent_x = 1, percent_y = 1 diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 6cb0691..7e180c6 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -93,17 +93,7 @@ pub trait KeyEventHandler<'a, 'b, T: Into + Copy> { fn handle_submit(&mut self); fn handle_esc(&mut self); fn handle_char_key_event(&mut self); - - /// Returns a mutable reference to the application state. - /// - /// This method is used by the trait-based table handler to modify app state during - /// table operations (e.g., navigation stack, loading flags). fn app_mut(&mut self) -> &mut App<'b>; - - /// Returns the current navigation route. - /// - /// This method is used by the trait-based table handler to determine which screen - /// or mode is currently active, enabling context-aware event handling. fn current_route(&self) -> Route; } diff --git a/src/network/network_tests.rs b/src/network/network_tests.rs index 745ef9d..7b83b9c 100644 --- a/src/network/network_tests.rs +++ b/src/network/network_tests.rs @@ -730,17 +730,14 @@ pub(in crate::network) mod test_utils { network::{Network, NetworkEvent, NetworkResource, RequestMethod}, }; - /// Creates a test HTTP client pub fn test_client() -> Client { Client::new() } - /// Creates a test cancellation token pub fn test_cancellation_token() -> CancellationToken { CancellationToken::new() } - /// Creates a test network instance pub fn test_network<'a, 'b>(app: &'a Arc>>) -> Network<'a, 'b> { Network::new(app, test_cancellation_token(), test_client()) } @@ -755,28 +752,23 @@ pub(in crate::network) mod test_utils { } impl MockServarrApi { - /// Create a GET request builder pub fn get() -> Self { Self::new(RequestMethod::Get) } - /// Create a POST request builder pub fn post() -> Self { Self::new(RequestMethod::Post) } - /// Create a PUT request builder #[allow(dead_code)] pub fn put() -> Self { Self::new(RequestMethod::Put) } - /// Create a DELETE request builder pub fn delete() -> Self { Self::new(RequestMethod::Delete) } - /// Create a builder with a specific request method pub fn new(method: RequestMethod) -> Self { Self { method, @@ -788,37 +780,31 @@ pub(in crate::network) mod test_utils { } } - /// Set the expected request body pub fn with_request_body(mut self, body: Value) -> Self { self.request_body = Some(body); self } - /// Set the response body to return pub fn returns(mut self, body: Value) -> Self { self.response_body = Some(body); self } - /// Set the HTTP status code pub fn status(mut self, status: usize) -> Self { self.response_status = status; self } - /// Add a path suffix to the resource URL pub fn path(mut self, path: impl Into) -> Self { self.path = Some(path.into()); self } - /// Add query parameters pub fn query(mut self, params: impl Into) -> Self { self.query_params = Some(params.into()); self } - /// Build the mock for a specific network event pub async fn build_for( self, network_event: E, diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 75833bf..4968452 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -31,6 +31,10 @@ mod radarr_ui; mod sonarr_ui; mod styles; pub mod theme; +#[cfg(test)] +mod ui_property_tests; +#[cfg(test)] +pub mod ui_test_utils; mod utils; mod widgets; diff --git a/src/ui/radarr_ui/blocklist/blocklist_ui_tests.rs b/src/ui/radarr_ui/blocklist/blocklist_ui_tests.rs index c476ec5..42d3bdf 100644 --- a/src/ui/radarr_ui/blocklist/blocklist_ui_tests.rs +++ b/src/ui/radarr_ui/blocklist/blocklist_ui_tests.rs @@ -1,9 +1,14 @@ #[cfg(test)] mod tests { + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::radarr_models::BlocklistItem; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::blocklist::BlocklistUi; - use strum::IntoEnumIterator; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_blocklist_ui_accepts() { @@ -15,4 +20,55 @@ mod tests { } }); } + + #[test] + fn test_blocklist_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + BlocklistUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_blocklist_ui_renders_empty_blocklist() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); + app.data.radarr_data.blocklist = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + BlocklistUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_blocklist_ui_renders_with_blocklist_items() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); + app.data.radarr_data.blocklist = StatefulTable::default(); + app.data.radarr_data.blocklist.set_items(vec![ + BlocklistItem { + id: 1, + source_title: "Test.Movie.2023.1080p".to_owned(), + ..BlocklistItem::default() + }, + BlocklistItem { + id: 2, + source_title: "Another.Movie.2023.720p".to_owned(), + ..BlocklistItem::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + BlocklistUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_empty_blocklist.snap b/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_empty_blocklist.snap new file mode 100644 index 0000000..5be459a --- /dev/null +++ b/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_empty_blocklist.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/radarr_ui/blocklist/blocklist_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_loading_state.snap b/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_loading_state.snap new file mode 100644 index 0000000..0f40c50 --- /dev/null +++ b/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/blocklist/blocklist_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_with_blocklist_items.snap b/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_with_blocklist_items.snap new file mode 100644 index 0000000..6553ab2 --- /dev/null +++ b/src/ui/radarr_ui/blocklist/snapshots/managarr__ui__radarr_ui__blocklist__blocklist_ui_tests__tests__blocklist_ui_renders_with_blocklist_items.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/blocklist/blocklist_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Movie Title Source Title Languages Quality Formats Date +=> Test.Movie.2023.1080p 1970-01-01 00:00:0 + Another.Movie.2023.720p 1970-01-01 00:00:0 diff --git a/src/ui/radarr_ui/collections/collection_details_ui_tests.rs b/src/ui/radarr_ui/collections/collection_details_ui_tests.rs index fae0a22..23d1c7d 100644 --- a/src/ui/radarr_ui/collections/collection_details_ui_tests.rs +++ b/src/ui/radarr_ui/collections/collection_details_ui_tests.rs @@ -1,12 +1,17 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::radarr_models::{Collection, CollectionMovie}; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, }; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::collections::collection_details_ui::CollectionDetailsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_collection_details_ui_accepts() { @@ -33,4 +38,28 @@ mod tests { .into() )); } + + #[test] + fn test_collection_details_ui_renders_collection_details() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); + app.data.radarr_data.quality_profile_map = BiMap::from_iter(vec![(1, "HD - 1080p".to_owned())]); + app.data.radarr_data.collections = StatefulTable::default(); + app.data.radarr_data.collections.set_items(vec![Collection { + id: 1, + title: "Test Collection".into(), + quality_profile_id: 1, + movies: Some(vec![CollectionMovie { + title: "Movie 1".into(), + ..CollectionMovie::default() + }]), + ..Collection::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + CollectionDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/collections/collections_ui_tests.rs b/src/ui/radarr_ui/collections/collections_ui_tests.rs index 09cde4a..e3f4437 100644 --- a/src/ui/radarr_ui/collections/collections_ui_tests.rs +++ b/src/ui/radarr_ui/collections/collections_ui_tests.rs @@ -2,11 +2,15 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, COLLECTION_DETAILS_BLOCKS, COLLECTIONS_BLOCKS, EDIT_COLLECTION_BLOCKS, }; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::collections::CollectionsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_collections_ui_accepts() { @@ -23,4 +27,30 @@ mod tests { } }); } + + #[test] + fn test_collections_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + CollectionsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_collections_ui_renders_empty_collections() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); + app.data.radarr_data.collections = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + CollectionsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs b/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs index e458671..2dd05a6 100644 --- a/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs +++ b/src/ui/radarr_ui/collections/edit_collection_ui_tests.rs @@ -1,12 +1,19 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::radarr_models::Collection; + use crate::models::servarr_data::radarr::modals::EditCollectionModal; use crate::models::servarr_data::radarr::radarr_data::{ - ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS, + ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS, EDIT_COLLECTION_SELECTION_BLOCKS, }; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::collections::edit_collection_ui::EditCollectionUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_edit_collection_ui_accepts() { @@ -26,4 +33,29 @@ mod tests { .into() )); } + + #[test] + fn test_edit_collection_ui_renders_edit_collection_modal() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::EditCollectionRootFolderPathInput.into()); + app.data.radarr_data.quality_profile_map = BiMap::from_iter(vec![(1, "HD - 1080p".to_owned())]); + app.data.radarr_data.collections = StatefulTable::default(); + app.data.radarr_data.collections.set_items(vec![Collection { + id: 1, + title: "Test Collection".into(), + quality_profile_id: 1, + root_folder_path: Some("/movies".to_owned()), + ..Collection::default() + }]); + app.data.radarr_data.selected_block = + BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS); + app.data.radarr_data.edit_collection_modal = + Some(EditCollectionModal::from(&app.data.radarr_data)); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EditCollectionUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__collection_details_ui_renders_collection_details.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__collection_details_ui_renders_collection_details.snap new file mode 100644 index 0000000..776d581 --- /dev/null +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collection_details_ui__collection_details_ui_tests__tests__collection_details_ui_renders_collection_details.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/collections/collection_details_ui_tests.rs +expression: output +--- + + + + + ╭ Test Collection ─────────────────────────────────────────────────────────────────────╮ + │Overview: │ + │Root Folder Path: │ + │Quality Profile: HD - 1080p │ + │Minimum Availability: Announced │ + │Monitored: No │ + │ Movies ──────────────────────────────────────────────────────────────────────────────│ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_empty_collections.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_empty_collections.snap new file mode 100644 index 0000000..7cbbe61 --- /dev/null +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_empty_collections.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/collections/collections_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_loading_state.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_loading_state.snap new file mode 100644 index 0000000..7cbbe61 --- /dev/null +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__collections_ui_tests__tests__collections_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/collections/collections_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__edit_collection_ui__edit_collection_ui_tests__tests__edit_collection_ui_renders_edit_collection_modal.snap b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__edit_collection_ui__edit_collection_ui_tests__tests__edit_collection_ui_renders_edit_collection_modal.snap new file mode 100644 index 0000000..0d53eb0 --- /dev/null +++ b/src/ui/radarr_ui/collections/snapshots/managarr__ui__radarr_ui__collections__edit_collection_ui__edit_collection_ui_tests__tests__edit_collection_ui_renders_edit_collection_modal.snap @@ -0,0 +1,28 @@ +--- +source: src/ui/radarr_ui/collections/edit_collection_ui_tests.rs +expression: output +--- + + + + + + + ╭────────────────────── Edit - Test Collection ──────────────────────╮ + │ │ + │ │ + │ │ + │ ╭───╮ │ + │ Monitored: ╰───╯ │ + │ ╭───────────────────────────────╮ │ + │ Minimum Availability: │Announced ▼ │ │ + │ ╰───────────────────────────────╯ │ + │ ╭───────────────────────────────╮ │ + │ Quality Profile: │HD - 1080p ▼ │ │ + │ ╰───────────────────────────────╯ │ + │ ╭───────────────────────────────╮ │ + │ Root Folder: ╰───────────────────────────────╯ │ + │ ╭───╮ │ + │ Search on Add: │ │ │ + │ ╰───╯ │ + ╰──────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/downloads/downloads_ui_tests.rs b/src/ui/radarr_ui/downloads/downloads_ui_tests.rs index a1c4d9c..6ada6c4 100644 --- a/src/ui/radarr_ui/downloads/downloads_ui_tests.rs +++ b/src/ui/radarr_ui/downloads/downloads_ui_tests.rs @@ -2,9 +2,13 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::radarr_models::DownloadRecord; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::downloads::DownloadsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_downloads_ui_accepts() { @@ -16,4 +20,63 @@ mod tests { } }); } + + #[test] + fn test_downloads_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DownloadsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_downloads_ui_renders_empty_downloads() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); + app.data.radarr_data.downloads = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DownloadsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_downloads_ui_renders_with_downloads() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); + app.data.radarr_data.downloads = StatefulTable::default(); + app.data.radarr_data.downloads.set_items(vec![ + DownloadRecord { + id: 1, + movie_id: 1, + title: "Test Movie Download".to_owned(), + status: "downloading".to_owned(), + size: 1024 * 1024 * 1024, + sizeleft: 512 * 1024 * 1024, + ..DownloadRecord::default() + }, + DownloadRecord { + id: 2, + movie_id: 2, + title: "Another Movie Download".to_owned(), + status: "completed".to_owned(), + size: 2048 * 1024 * 1024, + sizeleft: 0, + ..DownloadRecord::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DownloadsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_empty_downloads.snap b/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_empty_downloads.snap new file mode 100644 index 0000000..74c15cb --- /dev/null +++ b/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_empty_downloads.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/radarr_ui/downloads/downloads_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_loading_state.snap b/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_loading_state.snap new file mode 100644 index 0000000..9d9848b --- /dev/null +++ b/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/downloads/downloads_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_with_downloads.snap b/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_with_downloads.snap new file mode 100644 index 0000000..df3d304 --- /dev/null +++ b/src/ui/radarr_ui/downloads/snapshots/managarr__ui__radarr_ui__downloads__downloads_ui_tests__tests__downloads_ui_renders_with_downloads.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/downloads/downloads_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Title Percent Compl Size Output Path Indexer Download Client +=> Test Movie Download 50% 1.00 GB + Another Movie Download 100% 2.00 GB diff --git a/src/ui/radarr_ui/indexers/edit_indexer_ui_tests.rs b/src/ui/radarr_ui/indexers/edit_indexer_ui_tests.rs index bf89691..f2d6ef0 100644 --- a/src/ui/radarr_ui/indexers/edit_indexer_ui_tests.rs +++ b/src/ui/radarr_ui/indexers/edit_indexer_ui_tests.rs @@ -1,9 +1,19 @@ #[cfg(test)] mod tests { - use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS}; + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::servarr_data::modals::EditIndexerModal; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, EDIT_INDEXER_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, + }; + use crate::models::servarr_models::{Indexer, IndexerField}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::indexers::edit_indexer_ui::EditIndexerUi; - use strum::IntoEnumIterator; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; + use serde_json::json; #[test] fn test_edit_indexer_ui_accepts() { @@ -15,4 +25,41 @@ mod tests { } }); } + + #[test] + fn test_edit_indexer_ui_renders_edit_indexer_modal() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::EditIndexerNameInput.into()); + app.data.radarr_data.indexers = StatefulTable::default(); + app.data.radarr_data.indexers.set_items(vec![Indexer { + id: 1, + name: Some("Test Indexer".to_owned()), + enable_rss: true, + priority: 25, + fields: Some(vec![ + IndexerField { + name: Some("baseUrl".to_owned()), + value: Some(json!("https://test.indexer.com")), + }, + IndexerField { + name: Some("apiKey".to_owned()), + value: Some(json!("test-api-key")), + }, + IndexerField { + name: Some("seedCriteria.seedRatio".to_owned()), + value: Some(json!(1.0)), + }, + ]), + ..Indexer::default() + }]); + app.data.radarr_data.selected_block = + BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); + app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::from(&app.data.radarr_data)); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EditIndexerUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs b/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs index e2cb89b..4c82258 100644 --- a/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs +++ b/src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs @@ -2,11 +2,15 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::radarr_models::IndexerSettings; use crate::models::servarr_data::radarr::radarr_data::{ - ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS, + ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS, INDEXER_SETTINGS_SELECTION_BLOCKS, }; use crate::ui::DrawUi; use crate::ui::radarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_indexer_settings_ui_accepts() { @@ -18,4 +22,19 @@ mod tests { } }); } + + #[test] + fn test_indexer_settings_ui_renders_indexer_settings() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::IndexerSettingsMinimumAgeInput.into()); + app.data.radarr_data.selected_block = + BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); + app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + IndexerSettingsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/indexers/indexers_ui_tests.rs b/src/ui/radarr_ui/indexers/indexers_ui_tests.rs index 214cded..bbb7480 100644 --- a/src/ui/radarr_ui/indexers/indexers_ui_tests.rs +++ b/src/ui/radarr_ui/indexers/indexers_ui_tests.rs @@ -2,11 +2,15 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, EDIT_INDEXER_BLOCKS, INDEXER_SETTINGS_BLOCKS, INDEXERS_BLOCKS, }; + use crate::models::servarr_models::Indexer; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::indexers::IndexersUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_indexers_ui_accepts() { @@ -24,4 +28,60 @@ mod tests { } }); } + + #[test] + fn test_indexers_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); + + let output = render_to_string_with_app(120, 30, &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(ActiveRadarrBlock::Indexers.into()); + app.data.radarr_data.indexers = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_with_indexers() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); + app.data.radarr_data.indexers = StatefulTable::default(); + app.data.radarr_data.indexers.set_items(vec![ + Indexer { + id: 1, + name: Some("Test Indexer 1".to_owned()), + enable_rss: true, + enable_automatic_search: true, + enable_interactive_search: true, + priority: 25, + ..Indexer::default() + }, + Indexer { + id: 2, + name: Some("Test Indexer 2".to_owned()), + enable_rss: false, + ..Indexer::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__edit_indexer_ui_renders_edit_indexer_modal.snap b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__edit_indexer_ui_renders_edit_indexer_modal.snap new file mode 100644 index 0000000..1fb62de --- /dev/null +++ b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__edit_indexer_ui_renders_edit_indexer_modal.snap @@ -0,0 +1,27 @@ +--- +source: src/ui/radarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + ╭───────────────────────────────── Edit Indexer ─────────────────────────────────╮ + │ │ + │ ╭─────────────────╮ ╭─────────────────╮ │ + │ Name: ╰─────────────────╯ URL: ╰─────────────────╯ │ + │ ╭───╮ ╭─────────────────╮ │ + │ ╭───╮ API Key: ╰─────────────────╯ │ + │ Enable Automatic Se╰───╯ ╭─────────────────╮ │ + │ ╭───╮ Tags: ╰─────────────────╯ │ + │ ╭─────────────────╮ │ + │ Indexer Priority ▴▾╰─────────────────╯ │ + │ │ + │ ╭──────────────────╮╭───────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰──────────────────╯╰───────────────────╯ │ + ╰──────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__indexer_settings_ui_renders_indexer_settings.snap b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__indexer_settings_ui_renders_indexer_settings.snap new file mode 100644 index 0000000..e5aa9f5 --- /dev/null +++ b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__indexer_settings_ui_renders_indexer_settings.snap @@ -0,0 +1,27 @@ +--- +source: src/ui/radarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + ╭──────────────────────── Configure All Indexer Settings ────────────────────────╮ + │ │ + │ ╭─────────────────╮ ╭─────────────────╮ │ + │ Minimum Age (minute╰─────────────────╯ Availability Delay ╰─────────────────╯ │ + │ ╭─────────────────╮ ╭─────────────────╮ │ + │ Retention (days) ▴▾╰─────────────────╯ RSS Sync Interval (╰─────────────────╯ │ + │ ╭─────────────────╮ ╭─────────────────╮ │ + │ Maximum Size (MB) ▴╰─────────────────╯ Whitelisted Subtitl╰─────────────────╯ │ + │ ╭───╮ ╭───╮ │ + │ Prefer Indexer Flag╰───╯ Allow Hardcoded Sub╰───╯ │ + │ │ + │ ╭──────────────────╮╭───────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰──────────────────╯╰───────────────────╯ │ + ╰──────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_empty_indexers.snap b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_empty_indexers.snap new file mode 100644 index 0000000..ee33805 --- /dev/null +++ b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_empty_indexers.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/radarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_loading_state.snap b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_loading_state.snap new file mode 100644 index 0000000..9ac0562 --- /dev/null +++ b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_with_indexers.snap b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_with_indexers.snap new file mode 100644 index 0000000..c4038d1 --- /dev/null +++ b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__indexers_ui_tests__tests__indexers_ui_renders_with_indexers.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Sea Priority Tags +=> Test Indexer 1 Enabled Enabled Enabled 25 + Test Indexer 2 Disabled Disabled Disabled 0 diff --git a/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap new file mode 100644 index 0000000..2ce3a04 --- /dev/null +++ b/src/ui/radarr_ui/indexers/snapshots/managarr__ui__radarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/indexers/test_all_indexers_ui_tests.rs +expression: output +--- + + + + + ╭ Test All Indexers ───────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/indexers/test_all_indexers_ui_tests.rs b/src/ui/radarr_ui/indexers/test_all_indexers_ui_tests.rs index 6b19994..d489b8a 100644 --- a/src/ui/radarr_ui/indexers/test_all_indexers_ui_tests.rs +++ b/src/ui/radarr_ui/indexers/test_all_indexers_ui_tests.rs @@ -2,9 +2,11 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::ui::DrawUi; use crate::ui::radarr_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() { @@ -16,4 +18,21 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_test_all_indexers_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + TestAllIndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/radarr_ui/library/add_movie_ui_tests.rs b/src/ui/radarr_ui/library/add_movie_ui_tests.rs index 417ffc5..9401a58 100644 --- a/src/ui/radarr_ui/library/add_movie_ui_tests.rs +++ b/src/ui/radarr_ui/library/add_movie_ui_tests.rs @@ -2,9 +2,12 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::HorizontallyScrollableText; use crate::models::servarr_data::radarr::radarr_data::{ADD_MOVIE_BLOCKS, ActiveRadarrBlock}; use crate::ui::DrawUi; use crate::ui::radarr_ui::library::add_movie_ui::AddMovieUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_add_movie_ui_accepts() { @@ -16,4 +19,31 @@ mod tests { } }); } + + #[test] + fn test_add_movie_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); + app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + AddMovieUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_add_movie_ui_renders_search_input() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); + app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + AddMovieUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/library/delete_movie_ui_tests.rs b/src/ui/radarr_ui/library/delete_movie_ui_tests.rs index 8fbd936..c9f17f2 100644 --- a/src/ui/radarr_ui/library/delete_movie_ui_tests.rs +++ b/src/ui/radarr_ui/library/delete_movie_ui_tests.rs @@ -1,10 +1,18 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::radarr_models::Movie; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, DELETE_MOVIE_BLOCKS, DELETE_MOVIE_SELECTION_BLOCKS, + }; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::library::delete_movie_ui::DeleteMovieUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_delete_movie_ui_accepts() { @@ -16,4 +24,25 @@ mod tests { } }); } + + #[test] + fn test_delete_movie_ui_renders_delete_movie_prompt() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); + app.data.radarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS); + app.data.radarr_data.movies = StatefulTable::default(); + app.data.radarr_data.movies.set_items(vec![Movie { + id: 1, + title: "Test Movie".into(), + quality_profile_id: 0, + ..Movie::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DeleteMovieUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/library/edit_movie_ui_tests.rs b/src/ui/radarr_ui/library/edit_movie_ui_tests.rs index a2d802e..b076c82 100644 --- a/src/ui/radarr_ui/library/edit_movie_ui_tests.rs +++ b/src/ui/radarr_ui/library/edit_movie_ui_tests.rs @@ -1,10 +1,19 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; - use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::radarr_models::Movie; + use crate::models::servarr_data::radarr::modals::EditMovieModal; + use crate::models::servarr_data::radarr::radarr_data::{ + ActiveRadarrBlock, EDIT_MOVIE_BLOCKS, EDIT_MOVIE_SELECTION_BLOCKS, + }; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::library::edit_movie_ui::EditMovieUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_edit_movie_ui_accepts() { @@ -16,4 +25,28 @@ mod tests { } }); } + + #[test] + fn test_edit_movie_ui_renders_edit_movie_modal() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::EditMoviePathInput.into()); + app.data.radarr_data.quality_profile_map = + BiMap::from_iter(vec![(1, "HD - 1080p".to_owned()), (2, "Any".to_owned())]); + app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); + app.data.radarr_data.movies = StatefulTable::default(); + app.data.radarr_data.movies.set_items(vec![Movie { + id: 1, + title: "Test Movie".into(), + path: "/movies/test".into(), + quality_profile_id: 1, + ..Movie::default() + }]); + app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::from(&app.data.radarr_data)); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EditMovieUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/library/movie_details_ui_tests.rs b/src/ui/radarr_ui/library/movie_details_ui_tests.rs index 1eb204e..66d3b0f 100644 --- a/src/ui/radarr_ui/library/movie_details_ui_tests.rs +++ b/src/ui/radarr_ui/library/movie_details_ui_tests.rs @@ -1,16 +1,22 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use pretty_assertions::assert_eq; use ratatui::style::Style; use rstest::rstest; use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::radarr_models::{Movie, RadarrRelease}; + use crate::models::servarr_data::radarr::modals::MovieDetailsModal; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, MOVIE_DETAILS_BLOCKS}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::library::movie_details_ui::{ MovieDetailsUi, style_from_download_status, }; use crate::ui::styles::ManagarrStyle; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_movie_details_ui_accepts() { @@ -42,4 +48,99 @@ mod tests { expected_style ); } + + #[test] + fn test_movie_details_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()); + app.data.radarr_data.movies = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + MovieDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_movie_details_ui_renders_movie_details_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()); + app.data.radarr_data.quality_profile_map = + BiMap::from_iter(vec![(2222, "HD - 1080p".to_owned())]); + app.data.radarr_data.movies = StatefulTable::default(); + app.data.radarr_data.movies.set_items(vec![Movie { + id: 1, + title: "Test Movie".into(), + ..Movie::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + MovieDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_movie_details_ui_renders_movie_history_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()); + app.data.radarr_data.quality_profile_map = + BiMap::from_iter(vec![(2222, "HD - 1080p".to_owned())]); + app.data.radarr_data.movies = StatefulTable::default(); + app.data.radarr_data.movies.set_items(vec![Movie { + id: 1, + title: "Test Movie".into(), + ..Movie::default() + }]); + app.data.radarr_data.movie_info_tabs.set_index(1); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + MovieDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_movie_details_ui_renders_manual_search_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()); + app.data.radarr_data.quality_profile_map = + BiMap::from_iter(vec![(2222, "HD - 1080p".to_owned())]); + app.data.radarr_data.movies = StatefulTable::default(); + app.data.radarr_data.movies.set_items(vec![Movie { + id: 1, + title: "Test Movie".into(), + ..Movie::default() + }]); + app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default()); + app + .data + .radarr_data + .movie_details_modal + .as_mut() + .unwrap() + .movie_releases = StatefulTable::default(); + app + .data + .radarr_data + .movie_details_modal + .as_mut() + .unwrap() + .movie_releases + .set_items(vec![RadarrRelease { + title: "Test Release".into(), + ..RadarrRelease::default() + }]); + app.data.radarr_data.movie_info_tabs.set_index(2); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + MovieDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_loading_state.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_loading_state.snap new file mode 100644 index 0000000..76245ed --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_loading_state.snap @@ -0,0 +1,29 @@ +--- +source: src/ui/radarr_ui/library/add_movie_ui_tests.rs +expression: output +--- + + + + + + ╭──────────────────────────────────── Add Movie ─────────────────────────────────────╮ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ + ╭──────────────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_search_input.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_search_input.snap new file mode 100644 index 0000000..76245ed --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__add_movie_ui__add_movie_ui_tests__tests__add_movie_ui_renders_search_input.snap @@ -0,0 +1,29 @@ +--- +source: src/ui/radarr_ui/library/add_movie_ui_tests.rs +expression: output +--- + + + + + + ╭──────────────────────────────────── Add Movie ─────────────────────────────────────╮ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ + ╭──────────────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__delete_movie_ui__delete_movie_ui_tests__tests__delete_movie_ui_renders_delete_movie_prompt.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__delete_movie_ui__delete_movie_ui_tests__tests__delete_movie_ui_renders_delete_movie_prompt.snap new file mode 100644 index 0000000..0c58379 --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__delete_movie_ui__delete_movie_ui_tests__tests__delete_movie_ui_renders_delete_movie_prompt.snap @@ -0,0 +1,24 @@ +--- +source: src/ui/radarr_ui/library/delete_movie_ui_tests.rs +expression: output +--- + + + + + + + + + + ╭───────────── Delete Movie ──────────────╮ + │ Do you really want to delete: │ + │ Test Movie? │ + │ │ + │ ╭───╮ │ + │ Delete Movie File: │ │ │ + │ ╰───╯ │ + │ ╭───╮ │ + │ Add List Exclusion: │ │ │ + │ ╰───╯ │ + ╰───────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__edit_movie_ui__edit_movie_ui_tests__tests__edit_movie_ui_renders_edit_movie_modal.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__edit_movie_ui__edit_movie_ui_tests__tests__edit_movie_ui_renders_edit_movie_modal.snap new file mode 100644 index 0000000..462693a --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__edit_movie_ui__edit_movie_ui_tests__tests__edit_movie_ui_renders_edit_movie_modal.snap @@ -0,0 +1,28 @@ +--- +source: src/ui/radarr_ui/library/edit_movie_ui_tests.rs +expression: output +--- + + + + + + + ╭──────────────────────── Edit - Test Movie ─────────────────────────╮ + │ │ + │ │ + │ │ + │ ╭───╮ │ + │ Monitored: ╰───╯ │ + │ ╭───────────────────────────────╮ │ + │ Minimum Availability: │Announced ▼ │ │ + │ ╰───────────────────────────────╯ │ + │ ╭───────────────────────────────╮ │ + │ Quality Profile: │HD - 1080p ▼ │ │ + │ ╰───────────────────────────────╯ │ + │ ╭───────────────────────────────╮ │ + │ Path: ╰───────────────────────────────╯ │ + │ ╭───────────────────────────────╮ │ + │ Tags: │ │ │ + │ ╰───────────────────────────────╯ │ + ╰──────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_loading_state.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_loading_state.snap new file mode 100644 index 0000000..7711262 --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_loading_state.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/library/movie_details_ui_tests.rs +expression: output +--- + + + + + ╭ Movie Info ──────────────────────────────────────────────────────────────────────────╮ + │ Details │ History │ File │ Cast │ Crew │ Manual Search │ + │────────────────────────────────────────────────────────────────────────────────────────│ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_manual_search_tab.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_manual_search_tab.snap new file mode 100644 index 0000000..9229ad5 --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_manual_search_tab.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/library/movie_details_ui_tests.rs +expression: output +--- + + + + + ╭ Movie Info ──────────────────────────────────────────────────────────────────────────╮ + │ Details │ History │ File │ Cast │ Crew │ Manual Search │ + │────────────────────────────────────────────────────────────────────────────────────────│ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_details_tab.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_details_tab.snap new file mode 100644 index 0000000..7711262 --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_details_tab.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/library/movie_details_ui_tests.rs +expression: output +--- + + + + + ╭ Movie Info ──────────────────────────────────────────────────────────────────────────╮ + │ Details │ History │ File │ Cast │ Crew │ Manual Search │ + │────────────────────────────────────────────────────────────────────────────────────────│ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_history_tab.snap b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_history_tab.snap new file mode 100644 index 0000000..cae88b4 --- /dev/null +++ b/src/ui/radarr_ui/library/snapshots/managarr__ui__radarr_ui__library__movie_details_ui__movie_details_ui_tests__tests__movie_details_ui_renders_movie_history_tab.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/library/movie_details_ui_tests.rs +expression: output +--- + + + + + ╭ Movie Info ──────────────────────────────────────────────────────────────────────────╮ + │ Details │ History │ File │ Cast │ Crew │ Manual Search │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/mod.rs b/src/ui/radarr_ui/mod.rs index 4868bca..72a9b6f 100644 --- a/src/ui/radarr_ui/mod.rs +++ b/src/ui/radarr_ui/mod.rs @@ -248,3 +248,7 @@ fn draw_radarr_logo(f: &mut Frame<'_>, area: Rect) { .centered(); f.render_widget(logo, area); } + +#[cfg(test)] +#[path = "radarr_ui_tests.rs"] +mod radarr_ui_tests; diff --git a/src/ui/radarr_ui/radarr_ui_tests.rs b/src/ui/radarr_ui/radarr_ui_tests.rs index 44fd4eb..24b90a2 100644 --- a/src/ui/radarr_ui/radarr_ui_tests.rs +++ b/src/ui/radarr_ui/radarr_ui_tests.rs @@ -1,15 +1,19 @@ #[cfg(test)] mod tests { use crate::models::radarr_models::{DownloadRecord, Movie}; + use bimap::BiMap; use pretty_assertions::assert_eq; use ratatui::widgets::{Cell, Row}; use rstest::rstest; use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; - use crate::ui::radarr_ui::{decorate_with_row_style, RadarrUi}; - use crate::ui::styles::ManagarrStyle; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; + use crate::ui::radarr_ui::{RadarrUi, decorate_with_row_style}; + use crate::ui::styles::ManagarrStyle; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_radarr_ui_accepts() { @@ -18,6 +22,79 @@ mod tests { }); } + mod snapshot_tests { + use super::*; + + #[test] + fn test_radarr_ui_renders_downloads_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.data.radarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.radarr_data.main_tabs.set_index(2); // Downloads tab + app.data.radarr_data.downloads = StatefulTable::default(); + app.data.radarr_data.downloads.set_items(vec![ + DownloadRecord { + id: 1, + title: "Test Movie 2024".to_owned(), + status: "downloading".to_owned(), + size: 2000000000, + sizeleft: 500000000, + ..DownloadRecord::default() + }, + DownloadRecord { + id: 2, + title: "Another Movie".to_owned(), + status: "downloading".to_owned(), + size: 1500000000, + sizeleft: 750000000, + ..DownloadRecord::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RadarrUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_radarr_ui_renders_downloads_tab_empty() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.data.radarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.radarr_data.main_tabs.set_index(2); // Downloads tab + app.data.radarr_data.downloads = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RadarrUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_radarr_ui_renders_library_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.data.radarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.radarr_data.main_tabs.set_index(0); // Library tab + app.data.radarr_data.movies = StatefulTable::default(); + app.data.radarr_data.movies.set_items(vec![Movie { + id: 1, + title: "Test Movie".into(), + quality_profile_id: 0, + ..Movie::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RadarrUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } + #[rstest] #[case(false, Some("downloading"), false, "", RowStyle::Downloading)] #[case(false, Some("completed"), false, "", RowStyle::AwaitingImport)] diff --git a/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs b/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs index bed74ce..e0d699b 100644 --- a/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs +++ b/src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs @@ -2,9 +2,14 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::HorizontallyScrollableText; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_FOLDERS_BLOCKS}; + use crate::models::servarr_models::RootFolder; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::radarr_ui::root_folders::RootFoldersUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_root_folders_ui_accepts() { @@ -16,4 +21,71 @@ mod tests { } }); } + + #[test] + fn test_root_folders_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_root_folders_ui_renders_empty_root_folders() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); + app.data.radarr_data.root_folders = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_root_folders_ui_renders_with_root_folders() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); + app.data.radarr_data.root_folders = StatefulTable::default(); + app.data.radarr_data.root_folders.set_items(vec![ + RootFolder { + path: "/movies".to_owned(), + accessible: true, + free_space: 1024 * 1024 * 1024 * 100, + ..RootFolder::default() + }, + RootFolder { + path: "/media/movies".to_owned(), + accessible: true, + free_space: 1024 * 1024 * 1024 * 50, + ..RootFolder::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_root_folders_ui_renders_add_root_folder() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into()); + app.data.radarr_data.root_folders = StatefulTable::default(); + app.data.radarr_data.edit_root_folder = Some(HorizontallyScrollableText::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_add_root_folder.snap b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_add_root_folder.snap new file mode 100644 index 0000000..92192db --- /dev/null +++ b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_add_root_folder.snap @@ -0,0 +1,20 @@ +--- +source: src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + + + + + + + + + + + + ╭────── Add Root Folder ───────╮ + cancel diff --git a/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_empty_root_folders.snap b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_empty_root_folders.snap new file mode 100644 index 0000000..0883c8a --- /dev/null +++ b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_empty_root_folders.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_loading_state.snap b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_loading_state.snap new file mode 100644 index 0000000..3571adb --- /dev/null +++ b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_with_root_folders.snap b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_with_root_folders.snap new file mode 100644 index 0000000..bffe454 --- /dev/null +++ b/src/ui/radarr_ui/root_folders/snapshots/managarr__ui__radarr_ui__root_folders__root_folders_ui_tests__tests__root_folders_ui_renders_with_root_folders.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/radarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Path Free Space Unmapped Folders +=> /movies 100.00 GB 0 + /media/movies 50.00 GB 0 diff --git a/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab.snap b/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab.snap new file mode 100644 index 0000000..3a04387 --- /dev/null +++ b/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/radarr_ui/radarr_ui_tests.rs +expression: output +--- +╭ Movies ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Collections │ Downloads │ Blocklist │ Root Folders │ Indexers │ System │ +│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab_empty.snap b/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab_empty.snap new file mode 100644 index 0000000..3a04387 --- /dev/null +++ b/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_downloads_tab_empty.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/radarr_ui/radarr_ui_tests.rs +expression: output +--- +╭ Movies ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Collections │ Downloads │ Blocklist │ Root Folders │ Indexers │ System │ +│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_library_tab.snap b/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_library_tab.snap new file mode 100644 index 0000000..daff9d2 --- /dev/null +++ b/src/ui/radarr_ui/snapshots/managarr__ui__radarr_ui__radarr_ui_tests__tests__snapshot_tests__radarr_ui_renders_library_tab.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/radarr_ui/radarr_ui_tests.rs +expression: output +--- +╭ Movies ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Collections │ Downloads │ Blocklist │ Root Folders │ Indexers │ System │ +│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ Title Year Studio Runtime Rating Languag Size Quality Pro Monitor Tags │ +│=> Test Movie 0 0h 0m 0.00 GB Any │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_loading_tasks.snap b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_loading_tasks.snap new file mode 100644 index 0000000..deb1ee9 --- /dev/null +++ b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_loading_tasks.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/system/system_details_ui_tests.rs +expression: output +--- + + + + + ╭ Tasks ───────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_logs.snap b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_logs.snap new file mode 100644 index 0000000..7272e3c --- /dev/null +++ b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_details_ui__system_details_ui_tests__tests__system_details_ui_renders_logs.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/radarr_ui/system/system_details_ui_tests.rs +expression: output +--- + + + + + ╭ Log Details ─────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_loading_state.snap b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_loading_state.snap new file mode 100644 index 0000000..5e6d27d --- /dev/null +++ b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_loading_state.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/radarr_ui/system/system_ui_tests.rs +expression: output +--- +╭ Tasks ─────────────────────────────────────────────────╮╭ Queued Events ─────────────────────────────────────────╮ +│ ││ │ +│ ││ │ +│ Loading ... ││ Loading ... │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +╰──────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────╯ +╭ Logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ │ +│ │ +│ Loading ... │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_system_menu.snap b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_system_menu.snap new file mode 100644 index 0000000..07cb0f2 --- /dev/null +++ b/src/ui/radarr_ui/system/snapshots/managarr__ui__radarr_ui__system__system_ui_tests__tests__system_ui_renders_system_menu.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/radarr_ui/system/system_ui_tests.rs +expression: output +--- +╭ Tasks ─────────────────────────────────────────────────╮╭ Queued Events ─────────────────────────────────────────╮ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +╰──────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────╯ +╭ Logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/radarr_ui/system/system_details_ui_tests.rs b/src/ui/radarr_ui/system/system_details_ui_tests.rs index ff77c51..771c933 100644 --- a/src/ui/radarr_ui/system/system_details_ui_tests.rs +++ b/src/ui/radarr_ui/system/system_details_ui_tests.rs @@ -2,11 +2,14 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS, }; + use crate::ui::DrawUi; use crate::ui::radarr_ui::system::system_details_ui::SystemDetailsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_system_details_ui_accepts() { @@ -18,4 +21,37 @@ mod tests { } }); } + + #[test] + fn test_system_details_ui_renders_loading_tasks() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_system_details_ui_renders_logs() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::SystemLogs.into()); + app.data.radarr_data.logs.set_items(vec![ + "2023-01-01T12:00:00Z | Info | Test log message 1" + .to_owned() + .into(), + "2023-01-01T12:01:00Z | Warn | Test warning message" + .to_owned() + .into(), + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/radarr_ui/system/system_ui_tests.rs b/src/ui/radarr_ui/system/system_ui_tests.rs index d41ae77..29e8902 100644 --- a/src/ui/radarr_ui/system/system_ui_tests.rs +++ b/src/ui/radarr_ui/system/system_ui_tests.rs @@ -2,11 +2,13 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::radarr::radarr_data::{ ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS, }; use crate::ui::DrawUi; use crate::ui::radarr_ui::system::SystemUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_system_ui_accepts() { @@ -22,4 +24,29 @@ mod tests { } }); } + + #[test] + fn test_system_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveRadarrBlock::System.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_system_ui_renders_system_menu() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::System.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } } diff --git a/src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs b/src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs index 4554804..24dca2a 100644 --- a/src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs +++ b/src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs @@ -1,9 +1,14 @@ #[cfg(test)] mod tests { + use strum::IntoEnumIterator; + + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, BLOCKLIST_BLOCKS}; + use crate::models::sonarr_models::BlocklistItem; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::blocklist::BlocklistUi; - use strum::IntoEnumIterator; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_blocklist_ui_accepts() { @@ -15,4 +20,59 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_blocklist_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + BlocklistUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_blocklist_ui_renders_empty_blocklist() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); + app.data.sonarr_data.blocklist = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + BlocklistUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_blocklist_ui_renders_with_blocklist_items() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); + app.data.sonarr_data.blocklist = StatefulTable::default(); + app.data.sonarr_data.blocklist.set_items(vec![ + BlocklistItem { + id: 1, + source_title: "Test.Series.S01E01.1080p".to_owned(), + ..BlocklistItem::default() + }, + BlocklistItem { + id: 2, + source_title: "Another.Series.S02E05.720p".to_owned(), + ..BlocklistItem::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + BlocklistUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_empty_blocklist.snap b/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_empty_blocklist.snap new file mode 100644 index 0000000..c6e9881 --- /dev/null +++ b/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_empty_blocklist.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_loading_state.snap b/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_loading_state.snap new file mode 100644 index 0000000..b9c1bf4 --- /dev/null +++ b/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_with_blocklist_items.snap b/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_with_blocklist_items.snap new file mode 100644 index 0000000..80e2649 --- /dev/null +++ b/src/ui/sonarr_ui/blocklist/snapshots/managarr__ui__sonarr_ui__blocklist__blocklist_ui_tests__tests__snapshot_tests__blocklist_ui_renders_with_blocklist_items.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/blocklist/blocklist_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Series Title Source Title Language Quality Date +=> Test.Series.S01E01.1080p 1970-01-01 00:00:0 + Another.Series.S02E05.720p 1970-01-01 00:00:0 diff --git a/src/ui/sonarr_ui/downloads/downloads_ui_tests.rs b/src/ui/sonarr_ui/downloads/downloads_ui_tests.rs index 8e0cfe5..1659ebd 100644 --- a/src/ui/sonarr_ui/downloads/downloads_ui_tests.rs +++ b/src/ui/sonarr_ui/downloads/downloads_ui_tests.rs @@ -2,9 +2,13 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS}; + use crate::models::sonarr_models::DownloadRecord; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::downloads::DownloadsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_downloads_ui_accepts() { @@ -16,4 +20,65 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_downloads_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DownloadsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_downloads_ui_renders_empty_downloads() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); + app.data.sonarr_data.downloads = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DownloadsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_downloads_ui_renders_with_downloads() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); + app.data.sonarr_data.downloads = StatefulTable::default(); + app.data.sonarr_data.downloads.set_items(vec![ + DownloadRecord { + id: 1, + title: "Test Series Download".to_owned(), + status: Default::default(), + size: 1024.0 * 1024.0 * 1024.0, + sizeleft: 512.0 * 1024.0 * 1024.0, + ..DownloadRecord::default() + }, + DownloadRecord { + id: 2, + title: "Another Series Download".to_owned(), + status: Default::default(), + size: 2048.0 * 1024.0 * 1024.0, + sizeleft: 0.0, + ..DownloadRecord::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DownloadsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_empty_downloads.snap b/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_empty_downloads.snap new file mode 100644 index 0000000..cfe9f6d --- /dev/null +++ b/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_empty_downloads.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/downloads/downloads_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_loading_state.snap b/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_loading_state.snap new file mode 100644 index 0000000..7c27b2f --- /dev/null +++ b/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/downloads/downloads_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_with_downloads.snap b/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_with_downloads.snap new file mode 100644 index 0000000..3c6eafc --- /dev/null +++ b/src/ui/sonarr_ui/downloads/snapshots/managarr__ui__sonarr_ui__downloads__downloads_ui_tests__tests__snapshot_tests__downloads_ui_renders_with_downloads.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/downloads/downloads_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Title Percent Compl Size Output Path Indexer Download Client +=> Test Series Download 50% 1.00 GB + Another Series Download 100% 2.00 GB diff --git a/src/ui/sonarr_ui/history/history_ui_tests.rs b/src/ui/sonarr_ui/history/history_ui_tests.rs index df15aef..fa1919c 100644 --- a/src/ui/sonarr_ui/history/history_ui_tests.rs +++ b/src/ui/sonarr_ui/history/history_ui_tests.rs @@ -1,9 +1,14 @@ #[cfg(test)] mod tests { + use strum::IntoEnumIterator; + + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTORY_BLOCKS}; + use crate::models::sonarr_models::SonarrHistoryItem; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::history::HistoryUi; - use strum::IntoEnumIterator; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_history_ui_accepts() { @@ -15,4 +20,59 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_history_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::History.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + HistoryUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_history_ui_renders_empty_history() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::History.into()); + app.data.sonarr_data.history = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + HistoryUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_history_ui_renders_with_history_items() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::History.into()); + app.data.sonarr_data.history = StatefulTable::default(); + app.data.sonarr_data.history.set_items(vec![ + SonarrHistoryItem { + id: 1, + source_title: "Test.Series.S01E01".to_owned().into(), + ..SonarrHistoryItem::default() + }, + SonarrHistoryItem { + id: 2, + source_title: "Another.Series.S02E05".to_owned().into(), + ..SonarrHistoryItem::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + HistoryUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_empty_history.snap b/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_empty_history.snap new file mode 100644 index 0000000..bb3846a --- /dev/null +++ b/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_empty_history.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/history/history_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_loading_state.snap b/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_loading_state.snap new file mode 100644 index 0000000..a7e7f8e --- /dev/null +++ b/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/history/history_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_with_history_items.snap b/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_with_history_items.snap new file mode 100644 index 0000000..73bece9 --- /dev/null +++ b/src/ui/sonarr_ui/history/snapshots/managarr__ui__sonarr_ui__history__history_ui_tests__tests__snapshot_tests__history_ui_renders_with_history_items.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/history/history_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Source Title Event Type Language Quality Date +=> Test.Series.S01E01 unknown 1970-01-01 00:00:00 UTC + Another.Series.S02E05 unknown 1970-01-01 00:00:00 UTC diff --git a/src/ui/sonarr_ui/indexers/edit_indexer_ui_tests.rs b/src/ui/sonarr_ui/indexers/edit_indexer_ui_tests.rs index 3b22177..7d7fe58 100644 --- a/src/ui/sonarr_ui/indexers/edit_indexer_ui_tests.rs +++ b/src/ui/sonarr_ui/indexers/edit_indexer_ui_tests.rs @@ -1,9 +1,19 @@ #[cfg(test)] mod tests { - use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS}; + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::servarr_data::modals::EditIndexerModal; + use crate::models::servarr_data::sonarr::sonarr_data::{ + ActiveSonarrBlock, EDIT_INDEXER_BLOCKS, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS, + }; + use crate::models::servarr_models::{Indexer, IndexerField}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::indexers::edit_indexer_ui::EditIndexerUi; - use strum::IntoEnumIterator; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; + use serde_json::json; #[test] fn test_edit_indexer_ui_accepts() { @@ -15,4 +25,45 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_edit_indexer_ui_renders_edit_indexer_modal() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::EditIndexerNameInput.into()); + app.data.sonarr_data.indexers = StatefulTable::default(); + app.data.sonarr_data.indexers.set_items(vec![Indexer { + id: 1, + name: Some("Test Indexer".to_owned()), + enable_rss: true, + priority: 25, + fields: Some(vec![ + IndexerField { + name: Some("baseUrl".to_owned()), + value: Some(json!("https://test.indexer.com")), + }, + IndexerField { + name: Some("apiKey".to_owned()), + value: Some(json!("test-api-key")), + }, + IndexerField { + name: Some("seedCriteria.seedRatio".to_owned()), + value: Some(json!(1.0)), + }, + ]), + ..Indexer::default() + }]); + app.data.sonarr_data.selected_block = + BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); + app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::from(&app.data.sonarr_data)); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EditIndexerUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/indexers/indexer_settings_ui_tests.rs b/src/ui/sonarr_ui/indexers/indexer_settings_ui_tests.rs index d7d729d..bc86f32 100644 --- a/src/ui/sonarr_ui/indexers/indexer_settings_ui_tests.rs +++ b/src/ui/sonarr_ui/indexers/indexer_settings_ui_tests.rs @@ -2,11 +2,15 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::BlockSelectionState; use crate::models::servarr_data::sonarr::sonarr_data::{ - ActiveSonarrBlock, INDEXER_SETTINGS_BLOCKS, + ActiveSonarrBlock, INDEXER_SETTINGS_BLOCKS, INDEXER_SETTINGS_SELECTION_BLOCKS, }; + use crate::models::sonarr_models::IndexerSettings; use crate::ui::DrawUi; use crate::ui::sonarr_ui::indexers::indexer_settings_ui::IndexerSettingsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_indexer_settings_ui_accepts() { @@ -18,4 +22,23 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_indexer_settings_ui_renders_indexer_settings() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::IndexerSettingsMinimumAgeInput.into()); + app.data.sonarr_data.selected_block = + BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); + app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + IndexerSettingsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/indexers/indexers_ui_tests.rs b/src/ui/sonarr_ui/indexers/indexers_ui_tests.rs index 725b19f..5a55253 100644 --- a/src/ui/sonarr_ui/indexers/indexers_ui_tests.rs +++ b/src/ui/sonarr_ui/indexers/indexers_ui_tests.rs @@ -2,11 +2,15 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, EDIT_INDEXER_BLOCKS, INDEXER_SETTINGS_BLOCKS, INDEXERS_BLOCKS, }; + use crate::models::servarr_models::Indexer; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::indexers::IndexersUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_indexers_ui_accepts() { @@ -24,4 +28,64 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_indexers_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); + + let output = render_to_string_with_app(120, 30, &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(ActiveSonarrBlock::Indexers.into()); + app.data.sonarr_data.indexers = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_indexers_ui_renders_with_indexers() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); + app.data.sonarr_data.indexers = StatefulTable::default(); + app.data.sonarr_data.indexers.set_items(vec![ + Indexer { + id: 1, + name: Some("Test Indexer 1".to_owned()), + enable_rss: true, + enable_automatic_search: true, + enable_interactive_search: true, + priority: 25, + ..Indexer::default() + }, + Indexer { + id: 2, + name: Some("Test Indexer 2".to_owned()), + enable_rss: false, + ..Indexer::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + IndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_edit_indexer_modal.snap b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_edit_indexer_modal.snap new file mode 100644 index 0000000..4e928f8 --- /dev/null +++ b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__edit_indexer_ui__edit_indexer_ui_tests__tests__snapshot_tests__edit_indexer_ui_renders_edit_indexer_modal.snap @@ -0,0 +1,27 @@ +--- +source: src/ui/sonarr_ui/indexers/edit_indexer_ui_tests.rs +expression: output +--- + + + + + + + + + ╭───────────────────────────────── Edit Indexer ─────────────────────────────────╮ + │ │ + │ ╭─────────────────╮ ╭─────────────────╮ │ + │ Name: ╰─────────────────╯ URL: ╰─────────────────╯ │ + │ ╭───╮ ╭─────────────────╮ │ + │ ╭───╮ API Key: ╰─────────────────╯ │ + │ Enable Automatic Se╰───╯ ╭─────────────────╮ │ + │ ╭───╮ Tags: ╰─────────────────╯ │ + │ ╭─────────────────╮ │ + │ Indexer Priority ▴▾╰─────────────────╯ │ + │ │ + │ ╭──────────────────╮╭───────────────────╮ │ + │ │ Save ││ Cancel │ │ + │ ╰──────────────────╯╰───────────────────╯ │ + ╰──────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_indexer_settings.snap b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_indexer_settings.snap new file mode 100644 index 0000000..157c634 --- /dev/null +++ b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexer_settings_ui__indexer_settings_ui_tests__tests__snapshot_tests__indexer_settings_ui_renders_indexer_settings.snap @@ -0,0 +1,26 @@ +--- +source: src/ui/sonarr_ui/indexers/indexer_settings_ui_tests.rs +expression: output +--- + + + + + + + + + ╭───────── Configure All Indexer Settings ─────────╮ + │ ╭───────────────────────╮ │ + │Minimum Age (minutes) ▴▾:│0 │ │ + │ ╰───────────────────────╯ │ + │ ╭───────────────────────╮ │ + │ Retention (days) ▴▾: │0 │ │ + │ ╰───────────────────────╯ │ + │ ╭───────────────────────╮ │ + │ Maximum Size (MB) ▴▾: │0 │ │ + │ ╰───────────────────────╯ │ + │ ╭───────────────────────╮ │ + │RSS Sync Interval (minute│0 │ │ + │ ╰───────────────────────╯ │ + ╰────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap new file mode 100644 index 0000000..df13382 --- /dev/null +++ b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_empty_indexers.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_state.snap b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_state.snap new file mode 100644 index 0000000..cb64756 --- /dev/null +++ b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_with_indexers.snap b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_with_indexers.snap new file mode 100644 index 0000000..1af1435 --- /dev/null +++ b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__indexers_ui_tests__tests__snapshot_tests__indexers_ui_renders_with_indexers.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/indexers/indexers_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Indexer RSS Automatic Search Interactive Sea Priority Tags +=> Test Indexer 1 Enabled Enabled Enabled 25 + Test Indexer 2 Disabled Disabled Disabled 0 diff --git a/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap new file mode 100644 index 0000000..4e377fd --- /dev/null +++ b/src/ui/sonarr_ui/indexers/snapshots/managarr__ui__sonarr_ui__indexers__test_all_indexers_ui__test_all_indexers_ui_tests__tests__snapshot_tests__test_all_indexers_ui_renders_loading_state.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/indexers/test_all_indexers_ui_tests.rs +expression: output +--- + + + + + ╭ Test All Indexers ───────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/indexers/test_all_indexers_ui_tests.rs b/src/ui/sonarr_ui/indexers/test_all_indexers_ui_tests.rs index c221453..6629ebf 100644 --- a/src/ui/sonarr_ui/indexers/test_all_indexers_ui_tests.rs +++ b/src/ui/sonarr_ui/indexers/test_all_indexers_ui_tests.rs @@ -2,9 +2,11 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock; use crate::ui::DrawUi; use crate::ui::sonarr_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() { @@ -16,4 +18,21 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_test_all_indexers_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::TestAllIndexers.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + TestAllIndexersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/add_series_ui_tests.rs b/src/ui/sonarr_ui/library/add_series_ui_tests.rs index cac470c..5a3eef0 100644 --- a/src/ui/sonarr_ui/library/add_series_ui_tests.rs +++ b/src/ui/sonarr_ui/library/add_series_ui_tests.rs @@ -2,9 +2,12 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::HorizontallyScrollableText; use crate::models::servarr_data::sonarr::sonarr_data::{ADD_SERIES_BLOCKS, ActiveSonarrBlock}; use crate::ui::DrawUi; use crate::ui::sonarr_ui::library::add_series_ui::AddSeriesUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_add_series_ui_accepts() { @@ -16,4 +19,35 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_add_series_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::AddSeriesSearchInput.into()); + app.data.sonarr_data.add_series_search = Some(HorizontallyScrollableText::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + AddSeriesUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_add_series_ui_renders_search_input() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::AddSeriesSearchInput.into()); + app.data.sonarr_data.add_series_search = Some(HorizontallyScrollableText::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + AddSeriesUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/delete_series_ui_tests.rs b/src/ui/sonarr_ui/library/delete_series_ui_tests.rs index 5dfd620..57a904f 100644 --- a/src/ui/sonarr_ui/library/delete_series_ui_tests.rs +++ b/src/ui/sonarr_ui/library/delete_series_ui_tests.rs @@ -2,9 +2,16 @@ mod tests { use strum::IntoEnumIterator; - use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DELETE_SERIES_BLOCKS}; + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::servarr_data::sonarr::sonarr_data::{ + ActiveSonarrBlock, DELETE_SERIES_BLOCKS, DELETE_SERIES_SELECTION_BLOCKS, + }; + use crate::models::sonarr_models::Series; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::library::delete_series_ui::DeleteSeriesUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_delete_series_ui_accepts() { @@ -16,4 +23,28 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_delete_series_ui_renders_delete_series_toggle() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::DeleteSeriesPrompt.into()); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + id: 1, + title: "Test Series".into(), + ..Series::default() + }]); + app.data.sonarr_data.selected_block = + BlockSelectionState::new(DELETE_SERIES_SELECTION_BLOCKS); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + DeleteSeriesUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/edit_series_ui_tests.rs b/src/ui/sonarr_ui/library/edit_series_ui_tests.rs index 938dde3..0961a0e 100644 --- a/src/ui/sonarr_ui/library/edit_series_ui_tests.rs +++ b/src/ui/sonarr_ui/library/edit_series_ui_tests.rs @@ -1,10 +1,19 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; - use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_SERIES_BLOCKS}; + use crate::app::App; + use crate::models::BlockSelectionState; + use crate::models::servarr_data::sonarr::modals::EditSeriesModal; + use crate::models::servarr_data::sonarr::sonarr_data::{ + ActiveSonarrBlock, EDIT_SERIES_BLOCKS, EDIT_SERIES_SELECTION_BLOCKS, + }; + use crate::models::sonarr_models::Series; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::library::edit_series_ui::EditSeriesUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_edit_series_ui_accepts() { @@ -16,4 +25,34 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_edit_series_ui_renders_edit_series_modal() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::EditSeriesPathInput.into()); + app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(1, "HD-1080p".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter(vec![(1, "English".to_owned())]); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + id: 1, + title: "Test Series".into(), + path: "/tv/test".to_owned(), + quality_profile_id: 1, + language_profile_id: 1, + ..Series::default() + }]); + app.data.sonarr_data.selected_block = BlockSelectionState::new(EDIT_SERIES_SELECTION_BLOCKS); + app.data.sonarr_data.edit_series_modal = Some(EditSeriesModal::from(&app.data.sonarr_data)); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EditSeriesUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/episode_details_ui_tests.rs b/src/ui/sonarr_ui/library/episode_details_ui_tests.rs index 4246f53..699cef2 100644 --- a/src/ui/sonarr_ui/library/episode_details_ui_tests.rs +++ b/src/ui/sonarr_ui/library/episode_details_ui_tests.rs @@ -1,11 +1,17 @@ #[cfg(test)] mod tests { + use strum::IntoEnumIterator; + + use crate::app::App; + use crate::models::servarr_data::sonarr::modals::{EpisodeDetailsModal, SeasonDetailsModal}; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS, }; + use crate::models::sonarr_models::{Episode, Season, Series}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::library::episode_details_ui::EpisodeDetailsUi; - use strum::IntoEnumIterator; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_episode_details_ui_accepts() { @@ -17,4 +23,111 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_episode_details_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into()); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season { + season_number: 1, + ..Season::default() + }]), + ..Series::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EpisodeDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_episode_details_ui_renders_episode_details_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into()); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season { + season_number: 1, + ..Season::default() + }]), + ..Series::default() + }]); + let mut season_details_modal = SeasonDetailsModal::default(); + season_details_modal + .episodes + .set_items(vec![Episode::default()]); + season_details_modal.episode_details_modal = Some(EpisodeDetailsModal::default()); + app.data.sonarr_data.season_details_modal = Some(season_details_modal); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EpisodeDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_episode_details_ui_renders_episode_history_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into()); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season { + season_number: 1, + ..Season::default() + }]), + ..Series::default() + }]); + let mut season_details_modal = SeasonDetailsModal::default(); + season_details_modal + .episodes + .set_items(vec![Episode::default()]); + let mut episode_details_modal = EpisodeDetailsModal::default(); + episode_details_modal.episode_details_tabs.set_index(1); + season_details_modal.episode_details_modal = Some(episode_details_modal); + app.data.sonarr_data.season_details_modal = Some(season_details_modal); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EpisodeDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_episode_details_ui_renders_manual_search_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::EpisodeDetails.into()); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season { + season_number: 1, + ..Season::default() + }]), + ..Series::default() + }]); + let mut season_details_modal = SeasonDetailsModal::default(); + season_details_modal + .episodes + .set_items(vec![Episode::default()]); + let mut episode_details_modal = EpisodeDetailsModal::default(); + episode_details_modal.episode_details_tabs.set_index(3); + season_details_modal.episode_details_modal = Some(episode_details_modal); + app.data.sonarr_data.season_details_modal = Some(season_details_modal); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + EpisodeDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/library_ui_tests.rs b/src/ui/sonarr_ui/library/library_ui_tests.rs index fd0c51b..98cf71b 100644 --- a/src/ui/sonarr_ui/library/library_ui_tests.rs +++ b/src/ui/sonarr_ui/library/library_ui_tests.rs @@ -245,4 +245,41 @@ mod tests { assert_eq!(style, row.indeterminate()); } + + mod snapshot_tests { + + use crate::app::App; + use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock; + + use crate::models::stateful_table::StatefulTable; + use crate::ui::DrawUi; + use crate::ui::sonarr_ui::library::LibraryUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; + + #[test] + fn test_library_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::Series.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + LibraryUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_library_ui_renders_empty_series() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Series.into()); + app.data.sonarr_data.series = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + LibraryUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/season_details_ui_tests.rs b/src/ui/sonarr_ui/library/season_details_ui_tests.rs index cd987ca..1bb7569 100644 --- a/src/ui/sonarr_ui/library/season_details_ui_tests.rs +++ b/src/ui/sonarr_ui/library/season_details_ui_tests.rs @@ -1,12 +1,18 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::servarr_data::sonarr::modals::SeasonDetailsModal; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS, SEASON_DETAILS_BLOCKS, }; + use crate::models::sonarr_models::{Season, Series}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::library::season_details_ui::SeasonDetailsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_season_details_ui_accepts() { @@ -21,4 +27,121 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_season_details_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into()); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season::default()]), + ..Series::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SeasonDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_season_details_ui_renders_episodes_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into()); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season::default()]), + ..Series::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SeasonDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_season_details_ui_renders_manual_search_tab() { + use crate::models::sonarr_models::{Episode, EpisodeFile, SonarrRelease}; + + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into()); + app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter(vec![(0, "English".to_owned())]); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season::default()]), + ..Series::default() + }]); + app + .data + .sonarr_data + .seasons + .set_items(vec![Season::default()]); + let mut season_details_modal = SeasonDetailsModal::default(); + season_details_modal.season_details_tabs.set_index(2); + season_details_modal + .episodes + .set_items(vec![Episode::default()]); + season_details_modal + .episode_files + .set_items(vec![EpisodeFile::default()]); + season_details_modal + .season_releases + .set_items(vec![SonarrRelease::default()]); + app.data.sonarr_data.season_details_modal = Some(season_details_modal); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SeasonDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_season_details_ui_renders_season_history_tab() { + use crate::models::sonarr_models::{Episode, EpisodeFile, SonarrHistoryItem}; + + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::SeasonDetails.into()); + app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter(vec![(0, "English".to_owned())]); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + seasons: Some(vec![Season::default()]), + ..Series::default() + }]); + app + .data + .sonarr_data + .seasons + .set_items(vec![Season::default()]); + let mut season_details_modal = SeasonDetailsModal::default(); + season_details_modal.season_details_tabs.set_index(1); + season_details_modal + .episodes + .set_items(vec![Episode::default()]); + season_details_modal + .episode_files + .set_items(vec![EpisodeFile::default()]); + season_details_modal + .season_history + .set_items(vec![SonarrHistoryItem::default()]); + app.data.sonarr_data.season_details_modal = Some(season_details_modal); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SeasonDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/series_details_ui_tests.rs b/src/ui/sonarr_ui/library/series_details_ui_tests.rs index a261dd7..69cd1a1 100644 --- a/src/ui/sonarr_ui/library/series_details_ui_tests.rs +++ b/src/ui/sonarr_ui/library/series_details_ui_tests.rs @@ -1,12 +1,17 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, EPISODE_DETAILS_BLOCKS, SEASON_DETAILS_BLOCKS, SERIES_DETAILS_BLOCKS, }; + use crate::models::sonarr_models::{Season, Series}; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::library::series_details_ui::SeriesDetailsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_series_details_ui_accepts() { @@ -22,4 +27,33 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_series_details_ui_renders_series_details() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::SeriesDetails.into()); + app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(1, "HD-1080p".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter(vec![(1, "English".to_owned())]); + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + id: 1, + title: "Test Series".into(), + seasons: Some(vec![Season::default()]), + quality_profile_id: 1, + language_profile_id: 1, + ..Series::default() + }]); + app.data.sonarr_data.series_history = Some(StatefulTable::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SeriesDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_loading_state.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_loading_state.snap new file mode 100644 index 0000000..6253724 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_loading_state.snap @@ -0,0 +1,29 @@ +--- +source: src/ui/sonarr_ui/library/add_series_ui_tests.rs +expression: output +--- + + + + + + ╭──────────────────────────────────── Add Series ────────────────────────────────────╮ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ + ╭──────────────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_search_input.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_search_input.snap new file mode 100644 index 0000000..6253724 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__add_series_ui__add_series_ui_tests__tests__snapshot_tests__add_series_ui_renders_search_input.snap @@ -0,0 +1,29 @@ +--- +source: src/ui/sonarr_ui/library/add_series_ui_tests.rs +expression: output +--- + + + + + + ╭──────────────────────────────────── Add Series ────────────────────────────────────╮ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ + ╭──────────────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰──────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__delete_series_ui__delete_series_ui_tests__tests__snapshot_tests__delete_series_ui_renders_delete_series_toggle.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__delete_series_ui__delete_series_ui_tests__tests__snapshot_tests__delete_series_ui_renders_delete_series_toggle.snap new file mode 100644 index 0000000..87ec34a --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__delete_series_ui__delete_series_ui_tests__tests__snapshot_tests__delete_series_ui_renders_delete_series_toggle.snap @@ -0,0 +1,24 @@ +--- +source: src/ui/sonarr_ui/library/delete_series_ui_tests.rs +expression: output +--- + + + + + + + + + + ╭───────────── Delete Series ─────────────╮ + │ Do you really want to delete the series: │ + │ Test Series? │ + │ │ + │ ╭───╮ │ + │ Delete Series File: │ │ │ + │ ╰───╯ │ + │ ╭───╮ │ + │ Add List Exclusion: │ │ │ + │ ╰───╯ │ + ╰───────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__edit_series_ui__edit_series_ui_tests__tests__snapshot_tests__edit_series_ui_renders_edit_series_modal.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__edit_series_ui__edit_series_ui_tests__tests__snapshot_tests__edit_series_ui_renders_edit_series_modal.snap new file mode 100644 index 0000000..bc745af --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__edit_series_ui__edit_series_ui_tests__tests__snapshot_tests__edit_series_ui_renders_edit_series_modal.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/library/edit_series_ui_tests.rs +expression: output +--- + + + + + ╭─────────────────────────── Edit - Test Series ───────────────────────────╮ + │ │ + │ │ + │ │ + │ ╭───╮ │ + │ Monitored: ╰───╯ │ + │ ╭───╮ │ + │ Season Folder: │ │ │ + │ ╰───╯ │ + │ ╭───────────────────────────────────╮ │ + │ Quality Profile: ╰───────────────────────────────────╯ │ + │ ╭───────────────────────────────────╮ │ + │ Language Profile: │English ▼ │ │ + │ ╰───────────────────────────────────╯ │ + │ ╭───────────────────────────────────╮ │ + │ Series Type: ╰───────────────────────────────────╯ │ + │ ╭───────────────────────────────────╮ │ + │ Path: │/tv/test │ │ + │ ╰───────────────────────────────────╯ │ + │ ╭───────────────────────────────────╮ │ + │ Tags: ╰───────────────────────────────────╯ │ + ╰────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_details_tab.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_details_tab.snap new file mode 100644 index 0000000..e00c67d --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_details_tab.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/library/episode_details_ui_tests.rs +expression: output +--- + + + + + ╭ Episode Details ─────────────────────────────────────────────────────────────────────╮ + │ Details │ History │ File │ Manual Search │ + │────────────────────────────────────────────────────────────────────────────────────────│ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_history_tab.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_history_tab.snap new file mode 100644 index 0000000..e00c67d --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_episode_history_tab.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/library/episode_details_ui_tests.rs +expression: output +--- + + + + + ╭ Episode Details ─────────────────────────────────────────────────────────────────────╮ + │ Details │ History │ File │ Manual Search │ + │────────────────────────────────────────────────────────────────────────────────────────│ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_loading_state.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_loading_state.snap new file mode 100644 index 0000000..f112e11 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_loading_state.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/library/episode_details_ui_tests.rs +expression: output +--- + diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_manual_search_tab.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_manual_search_tab.snap new file mode 100644 index 0000000..7e37133 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__episode_details_ui__episode_details_ui_tests__tests__snapshot_tests__episode_details_ui_renders_manual_search_tab.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/library/episode_details_ui_tests.rs +expression: output +--- + + + + + ╭ Episode Details ─────────────────────────────────────────────────────────────────────╮ + │ Details │ History │ File │ Manual Search │ + │────────────────────────────────────────────────────────────────────────────────────────│ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_empty_series.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_empty_series.snap new file mode 100644 index 0000000..efada52 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_empty_series.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/library/library_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_loading_state.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_loading_state.snap new file mode 100644 index 0000000..7d08204 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__library_ui_tests__tests__snapshot_tests__library_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/library/library_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_episodes_tab.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_episodes_tab.snap new file mode 100644 index 0000000..67b9605 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_episodes_tab.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/library/season_details_ui_tests.rs +expression: output +--- + diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_loading_state.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_loading_state.snap new file mode 100644 index 0000000..67b9605 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_loading_state.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/library/season_details_ui_tests.rs +expression: output +--- + diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_manual_search_tab.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_manual_search_tab.snap new file mode 100644 index 0000000..9b59779 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_manual_search_tab.snap @@ -0,0 +1,31 @@ +--- +source: src/ui/sonarr_ui/library/season_details_ui_tests.rs +expression: output +--- + + + ╭ Season 0 Details ─────────────────────────────────────────────────────────────────────────────╮ + │ Episodes │ History │ Manual Search │ + │─────────────────────────────────────────────────────────────────────────────────────────────────│ + │ Source Age ⛔ Title Indexer Size Peers Languag Quality│ + │=> 0 days 0.0 GB │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_season_history_tab.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_season_history_tab.snap new file mode 100644 index 0000000..abfe70d --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__season_details_ui__season_details_ui_tests__tests__snapshot_tests__season_details_ui_renders_season_history_tab.snap @@ -0,0 +1,31 @@ +--- +source: src/ui/sonarr_ui/library/season_details_ui_tests.rs +expression: output +--- + + + ╭ Season 0 Details ─────────────────────────────────────────────────────────────────────────────╮ + │ Episodes │ History │ Manual Search │ + │─────────────────────────────────────────────────────────────────────────────────────────────────│ + │ Source Title Event Type Language Quality Date │ + │=> unknown 1970-01-01 00:00:00│ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__series_details_ui__series_details_ui_tests__tests__snapshot_tests__series_details_ui_renders_series_details.snap b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__series_details_ui__series_details_ui_tests__tests__snapshot_tests__series_details_ui_renders_series_details.snap new file mode 100644 index 0000000..1e405e4 --- /dev/null +++ b/src/ui/sonarr_ui/library/snapshots/managarr__ui__sonarr_ui__library__series_details_ui__series_details_ui_tests__tests__snapshot_tests__series_details_ui_renders_series_details.snap @@ -0,0 +1,33 @@ +--- +source: src/ui/sonarr_ui/library/series_details_ui_tests.rs +expression: output +--- + + + ╭ Test Series ───────────────────────────────────────────────────────────────────────────────────────────╮ + │Title: Test Series │ + │Overview: │ + │Network: │ + │Status: Continuing │ + │Genres: │ + │Rating: 0% │ + │Year: 0 │ + │Runtime: 0 minutes │ + │Path: │ + │╭ Series Details ──────────────────────────────────────────────────────────────────────────────────────╮│ + ││ Seasons │ History ││ + ││────────────────────────────────────────────────────────────────────────────────────────────────────────││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + ││ ││ + │╰────────────────────────────────────────────────────────────────────────────────────────────────────────╯│ + ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs b/src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs index 0313bd1..c26d0eb 100644 --- a/src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs +++ b/src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs @@ -2,9 +2,14 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; + use crate::models::HorizontallyScrollableText; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, ROOT_FOLDERS_BLOCKS}; + use crate::models::servarr_models::RootFolder; + use crate::models::stateful_table::StatefulTable; use crate::ui::DrawUi; use crate::ui::sonarr_ui::root_folders::RootFoldersUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_root_folders_ui_accepts() { @@ -16,4 +21,75 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_root_folders_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::RootFolders.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_root_folders_ui_renders_empty_root_folders() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::RootFolders.into()); + app.data.sonarr_data.root_folders = StatefulTable::default(); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_root_folders_ui_renders_with_root_folders() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::RootFolders.into()); + app.data.sonarr_data.root_folders = StatefulTable::default(); + app.data.sonarr_data.root_folders.set_items(vec![ + RootFolder { + path: "/tv".to_owned(), + accessible: true, + free_space: 1024 * 1024 * 1024 * 100, + ..RootFolder::default() + }, + RootFolder { + path: "/media/tv".to_owned(), + accessible: true, + free_space: 1024 * 1024 * 1024 * 50, + ..RootFolder::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_root_folders_ui_renders_add_root_folder() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::AddRootFolderPrompt.into()); + app.data.sonarr_data.root_folders = StatefulTable::default(); + app.data.sonarr_data.edit_root_folder = Some(HorizontallyScrollableText::default()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + RootFoldersUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_add_root_folder.snap b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_add_root_folder.snap new file mode 100644 index 0000000..7ac5efc --- /dev/null +++ b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_add_root_folder.snap @@ -0,0 +1,20 @@ +--- +source: src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + + + + + + + + + + + + ╭────── Add Root Folder ───────╮ + cancel diff --git a/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_empty_root_folders.snap b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_empty_root_folders.snap new file mode 100644 index 0000000..4b473dd --- /dev/null +++ b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_empty_root_folders.snap @@ -0,0 +1,5 @@ +--- +source: src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── diff --git a/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_loading_state.snap b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_loading_state.snap new file mode 100644 index 0000000..fc3627f --- /dev/null +++ b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_loading_state.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + + + Loading ... diff --git a/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_with_root_folders.snap b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_with_root_folders.snap new file mode 100644 index 0000000..460ffcd --- /dev/null +++ b/src/ui/sonarr_ui/root_folders/snapshots/managarr__ui__sonarr_ui__root_folders__root_folders_ui_tests__tests__snapshot_tests__root_folders_ui_renders_with_root_folders.snap @@ -0,0 +1,8 @@ +--- +source: src/ui/sonarr_ui/root_folders/root_folders_ui_tests.rs +expression: output +--- +──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── + Path Free Space Unmapped Folders +=> /tv 100.00 GB 0 + /media/tv 50.00 GB 0 diff --git a/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_downloads_tab.snap b/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_downloads_tab.snap new file mode 100644 index 0000000..058ce75 --- /dev/null +++ b/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_downloads_tab.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/sonarr_ui/sonarr_ui_tests.rs +expression: output +--- +╭ Series ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ +│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_history_tab.snap b/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_history_tab.snap new file mode 100644 index 0000000..058ce75 --- /dev/null +++ b/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_history_tab.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/sonarr_ui/sonarr_ui_tests.rs +expression: output +--- +╭ Series ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ +│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_library_tab.snap b/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_library_tab.snap new file mode 100644 index 0000000..89b03f7 --- /dev/null +++ b/src/ui/sonarr_ui/snapshots/managarr__ui__sonarr_ui__sonarr_ui_tests__tests__snapshot_tests__sonarr_ui_renders_library_tab.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/sonarr_ui/sonarr_ui_tests.rs +expression: output +--- +╭ Series ────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ +│──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ Title Year Network Status Rating Type Quality Prof Language Size Monitor Tags │ +│=> Test Series 0 Contin Standar Any English 0.00 GB │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/sonarr_ui_tests.rs b/src/ui/sonarr_ui/sonarr_ui_tests.rs index be3aaa6..8e14050 100644 --- a/src/ui/sonarr_ui/sonarr_ui_tests.rs +++ b/src/ui/sonarr_ui/sonarr_ui_tests.rs @@ -1,10 +1,16 @@ #[cfg(test)] mod tests { + use bimap::BiMap; use strum::IntoEnumIterator; use crate::{ - models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock, - ui::{DrawUi, sonarr_ui::SonarrUi}, + app::App, + models::{ + servarr_data::sonarr::sonarr_data::ActiveSonarrBlock, + sonarr_models::{DownloadRecord, DownloadStatus, Series, SonarrHistoryItem}, + stateful_table::StatefulTable, + }, + ui::{DrawUi, sonarr_ui::SonarrUi, ui_test_utils::test_utils::render_to_string_with_app}, }; #[test] @@ -13,4 +19,88 @@ mod tests { assert!(SonarrUi::accepts(active_sonarr_block.into())); }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_sonarr_ui_renders_downloads_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Series.into()); + app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter(vec![(0, "English".to_owned())]); + app.data.sonarr_data.main_tabs.set_index(1); // Downloads tab + app.data.sonarr_data.downloads = StatefulTable::default(); + app.data.sonarr_data.downloads.set_items(vec![ + DownloadRecord { + id: 1, + title: "Test Series S01E01".to_owned(), + status: DownloadStatus::Downloading, + size: 1500000000.0, + sizeleft: 500000000.0, + ..DownloadRecord::default() + }, + DownloadRecord { + id: 2, + title: "Another Series S02E05".to_owned(), + status: DownloadStatus::Downloading, + size: 1200000000.0, + sizeleft: 400000000.0, + ..DownloadRecord::default() + }, + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SonarrUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_sonarr_ui_renders_history_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Series.into()); + app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter(vec![(0, "English".to_owned())]); + app.data.sonarr_data.main_tabs.set_index(2); // History tab + app.data.sonarr_data.history = StatefulTable::default(); + app + .data + .sonarr_data + .history + .set_items(vec![SonarrHistoryItem::default()]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SonarrUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_sonarr_ui_renders_library_tab() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::Series.into()); + app.data.sonarr_data.quality_profile_map = BiMap::from_iter(vec![(0, "Any".to_owned())]); + app.data.sonarr_data.language_profiles_map = + BiMap::from_iter(vec![(0, "English".to_owned())]); + app.data.sonarr_data.main_tabs.set_index(0); // Library tab + app.data.sonarr_data.series = StatefulTable::default(); + app.data.sonarr_data.series.set_items(vec![Series { + id: 1, + title: "Test Series".into(), + quality_profile_id: 0, + ..Series::default() + }]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SonarrUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_loading_tasks.snap b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_loading_tasks.snap new file mode 100644 index 0000000..2434403 --- /dev/null +++ b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_loading_tasks.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/system/system_details_ui_tests.rs +expression: output +--- + + + + + ╭ Tasks ───────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ Loading ... │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_logs.snap b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_logs.snap new file mode 100644 index 0000000..44f2238 --- /dev/null +++ b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_logs.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/system/system_details_ui_tests.rs +expression: output +--- + + + + + ╭ Log Details ─────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_tasks.snap b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_tasks.snap new file mode 100644 index 0000000..2c7c537 --- /dev/null +++ b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_details_ui__system_details_ui_tests__tests__snapshot_tests__system_details_ui_renders_tasks.snap @@ -0,0 +1,30 @@ +--- +source: src/ui/sonarr_ui/system/system_details_ui_tests.rs +expression: output +--- + + + + + ╭ Tasks ───────────────────────────────────────────────────────────────────────────────╮ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + │ │ + ╰────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_loading_state.snap b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_loading_state.snap new file mode 100644 index 0000000..643dfb2 --- /dev/null +++ b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_loading_state.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/sonarr_ui/system/system_ui_tests.rs +expression: output +--- +╭ Tasks ─────────────────────────────────────────────────╮╭ Queued Events ─────────────────────────────────────────╮ +│ ││ │ +│ ││ │ +│ Loading ... ││ Loading ... │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +╰──────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────╯ +╭ Logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ │ +│ │ +│ Loading ... │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_system_menu.snap b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_system_menu.snap new file mode 100644 index 0000000..e98cdea --- /dev/null +++ b/src/ui/sonarr_ui/system/snapshots/managarr__ui__sonarr_ui__system__system_ui_tests__tests__snapshot_tests__system_ui_renders_system_menu.snap @@ -0,0 +1,34 @@ +--- +source: src/ui/sonarr_ui/system/system_ui_tests.rs +expression: output +--- +╭ Tasks ─────────────────────────────────────────────────╮╭ Queued Events ─────────────────────────────────────────╮ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +│ ││ │ +╰──────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────╯ +╭ Logs ──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/sonarr_ui/system/system_details_ui_tests.rs b/src/ui/sonarr_ui/system/system_details_ui_tests.rs index cf6af3d..d270e37 100644 --- a/src/ui/sonarr_ui/system/system_details_ui_tests.rs +++ b/src/ui/sonarr_ui/system/system_details_ui_tests.rs @@ -2,11 +2,14 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, SYSTEM_DETAILS_BLOCKS, }; + use crate::ui::DrawUi; use crate::ui::sonarr_ui::system::system_details_ui::SystemDetailsUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_system_details_ui_accepts() { @@ -18,4 +21,53 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_system_details_ui_renders_loading_tasks() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::SystemTasks.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_system_details_ui_renders_logs() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::SystemLogs.into()); + app.data.sonarr_data.logs.set_items(vec![ + "2023-01-01T12:00:00Z | Info | Test log message 1" + .to_owned() + .into(), + "2023-01-01T12:01:00Z | Warn | Test warning message" + .to_owned() + .into(), + ]); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_system_details_ui_renders_tasks() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::SystemTasks.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemDetailsUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/sonarr_ui/system/system_ui_tests.rs b/src/ui/sonarr_ui/system/system_ui_tests.rs index 9f6fd54..6234e1d 100644 --- a/src/ui/sonarr_ui/system/system_ui_tests.rs +++ b/src/ui/sonarr_ui/system/system_ui_tests.rs @@ -2,11 +2,13 @@ mod tests { use strum::IntoEnumIterator; + use crate::app::App; use crate::models::servarr_data::sonarr::sonarr_data::{ ActiveSonarrBlock, SYSTEM_DETAILS_BLOCKS, }; use crate::ui::DrawUi; use crate::ui::sonarr_ui::system::SystemUi; + use crate::ui::ui_test_utils::test_utils::render_to_string_with_app; #[test] fn test_system_ui_accepts() { @@ -22,4 +24,33 @@ mod tests { } }); } + + mod snapshot_tests { + use super::*; + + #[test] + fn test_system_ui_renders_loading_state() { + let mut app = App::test_default(); + app.is_loading = true; + app.push_navigation_stack(ActiveSonarrBlock::System.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_system_ui_renders_system_menu() { + let mut app = App::test_default(); + app.push_navigation_stack(ActiveSonarrBlock::System.into()); + + let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + SystemUi::draw(f, app, f.area()); + }); + + insta::assert_snapshot!(output); + } + } } diff --git a/src/ui/ui_property_tests.rs b/src/ui/ui_property_tests.rs new file mode 100644 index 0000000..03431e2 --- /dev/null +++ b/src/ui/ui_property_tests.rs @@ -0,0 +1,268 @@ +#[cfg(test)] +mod ui_invariant_tests { + use proptest::prelude::*; + use ratatui::Terminal; + use ratatui::backend::TestBackend; + use ratatui::layout::Rect; + + use crate::app::App; + use crate::models::radarr_models::Movie; + use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; + use crate::models::sonarr_models::Series; + use crate::models::{Scrollable, stateful_table::StatefulTable}; + use crate::ui::DrawUi; + use crate::ui::radarr_ui::RadarrUi; + use crate::ui::sonarr_ui::SonarrUi; + use prop::bool::ANY; + + proptest! { + #[test] + fn test_radarr_library_never_panics_on_large_datasets( + num_movies in 0usize..500, + viewport_height in 10u16..100, + ) { + let backend = TestBackend::new(120, viewport_height); + let mut terminal = Terminal::new(backend).unwrap(); + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + + let mut quality_profile_map = bimap::BiMap::new(); + quality_profile_map.insert(0, "Any".to_string()); + app.data.radarr_data.quality_profile_map = quality_profile_map; + + let movies: Vec = (0..num_movies) + .map(|i| Movie { + id: i as i64, + title: format!("Movie {}", i).into(), + ..Movie::default() + }) + .collect(); + + let mut table = StatefulTable::default(); + table.set_items(movies); + app.data.radarr_data.movies = table; + + terminal + .draw(|f| { + RadarrUi::draw(f, &mut app, f.area()); + }) + .unwrap(); + + let buffer = terminal.backend().buffer(); + prop_assert!(buffer.area().height <= viewport_height); + prop_assert!(buffer.area().width <= 120); + } + + #[test] + fn test_sonarr_library_never_panics_on_large_datasets( + num_series in 0usize..500, + viewport_height in 10u16..100, + ) { + let backend = TestBackend::new(120, viewport_height); + let mut terminal = Terminal::new(backend).unwrap(); + let mut app = App::test_default(); + app.push_navigation_stack( + crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock::Series.into() + ); + + let mut language_profiles_map = bimap::BiMap::new(); + language_profiles_map.insert(0, "English".to_string()); + app.data.sonarr_data.language_profiles_map = language_profiles_map; + + let mut quality_profile_map = bimap::BiMap::new(); + quality_profile_map.insert(0, "Any".to_string()); + app.data.sonarr_data.quality_profile_map = quality_profile_map; + + let series: Vec = (0..num_series) + .map(|i| Series { + id: i as i64, + title: format!("Series {}", i).into(), + ..Series::default() + }) + .collect(); + + let mut table = StatefulTable::default(); + table.set_items(series); + app.data.sonarr_data.series = table; + + terminal + .draw(|f| { + SonarrUi::draw(f, &mut app, f.area()); + }) + .unwrap(); + + let buffer = terminal.backend().buffer(); + prop_assert!(buffer.area().height <= viewport_height); + prop_assert!(buffer.area().width <= 120); + } + + #[test] + fn test_ui_respects_viewport_boundaries( + viewport_width in 40u16..200, + viewport_height in 10u16..100, + ) { + let backend = TestBackend::new(viewport_width, viewport_height); + let mut terminal = Terminal::new(backend).unwrap(); + let mut app = App::test_default(); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + + let mut quality_profile_map = bimap::BiMap::new(); + quality_profile_map.insert(0, "Any".to_string()); + app.data.radarr_data.quality_profile_map = quality_profile_map; + + let movies = vec![Movie { + id: 1, + title: "Very Long Movie Title That Should Be Scrollable And Not Overflow".into(), + ..Movie::default() + }]; + + let mut table = StatefulTable::default(); + table.set_items(movies); + app.data.radarr_data.movies = table; + + terminal + .draw(|f| { + RadarrUi::draw(f, &mut app, f.area()); + }) + .unwrap(); + + let buffer = terminal.backend().buffer(); + prop_assert_eq!(buffer.area().width, viewport_width); + prop_assert_eq!(buffer.area().height, viewport_height); + } + + #[test] + fn test_centered_rect_never_exceeds_parent( + parent_width in 20u16..200, + parent_height in 10u16..100, + percent_x in 1u16..=100, + percent_y in 1u16..=100, + ) { + use crate::ui::utils::centered_rect; + + let parent = Rect { + x: 0, + y: 0, + width: parent_width, + height: parent_height, + }; + + let centered = centered_rect(percent_x, percent_y, parent); + + prop_assert!(centered.x >= parent.x); + prop_assert!(centered.y >= parent.y); + prop_assert!(centered.x + centered.width <= parent.x + parent.width); + prop_assert!(centered.y + centered.height <= parent.y + parent.height); + } + + #[test] + fn test_table_navigation_stays_in_bounds( + num_items in 1usize..100, + num_scrolls in 0usize..200, + ) { + let mut table = StatefulTable::default(); + let movies: Vec = (0..num_items) + .map(|i| Movie { + id: i as i64, + title: format!("Movie {}", i).into(), + ..Movie::default() + }) + .collect(); + + table.set_items(movies); + + for _ in 0..num_scrolls { + table.scroll_down(); + } + + let current_item = table.current_selection(); + prop_assert!(current_item.id >= 0 && (current_item.id as usize) < num_items); + + for _ in 0..num_scrolls { + table.scroll_up(); + } + + let current_item_after = table.current_selection(); + prop_assert!(current_item_after.id >= 0 && (current_item_after.id as usize) < num_items); + } + + #[test] + fn test_empty_tables_handle_navigation_gracefully( + num_scroll_attempts in 0usize..50, + ) { + let mut table = StatefulTable::::default(); + + for _ in 0..num_scroll_attempts { + table.scroll_down(); + table.scroll_up(); + } + + prop_assert!(true); + } + + #[test] + fn test_loading_state_never_panics( + is_loading in ANY, + num_items in 0usize..100, + ) { + let backend = TestBackend::new(120, 30); + let mut terminal = Terminal::new(backend).unwrap(); + let mut app = App::test_default(); + app.is_loading = is_loading; + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + + let mut quality_profile_map = bimap::BiMap::new(); + quality_profile_map.insert(0, "Any".to_string()); + app.data.radarr_data.quality_profile_map = quality_profile_map; + + let movies: Vec = (0..num_items) + .map(|i| Movie { + id: i as i64, + title: format!("Movie {}", i).into(), + ..Movie::default() + }) + .collect(); + + let mut table = StatefulTable::default(); + table.set_items(movies); + app.data.radarr_data.movies = table; + + terminal + .draw(|f| { + RadarrUi::draw(f, &mut app, f.area()); + }) + .unwrap(); + + prop_assert!(true); + } + + #[test] + fn test_navigation_stack_maintains_route_integrity( + stack_depth in 1usize..10, + ) { + let mut app = App::test_default(); + + let blocks = [ActiveRadarrBlock::Movies, + ActiveRadarrBlock::Collections, + ActiveRadarrBlock::Downloads, + ActiveRadarrBlock::Blocklist, + ActiveRadarrBlock::RootFolders]; + + for i in 0..stack_depth { + let block = blocks[i % blocks.len()]; + app.push_navigation_stack(block.into()); + } + + let current_route = app.get_current_route(); + let expected_block = blocks[(stack_depth - 1) % blocks.len()]; + prop_assert!(matches!(current_route, crate::models::Route::Radarr(block, _) if block == expected_block)); + + for _ in 0..stack_depth { + app.pop_navigation_stack(); + } + + let final_route = app.get_current_route(); + prop_assert!(matches!(final_route, crate::models::Route::Radarr(_, _))); + } + } +} diff --git a/src/ui/ui_test_utils.rs b/src/ui/ui_test_utils.rs new file mode 100644 index 0000000..6e950a1 --- /dev/null +++ b/src/ui/ui_test_utils.rs @@ -0,0 +1,126 @@ +#[cfg(test)] +#[allow(dead_code)] +pub mod test_utils { + use ratatui::Frame; + use ratatui::Terminal; + use ratatui::backend::TestBackend; + use ratatui::buffer::Buffer; + + use crate::app::App; + + pub fn create_test_backend(width: u16, height: u16) -> TestBackend { + TestBackend::new(width, height) + } + + pub fn create_test_terminal(width: u16, height: u16) -> Terminal { + let backend = create_test_backend(width, height); + Terminal::new(backend).unwrap() + } + + /// Renders a UI component and returns the output as a string + /// + /// # Arguments + /// * `width` - Terminal width in columns + /// * `height` - Terminal height in rows + /// * `render_fn` - Function that renders to the frame + /// + /// # Example + /// ```rust + /// let output = render_to_string(120, 30, |f| { + /// Block::default().title("Test").render(f.area(), f.buffer_mut()); + /// }); + /// ``` + pub fn render_to_string(width: u16, height: u16, mut render_fn: F) -> String + where + F: FnMut(&mut Frame), + { + let mut terminal = create_test_terminal(width, height); + + terminal + .draw(|f| { + render_fn(f); + }) + .unwrap(); + + buffer_to_string(terminal.backend().buffer(), width, height) + } + + /// Renders a UI component with an App instance and returns the output as a string + /// + /// This is the primary helper for testing UI components that need app state. + /// + /// # Arguments + /// * `width` - Terminal width in columns (typically 120) + /// * `height` - Terminal height in rows (typically 30) + /// * `app` - Mutable reference to App instance + /// * `render_fn` - Function that renders to the frame with app + /// + /// # Example + /// ```rust + /// let mut app = App::test_default(); + /// app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + /// + /// let output = render_to_string_with_app(120, 30, &mut app, |f, app| { + /// LibraryUi::draw(f, app, f.area()); + /// }); + /// + /// insta::assert_snapshot!(output); + /// ``` + pub fn render_to_string_with_app( + width: u16, + height: u16, + app: &mut App, + mut render_fn: F, + ) -> String + where + F: FnMut(&mut Frame, &mut App), + { + let mut terminal = create_test_terminal(width, height); + + terminal + .draw(|f| { + render_fn(f, app); + }) + .unwrap(); + + buffer_to_string(terminal.backend().buffer(), width, height) + } + + fn buffer_to_string(buffer: &Buffer, width: u16, height: u16) -> String { + let mut result = String::new(); + + for y in 0..height { + for x in 0..width { + let cell = buffer.cell((x, y)).expect("Cell should exist"); + result.push_str(cell.symbol()); + } + if y < height - 1 { + result.push('\n'); + } + } + + result + } + + pub fn output_contains(output: &str, text: &str) -> bool { + output.contains(text) + } + + pub fn output_contains_all(output: &str, texts: &[&str]) -> bool { + texts.iter().all(|text| output.contains(text)) + } + + pub fn count_lines(output: &str) -> usize { + output.lines().count() + } + + pub fn verify_dimensions(output: &str, max_width: usize, max_height: usize) -> bool { + let lines: Vec<&str> = output.lines().collect(); + + if lines.len() > max_height { + return false; + } + + lines.iter().all(|line| line.chars().count() <= max_width) + } +}