diff --git a/src/app/mod.rs b/src/app/mod.rs index 0095bca..2ab870d 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -13,6 +13,7 @@ use tokio_util::sync::CancellationToken; use veil::Redact; use crate::cli::Command; +use crate::models::servarr_data::Notification; use crate::models::servarr_data::lidarr::lidarr_data::{ActiveLidarrBlock, LidarrData}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData}; @@ -38,6 +39,7 @@ pub struct App<'a> { pub server_tabs: TabState, pub keymapping_table: Option>, pub error: HorizontallyScrollableText, + pub notification: Option, pub tick_until_poll: u64, pub ticks_until_scroll: u64, pub tick_count: u64, @@ -254,6 +256,7 @@ impl Default for App<'_> { cancellation_token: CancellationToken::new(), keymapping_table: None, error: HorizontallyScrollableText::default(), + notification: None, is_first_render: true, server_tabs: TabState::new(Vec::new()), tick_until_poll: 400, diff --git a/src/handlers/handlers_tests.rs b/src/handlers/handlers_tests.rs index 819921b..cf96c8a 100644 --- a/src/handlers/handlers_tests.rs +++ b/src/handlers/handlers_tests.rs @@ -20,10 +20,10 @@ mod tests { use crate::handlers::{handle_events, populate_keymapping_table}; use crate::models::HorizontallyScrollableText; use crate::models::Route; - use crate::models::servarr_data::ActiveKeybindingBlock; use crate::models::servarr_data::lidarr::lidarr_data::ActiveLidarrBlock; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData}; use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock; + use crate::models::servarr_data::{ActiveKeybindingBlock, Notification}; use crate::models::servarr_models::KeybindingItem; use crate::models::stateful_table::StatefulTable; @@ -284,6 +284,39 @@ mod tests { ); } + #[test] + fn test_handle_events_esc_clears_notification() { + let mut app = App::test_default(); + app.notification = Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + + handle_events(DEFAULT_KEYBINDINGS.esc.key, &mut app); + + assert_none!(app.notification); + assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); + } + + #[test] + fn test_handle_events_esc_does_not_clear_notification_when_none() { + let mut app = App::test_default(); + app + .data + .radarr_data + .movies + .set_items(vec![Movie::default()]); + app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); + app.push_navigation_stack(ActiveRadarrBlock::SearchMovie.into()); + + handle_events(DEFAULT_KEYBINDINGS.esc.key, &mut app); + + assert_none!(app.notification); + assert_navigation_popped!(app, ActiveRadarrBlock::Movies.into()); + } + fn context_clue_to_keybinding_item(key: &KeyBinding, desc: &&str) -> KeybindingItem { let (key, alt_key) = if key.alt.is_some() { (key.key.to_string(), key.alt.as_ref().unwrap().to_string()) diff --git a/src/handlers/mod.rs b/src/handlers/mod.rs index 316ba13..6c841f4 100644 --- a/src/handlers/mod.rs +++ b/src/handlers/mod.rs @@ -2,11 +2,11 @@ use lidarr_handlers::LidarrHandler; use radarr_handlers::RadarrHandler; use sonarr_handlers::SonarrHandler; -use crate::app::App; use crate::app::context_clues::{ - ContextClueProvider, SERVARR_CONTEXT_CLUES, ServarrContextClueProvider, + ContextClueProvider, ServarrContextClueProvider, SERVARR_CONTEXT_CLUES, }; use crate::app::key_binding::KeyBinding; +use crate::app::App; use crate::event::Key; use crate::handlers::keybinding_handler::KeybindingHandler; use crate::matches_key; @@ -116,6 +116,7 @@ pub fn handle_events(key: Key, app: &mut App<'_>) { } else { app.keymapping_table = None; } + } else if matches_key!(esc, key) && handle_clear_notification(app) { } else { match app.get_current_route() { _ if app.keymapping_table.is_some() => { @@ -183,6 +184,10 @@ fn handle_clear_errors(app: &mut App<'_>) { } } +fn handle_clear_notification(app: &mut App<'_>) -> bool { + app.notification.take().is_some() +} + fn handle_prompt_toggle(app: &mut App<'_>, key: Key) { match key { _ if matches_key!(left, key) || matches_key!(right, key) => match app.get_current_route() { diff --git a/src/models/servarr_data/mod.rs b/src/models/servarr_data/mod.rs index 256f0bc..c058380 100644 --- a/src/models/servarr_data/mod.rs +++ b/src/models/servarr_data/mod.rs @@ -10,6 +10,23 @@ pub(in crate::models::servarr_data) mod data_test_utils; #[cfg(test)] mod servarr_data_tests; +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct Notification { + pub title: String, + pub message: String, + pub success: bool, +} + +impl Notification { + pub fn new(title: String, message: String, success: bool) -> Self { + Self { + title, + message, + success, + } + } +} + #[derive(Clone, Copy, PartialEq, Eq, Debug, Default)] pub enum ActiveKeybindingBlock { #[default] diff --git a/src/network/lidarr_network/library/lidarr_library_network_tests.rs b/src/network/lidarr_network/library/lidarr_library_network_tests.rs index 133d37b..2ae68da 100644 --- a/src/network/lidarr_network/library/lidarr_library_network_tests.rs +++ b/src/network/lidarr_network/library/lidarr_library_network_tests.rs @@ -1,8 +1,10 @@ #[cfg(test)] mod tests { use crate::models::lidarr_models::LidarrReleaseDownloadBody; + use crate::models::servarr_data::Notification; use crate::network::lidarr_network::LidarrEvent; - use crate::network::network_tests::test_utils::{MockServarrApi, test_network}; + use crate::network::network_tests::test_utils::{test_network, MockServarrApi}; + use pretty_assertions::assert_eq; use serde_json::json; #[tokio::test] @@ -30,5 +32,51 @@ mod tests { mock.assert_async().await; assert_ok!(result); + assert_eq!( + app.lock().await.notification, + Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )) + ); + } + + #[tokio::test] + async fn test_handle_download_lidarr_release_event_sets_failure_notification_on_error() { + let params = LidarrReleaseDownloadBody { + guid: "1234".to_owned(), + indexer_id: 2, + }; + + let (mock, app, _server) = MockServarrApi::post() + .with_request_body(json!({ + "guid": "1234", + "indexerId": 2, + })) + .returns(json!({})) + .status(500) + .build_for(LidarrEvent::DownloadRelease(params.clone())) + .await; + + app.lock().await.server_tabs.set_index(2); + let mut network = test_network(&app); + + let result = network + .handle_lidarr_event(LidarrEvent::DownloadRelease(params)) + .await; + + mock.assert_async().await; + assert_err!(result); + let app = app.lock().await; + assert_is_empty!(app.error.text); + assert_some_eq_x!( + &app.notification, + &Notification::new( + "Download Failed".to_owned(), + "Download request failed. Check the logs for more details.".to_owned(), + false, + ) + ); } } diff --git a/src/network/lidarr_network/library/mod.rs b/src/network/lidarr_network/library/mod.rs index f20624f..aa68d60 100644 --- a/src/network/lidarr_network/library/mod.rs +++ b/src/network/lidarr_network/library/mod.rs @@ -1,4 +1,5 @@ use crate::models::lidarr_models::LidarrReleaseDownloadBody; +use crate::models::servarr_data::Notification; use crate::network::lidarr_network::LidarrEvent; use crate::network::{Network, RequestMethod}; use anyhow::Result; @@ -31,8 +32,26 @@ impl Network<'_, '_> { ) .await; - self - .handle_request::(request_props, |_, _| ()) - .await + let result = self + .handle_request::(request_props, |_, mut app| { + app.notification = Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )); + }) + .await; + + if result.is_err() { + let mut app = self.app.lock().await; + std::mem::take(&mut app.error.text); + app.notification = Some(Notification::new( + "Download Failed".to_owned(), + "Download request failed. Check the logs for more details.".to_owned(), + false, + )); + } + + result } } diff --git a/src/network/radarr_network/library/mod.rs b/src/network/radarr_network/library/mod.rs index c68a63c..42b2d67 100644 --- a/src/network/radarr_network/library/mod.rs +++ b/src/network/radarr_network/library/mod.rs @@ -3,6 +3,7 @@ use crate::models::radarr_models::{ EditMovieParams, Movie, MovieCommandBody, MovieHistoryItem, RadarrRelease, RadarrReleaseDownloadBody, }; +use crate::models::servarr_data::Notification; use crate::models::servarr_data::radarr::modals::MovieDetailsModal; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::stateful_table::StatefulTable; @@ -85,9 +86,27 @@ impl Network<'_, '_> { .request_props_from(event, RequestMethod::Post, Some(params), None, None) .await; - self - .handle_request::(request_props, |_, _| ()) - .await + let result = self + .handle_request::(request_props, |_, mut app| { + app.notification = Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )); + }) + .await; + + if result.is_err() { + let mut app = self.app.lock().await; + std::mem::take(&mut app.error.text); + app.notification = Some(Notification::new( + "Download Failed".to_owned(), + "Download request failed. Check the logs for more details.".to_owned(), + false, + )); + } + + result } pub(in crate::network::radarr_network) async fn edit_movie( diff --git a/src/network/radarr_network/library/radarr_library_network_tests.rs b/src/network/radarr_network/library/radarr_library_network_tests.rs index 26215e4..941f010 100644 --- a/src/network/radarr_network/library/radarr_library_network_tests.rs +++ b/src/network/radarr_network/library/radarr_library_network_tests.rs @@ -4,6 +4,7 @@ mod tests { AddMovieBody, AddMovieOptions, Credit, DeleteMovieParams, DownloadRecord, EditMovieParams, MinimumAvailability, Movie, MovieHistoryItem, MovieMonitor, RadarrReleaseDownloadBody, }; + use crate::models::servarr_data::Notification; use crate::models::servarr_data::radarr::modals::MovieDetailsModal; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::stateful_table::SortOption; @@ -164,14 +165,58 @@ mod tests { .await; let mut network = test_network(&app); - assert!( - network - .handle_radarr_event(RadarrEvent::DownloadRelease(expected_body)) - .await - .is_ok() - ); + let result = network + .handle_radarr_event(RadarrEvent::DownloadRelease(expected_body)) + .await; mock.assert_async().await; + assert_ok!(result); + assert_some_eq_x!( + &app.lock().await.notification, + &Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + ) + ); + } + + #[tokio::test] + async fn test_handle_download_radarr_release_event_sets_failure_notification_on_error() { + let expected_body = RadarrReleaseDownloadBody { + guid: "1234".to_owned(), + indexer_id: 2, + movie_id: 1, + }; + let body = json!({ + "guid": "1234", + "indexerId": 2, + "movieId": 1 + }); + let (mock, app, _server) = MockServarrApi::post() + .with_request_body(body) + .returns(json!({})) + .status(500) + .build_for(RadarrEvent::DownloadRelease(expected_body.clone())) + .await; + let mut network = test_network(&app); + + let result = network + .handle_radarr_event(RadarrEvent::DownloadRelease(expected_body)) + .await; + + mock.assert_async().await; + assert_err!(result); + let app = app.lock().await; + assert_is_empty!(app.error.text); + assert_some_eq_x!( + &app.notification, + &Notification::new( + "Download Failed".to_owned(), + "Download request failed. Check the logs for more details.".to_owned(), + false, + ) + ); } #[tokio::test] diff --git a/src/network/sonarr_network/library/mod.rs b/src/network/sonarr_network/library/mod.rs index 15c4a2c..b09c301 100644 --- a/src/network/sonarr_network/library/mod.rs +++ b/src/network/sonarr_network/library/mod.rs @@ -1,3 +1,4 @@ +use crate::models::servarr_data::Notification; use crate::models::sonarr_models::SonarrReleaseDownloadBody; use crate::network::sonarr_network::SonarrEvent; use crate::network::{Network, RequestMethod}; @@ -31,8 +32,26 @@ impl Network<'_, '_> { ) .await; - self - .handle_request::(request_props, |_, _| ()) - .await + let result = self + .handle_request::(request_props, |_, mut app| { + app.notification = Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )); + }) + .await; + + if result.is_err() { + let mut app = self.app.lock().await; + std::mem::take(&mut app.error.text); + app.notification = Some(Notification::new( + "Download Failed".to_owned(), + "Download request failed. Check the logs for more details.".to_owned(), + false, + )); + } + + result } } diff --git a/src/network/sonarr_network/library/sonarr_library_network_tests.rs b/src/network/sonarr_network/library/sonarr_library_network_tests.rs index 68562d3..08484df 100644 --- a/src/network/sonarr_network/library/sonarr_library_network_tests.rs +++ b/src/network/sonarr_network/library/sonarr_library_network_tests.rs @@ -1,8 +1,10 @@ #[cfg(test)] mod tests { + use crate::models::servarr_data::Notification; use crate::models::sonarr_models::SonarrReleaseDownloadBody; - use crate::network::network_tests::test_utils::{MockServarrApi, test_network}; + use crate::network::network_tests::test_utils::{test_network, MockServarrApi}; use crate::network::sonarr_network::SonarrEvent; + use pretty_assertions::assert_eq; use serde_json::json; #[tokio::test] @@ -33,5 +35,54 @@ mod tests { mock.assert_async().await; assert_ok!(result); + assert_eq!( + app.lock().await.notification, + Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )) + ); + } + + #[tokio::test] + async fn test_handle_download_sonarr_release_event_sets_failure_notification_on_error() { + let params = SonarrReleaseDownloadBody { + guid: "1234".to_owned(), + indexer_id: 2, + series_id: Some(1), + ..SonarrReleaseDownloadBody::default() + }; + + let (mock, app, _server) = MockServarrApi::post() + .with_request_body(json!({ + "guid": "1234", + "indexerId": 2, + "seriesId": 1, + })) + .returns(json!({})) + .status(500) + .build_for(SonarrEvent::DownloadRelease(params.clone())) + .await; + + app.lock().await.server_tabs.next(); + let mut network = test_network(&app); + + let result = network + .handle_sonarr_event(SonarrEvent::DownloadRelease(params)) + .await; + + mock.assert_async().await; + assert_err!(result); + let app = app.lock().await; + assert_is_empty!(app.error.text); + assert_some_eq_x!( + &app.notification, + &Notification::new( + "Download Failed".to_owned(), + "Download request failed. Check the logs for more details.".to_owned(), + false, + ) + ); } } diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 9842a5f..502a7c1 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -14,6 +14,7 @@ use sonarr_ui::SonarrUi; use utils::layout_block; use crate::app::App; +use crate::models::servarr_data::Notification; use crate::models::servarr_models::KeybindingItem; use crate::models::{HorizontallyScrollableText, Route, TabState}; use crate::ui::radarr_ui::RadarrUi; @@ -25,7 +26,8 @@ use crate::ui::utils::{ }; use crate::ui::widgets::input_box::InputBox; use crate::ui::widgets::managarr_table::ManagarrTable; -use crate::ui::widgets::popup::Size; +use crate::ui::widgets::message::Message; +use crate::ui::widgets::popup::{Popup, Size}; mod builtin_themes; mod lidarr_ui; @@ -95,6 +97,10 @@ pub fn ui(f: &mut Frame<'_>, app: &mut App<'_>) { _ => (), } + if let Some(notification) = &app.notification { + draw_notification_popup(f, notification); + } + if app.keymapping_table.is_some() { draw_help_popup(f, app); } @@ -183,6 +189,22 @@ pub fn draw_help_popup(f: &mut Frame<'_>, app: &mut App<'_>) { f.render_widget(keymapping_table, table_area); } +fn draw_notification_popup(f: &mut Frame<'_>, notification: &Notification) { + let style = if notification.success { + styles::success_style().bold() + } else { + styles::failure_style().bold() + }; + + let popup = Popup::new( + Message::new(notification.message.as_str()) + .title(notification.title.as_str()) + .style(style), + ) + .size(Size::Message); + f.render_widget(popup, f.area()); +} + fn draw_tabs(f: &mut Frame<'_>, area: Rect, title: &str, tab_state: &TabState) -> Rect { if title.is_empty() { f.render_widget(layout_block().default_color(), area); diff --git a/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__lidarr_ui_renders_notification_success_popup.snap b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__lidarr_ui_renders_notification_success_popup.snap new file mode 100644 index 0000000..201b8a9 --- /dev/null +++ b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__lidarr_ui_renders_notification_success_popup.snap @@ -0,0 +1,54 @@ +--- +source: src/ui/ui_tests.rs +expression: output +--- +╭ Managarr - A Servarr management TUI ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Radarr │ Sonarr │ Lidarr to open help│ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭ Stats ──────────────────────────────────────────────────────────────╮╭ Downloads ─────────────────────────────────────────────────────────╮╭──────────────────╮ +│Lidarr Version: 1.2.3.4 ││Test download title ││ ⠀⠀⠀⣠⣴⣶⡿⠻⣿⣶⣦⣄⠀⠀⠀ │ +│Uptime: 0d 00:00:44 ││50% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ⠀⢠⣾⠟⠋⠀⠀⢀⣀⠀⠙⠻⣷⡄⠀ │ +│Storage: ││ ││ ⢠⣿⠋⠀⣴⠃⠀⢸⣿⣿⣦⡀⠙⣿⡄ │ +│/path: 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ││ ⣾⡟⠀⢸⠃⠀⠀⠀⠈⠉⠉⠁⠀⢹⣷ │ +│Root Folders: ││ ││ ⢿⣧⠀⠈⠀⠀⠀⠀⠀⠀⢀⡟⠀⣸⡿ │ +│/nfs: 204800.00 GB free ││ ││ ⠘⣿⣄⠀⠻⣿⣿⡇⠀⢀⠞⠀⣠⣿⠃ │ +│ ││ ││ ⠀⠘⢿⣦⣄⠀⠉⠁⠀⠀⣠⣴⡿⠃⠀ │ +│ ││ ││ ⠀⠀⠀⠉⠻⠿⢿⡆⡾⠿⠟⠉⠀⠀⠀ │ +╰───────────────────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────╯╰──────────────────╯ +╭ Artists ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ +│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ Name ▼ Type Status Quality Profile Metadata Profile Albums Tracks Size Monitored Tags │ +│=> Alex Person Continuing Lossless Standard 1 15/15 0.00 GB 🏷 alex │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ ╭────────── Download Result ──────────╮ │ +│ │ Download request sent successfully │ │ +│ │ │ │ +│ ╰───────────────────────────────────────╯ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__radarr_ui_renders_notification_failure_popup.snap b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__radarr_ui_renders_notification_failure_popup.snap new file mode 100644 index 0000000..ce9f2c0 --- /dev/null +++ b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__radarr_ui_renders_notification_failure_popup.snap @@ -0,0 +1,54 @@ +--- +source: src/ui/ui_tests.rs +expression: output +--- +╭ Managarr - A Servarr management TUI ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Radarr │ Sonarr │ Lidarr to open help│ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭ Stats ──────────────────────────────────────────────────────────────╮╭ Downloads ─────────────────────────────────────────────────────────╮╭──────────────────╮ +│Radarr Version: 1.2.3.4 ││Test Download Title ││ ⠀⣠⣶⢶⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀ │ +│Uptime: 0d 00:00:44 ││50% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ⠀⣿⡇⠀⠈⠙⠻⢿⣶⣤⡀⠀⠀⠀⠀ │ +│Storage: ││ ││ ⠀⣿⡇⠀⠀⠀⠀⠀⠈⠙⠻⢷⣦⡄⠀ │ +│/path: 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ││ ⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢉⠻⠀ │ +│Root Folders: ││ ││ ⠀⣿⡇⠀⠀⠀⠀⠀⢀⣠⣴⣾⠿⠀⠀ │ +│/nfs: 204800.00 GB free ││ ││ ⠀⢿⡇⠀⠀⣀⣤⣶⡿⠛⠉⠀⠀⠀⠀ │ +│ ││ ││ ⠀⠀⠰⠶⡿⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀ │ +│ ││ ││ │ +╰───────────────────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────╯╰──────────────────╯ +╭ Movies ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Collections │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ +│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ Title ▼ Year Studio Runtime Rating Language Size Quality Profile Monitored Tags │ +│=> Test 2023 21st Century Alex 2h 0m R English 3.30 GB HD - 1080p 🏷 alex │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ ╭────────── Download Failed ──────────╮ │ +│ │ Request failed. Received 500 response │ │ +│ │ code │ │ +│ ╰───────────────────────────────────────╯ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__radarr_ui_renders_notification_success_popup.snap b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__radarr_ui_renders_notification_success_popup.snap new file mode 100644 index 0000000..ed22e92 --- /dev/null +++ b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__radarr_ui_renders_notification_success_popup.snap @@ -0,0 +1,54 @@ +--- +source: src/ui/ui_tests.rs +expression: output +--- +╭ Managarr - A Servarr management TUI ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Radarr │ Sonarr │ Lidarr to open help│ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭ Stats ──────────────────────────────────────────────────────────────╮╭ Downloads ─────────────────────────────────────────────────────────╮╭──────────────────╮ +│Radarr Version: 1.2.3.4 ││Test Download Title ││ ⠀⣠⣶⢶⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀ │ +│Uptime: 0d 00:00:44 ││50% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ⠀⣿⡇⠀⠈⠙⠻⢿⣶⣤⡀⠀⠀⠀⠀ │ +│Storage: ││ ││ ⠀⣿⡇⠀⠀⠀⠀⠀⠈⠙⠻⢷⣦⡄⠀ │ +│/path: 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ││ ⠀⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⢉⠻⠀ │ +│Root Folders: ││ ││ ⠀⣿⡇⠀⠀⠀⠀⠀⢀⣠⣴⣾⠿⠀⠀ │ +│/nfs: 204800.00 GB free ││ ││ ⠀⢿⡇⠀⠀⣀⣤⣶⡿⠛⠉⠀⠀⠀⠀ │ +│ ││ ││ ⠀⠀⠰⠶⡿⠟⠋⠁⠀⠀⠀⠀⠀⠀⠀ │ +│ ││ ││ │ +╰───────────────────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────╯╰──────────────────╯ +╭ Movies ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Collections │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ +│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ Title ▼ Year Studio Runtime Rating Language Size Quality Profile Monitored Tags │ +│=> Test 2023 21st Century Alex 2h 0m R English 3.30 GB HD - 1080p 🏷 alex │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ ╭────────── Download Result ──────────╮ │ +│ │ Download request sent successfully │ │ +│ │ │ │ +│ ╰───────────────────────────────────────╯ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__sonarr_ui_renders_notification_success_popup.snap b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__sonarr_ui_renders_notification_success_popup.snap new file mode 100644 index 0000000..7cd77bf --- /dev/null +++ b/src/ui/snapshots/managarr__ui__ui_tests__snapshot_tests__sonarr_ui_renders_notification_success_popup.snap @@ -0,0 +1,54 @@ +--- +source: src/ui/ui_tests.rs +expression: output +--- +╭ Managarr - A Servarr management TUI ──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Radarr │ Sonarr │ Lidarr to open help│ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ +╭ Stats ──────────────────────────────────────────────────────────────╮╭ Downloads ─────────────────────────────────────────────────────────╮╭──────────────────╮ +│Sonarr Version: 1.2.3.4 ││Test Download Title ││ ⠀⠀⠀⣠⣴⣶⣿⣿⣿⣿⣶⣦⣄⠀⠀⠀ │ +│Uptime: 0d 00:00:44 ││50% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ⠀⣠⡀⠈⠻⣿⣿⣿⣿⣿⣿⠟⠁⢀⣀⠀ │ +│Storage: ││ ││ ⢰⣿⣿⣦⠐⠄⠉⠉⠉⠉⠠⠂⣰⣿⣿⡆ │ +│/path: 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━││ ││ ⣿⣿⣿⣿⡆⠀⣴⣿⣿⣦⠀⢰⣿⣿⣿⣿ │ +│Root Folders: ││ ││ ⣿⣿⣿⣿⡇⠀⠻⣿⣿⠟⠀⠸⣿⣿⣿⣿ │ +│/nfs: 204800.00 GB free ││ ││ ⠸⣿⣿⠟⠠⠂⠀⢀⡀⠀⠐⠄⠻⣿⣿⠇ │ +│ ││ ││ ⠀⠙⠁⢀⣴⣾⣿⣿⣿⣿⣷⣦⡀⠈⠋⠀ │ +│ ││ ││ ⠀⠀⠀⠘⠻⠿⣿⣿⣿⣿⠿⠟⠋⠀⠀⠀ │ +╰───────────────────────────────────────────────────────────────────────╯╰──────────────────────────────────────────────────────────────────────╯╰──────────────────╯ +╭ Series ─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +│ Library │ Downloads │ Blocklist │ History │ Root Folders │ Indexers │ System │ +│───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────│ +│ Title ▼ Year Network Status Rating Type Quality Profile Language Size Monitored Tags │ +│=> Test 2022 HBO Continuin TV-MA Standard Bluray-1080p English 59.51 GB 🏷 │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ ╭────────── Download Result ──────────╮ │ +│ │ Download request sent successfully │ │ +│ │ │ │ +│ ╰───────────────────────────────────────╯ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +│ │ +╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ diff --git a/src/ui/ui_tests.rs b/src/ui/ui_tests.rs index 53dfe57..555e0ba 100644 --- a/src/ui/ui_tests.rs +++ b/src/ui/ui_tests.rs @@ -2,6 +2,7 @@ mod snapshot_tests { use crate::app::App; use crate::handlers::populate_keymapping_table; + use crate::models::servarr_data::Notification; use crate::models::servarr_data::lidarr::lidarr_data::ActiveLidarrBlock; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock; @@ -46,6 +47,40 @@ mod snapshot_tests { insta::assert_snapshot!(output); } + #[test] + fn test_radarr_ui_renders_notification_success_popup() { + let mut app = App::test_default_fully_populated(); + app.notification = Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )); + app.push_navigation_stack(ActiveRadarrBlock::default().into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + ui(f, app); + }); + + insta::assert_snapshot!(output); + } + + #[test] + fn test_radarr_ui_renders_notification_failure_popup() { + let mut app = App::test_default_fully_populated(); + app.notification = Some(Notification::new( + "Download Failed".to_owned(), + "Request failed. Received 500 response code".to_owned(), + false, + )); + app.push_navigation_stack(ActiveRadarrBlock::default().into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + ui(f, app); + }); + + insta::assert_snapshot!(output); + } + #[test] fn test_sonarr_ui_renders_library_tab() { let mut app = App::test_default_fully_populated(); @@ -84,6 +119,23 @@ mod snapshot_tests { insta::assert_snapshot!(output); } + #[test] + fn test_sonarr_ui_renders_notification_success_popup() { + let mut app = App::test_default_fully_populated(); + app.notification = Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )); + app.push_navigation_stack(ActiveSonarrBlock::default().into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + ui(f, app); + }); + + insta::assert_snapshot!(output); + } + #[test] fn test_lidarr_ui_renders_library_tab() { let mut app = App::test_default_fully_populated(); @@ -109,6 +161,23 @@ mod snapshot_tests { insta::assert_snapshot!(output); } + #[test] + fn test_lidarr_ui_renders_notification_success_popup() { + let mut app = App::test_default_fully_populated(); + app.notification = Some(Notification::new( + "Download Result".to_owned(), + "Download request sent successfully".to_owned(), + true, + )); + app.push_navigation_stack(ActiveLidarrBlock::default().into()); + + let output = render_to_string_with_app(TerminalSize::Large, &mut app, |f, app| { + ui(f, app); + }); + + insta::assert_snapshot!(output); + } + #[test] fn test_lidarr_ui_renders_library_tab_error_popup() { let mut app = App::test_default_fully_populated();