feat: Added support for a system-wide notification popup mechanism that works across Servarrs
This commit is contained in:
@@ -13,6 +13,7 @@ use tokio_util::sync::CancellationToken;
|
|||||||
use veil::Redact;
|
use veil::Redact;
|
||||||
|
|
||||||
use crate::cli::Command;
|
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::lidarr::lidarr_data::{ActiveLidarrBlock, LidarrData};
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData};
|
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData};
|
||||||
@@ -38,6 +39,7 @@ pub struct App<'a> {
|
|||||||
pub server_tabs: TabState,
|
pub server_tabs: TabState,
|
||||||
pub keymapping_table: Option<StatefulTable<KeybindingItem>>,
|
pub keymapping_table: Option<StatefulTable<KeybindingItem>>,
|
||||||
pub error: HorizontallyScrollableText,
|
pub error: HorizontallyScrollableText,
|
||||||
|
pub notification: Option<Notification>,
|
||||||
pub tick_until_poll: u64,
|
pub tick_until_poll: u64,
|
||||||
pub ticks_until_scroll: u64,
|
pub ticks_until_scroll: u64,
|
||||||
pub tick_count: u64,
|
pub tick_count: u64,
|
||||||
@@ -254,6 +256,7 @@ impl Default for App<'_> {
|
|||||||
cancellation_token: CancellationToken::new(),
|
cancellation_token: CancellationToken::new(),
|
||||||
keymapping_table: None,
|
keymapping_table: None,
|
||||||
error: HorizontallyScrollableText::default(),
|
error: HorizontallyScrollableText::default(),
|
||||||
|
notification: None,
|
||||||
is_first_render: true,
|
is_first_render: true,
|
||||||
server_tabs: TabState::new(Vec::new()),
|
server_tabs: TabState::new(Vec::new()),
|
||||||
tick_until_poll: 400,
|
tick_until_poll: 400,
|
||||||
|
|||||||
@@ -20,10 +20,10 @@ mod tests {
|
|||||||
use crate::handlers::{handle_events, populate_keymapping_table};
|
use crate::handlers::{handle_events, populate_keymapping_table};
|
||||||
use crate::models::HorizontallyScrollableText;
|
use crate::models::HorizontallyScrollableText;
|
||||||
use crate::models::Route;
|
use crate::models::Route;
|
||||||
use crate::models::servarr_data::ActiveKeybindingBlock;
|
|
||||||
use crate::models::servarr_data::lidarr::lidarr_data::ActiveLidarrBlock;
|
use crate::models::servarr_data::lidarr::lidarr_data::ActiveLidarrBlock;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
|
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
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::servarr_models::KeybindingItem;
|
||||||
use crate::models::stateful_table::StatefulTable;
|
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 {
|
fn context_clue_to_keybinding_item(key: &KeyBinding, desc: &&str) -> KeybindingItem {
|
||||||
let (key, alt_key) = if key.alt.is_some() {
|
let (key, alt_key) = if key.alt.is_some() {
|
||||||
(key.key.to_string(), key.alt.as_ref().unwrap().to_string())
|
(key.key.to_string(), key.alt.as_ref().unwrap().to_string())
|
||||||
|
|||||||
+7
-2
@@ -2,11 +2,11 @@ use lidarr_handlers::LidarrHandler;
|
|||||||
use radarr_handlers::RadarrHandler;
|
use radarr_handlers::RadarrHandler;
|
||||||
use sonarr_handlers::SonarrHandler;
|
use sonarr_handlers::SonarrHandler;
|
||||||
|
|
||||||
use crate::app::App;
|
|
||||||
use crate::app::context_clues::{
|
use crate::app::context_clues::{
|
||||||
ContextClueProvider, SERVARR_CONTEXT_CLUES, ServarrContextClueProvider,
|
ContextClueProvider, ServarrContextClueProvider, SERVARR_CONTEXT_CLUES,
|
||||||
};
|
};
|
||||||
use crate::app::key_binding::KeyBinding;
|
use crate::app::key_binding::KeyBinding;
|
||||||
|
use crate::app::App;
|
||||||
use crate::event::Key;
|
use crate::event::Key;
|
||||||
use crate::handlers::keybinding_handler::KeybindingHandler;
|
use crate::handlers::keybinding_handler::KeybindingHandler;
|
||||||
use crate::matches_key;
|
use crate::matches_key;
|
||||||
@@ -116,6 +116,7 @@ pub fn handle_events(key: Key, app: &mut App<'_>) {
|
|||||||
} else {
|
} else {
|
||||||
app.keymapping_table = None;
|
app.keymapping_table = None;
|
||||||
}
|
}
|
||||||
|
} else if matches_key!(esc, key) && handle_clear_notification(app) {
|
||||||
} else {
|
} else {
|
||||||
match app.get_current_route() {
|
match app.get_current_route() {
|
||||||
_ if app.keymapping_table.is_some() => {
|
_ 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) {
|
fn handle_prompt_toggle(app: &mut App<'_>, key: Key) {
|
||||||
match key {
|
match key {
|
||||||
_ if matches_key!(left, key) || matches_key!(right, key) => match app.get_current_route() {
|
_ if matches_key!(left, key) || matches_key!(right, key) => match app.get_current_route() {
|
||||||
|
|||||||
@@ -10,6 +10,23 @@ pub(in crate::models::servarr_data) mod data_test_utils;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod servarr_data_tests;
|
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)]
|
#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
|
||||||
pub enum ActiveKeybindingBlock {
|
pub enum ActiveKeybindingBlock {
|
||||||
#[default]
|
#[default]
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::models::lidarr_models::LidarrReleaseDownloadBody;
|
use crate::models::lidarr_models::LidarrReleaseDownloadBody;
|
||||||
|
use crate::models::servarr_data::Notification;
|
||||||
use crate::network::lidarr_network::LidarrEvent;
|
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;
|
use serde_json::json;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -30,5 +32,51 @@ mod tests {
|
|||||||
|
|
||||||
mock.assert_async().await;
|
mock.assert_async().await;
|
||||||
assert_ok!(result);
|
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,
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::models::lidarr_models::LidarrReleaseDownloadBody;
|
use crate::models::lidarr_models::LidarrReleaseDownloadBody;
|
||||||
|
use crate::models::servarr_data::Notification;
|
||||||
use crate::network::lidarr_network::LidarrEvent;
|
use crate::network::lidarr_network::LidarrEvent;
|
||||||
use crate::network::{Network, RequestMethod};
|
use crate::network::{Network, RequestMethod};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
@@ -31,8 +32,26 @@ impl Network<'_, '_> {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
self
|
let result = self
|
||||||
.handle_request::<LidarrReleaseDownloadBody, Value>(request_props, |_, _| ())
|
.handle_request::<LidarrReleaseDownloadBody, Value>(request_props, |_, mut app| {
|
||||||
.await
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use crate::models::radarr_models::{
|
|||||||
EditMovieParams, Movie, MovieCommandBody, MovieHistoryItem, RadarrRelease,
|
EditMovieParams, Movie, MovieCommandBody, MovieHistoryItem, RadarrRelease,
|
||||||
RadarrReleaseDownloadBody,
|
RadarrReleaseDownloadBody,
|
||||||
};
|
};
|
||||||
|
use crate::models::servarr_data::Notification;
|
||||||
use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
|
use crate::models::servarr_data::radarr::modals::MovieDetailsModal;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||||
use crate::models::stateful_table::StatefulTable;
|
use crate::models::stateful_table::StatefulTable;
|
||||||
@@ -85,9 +86,27 @@ impl Network<'_, '_> {
|
|||||||
.request_props_from(event, RequestMethod::Post, Some(params), None, None)
|
.request_props_from(event, RequestMethod::Post, Some(params), None, None)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
self
|
let result = self
|
||||||
.handle_request::<RadarrReleaseDownloadBody, Value>(request_props, |_, _| ())
|
.handle_request::<RadarrReleaseDownloadBody, Value>(request_props, |_, mut app| {
|
||||||
.await
|
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(
|
pub(in crate::network::radarr_network) async fn edit_movie(
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ mod tests {
|
|||||||
AddMovieBody, AddMovieOptions, Credit, DeleteMovieParams, DownloadRecord, EditMovieParams,
|
AddMovieBody, AddMovieOptions, Credit, DeleteMovieParams, DownloadRecord, EditMovieParams,
|
||||||
MinimumAvailability, Movie, MovieHistoryItem, MovieMonitor, RadarrReleaseDownloadBody,
|
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::modals::MovieDetailsModal;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||||
use crate::models::stateful_table::SortOption;
|
use crate::models::stateful_table::SortOption;
|
||||||
@@ -164,14 +165,58 @@ mod tests {
|
|||||||
.await;
|
.await;
|
||||||
let mut network = test_network(&app);
|
let mut network = test_network(&app);
|
||||||
|
|
||||||
assert!(
|
let result = network
|
||||||
network
|
.handle_radarr_event(RadarrEvent::DownloadRelease(expected_body))
|
||||||
.handle_radarr_event(RadarrEvent::DownloadRelease(expected_body))
|
.await;
|
||||||
.await
|
|
||||||
.is_ok()
|
|
||||||
);
|
|
||||||
|
|
||||||
mock.assert_async().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]
|
#[tokio::test]
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
use crate::models::servarr_data::Notification;
|
||||||
use crate::models::sonarr_models::SonarrReleaseDownloadBody;
|
use crate::models::sonarr_models::SonarrReleaseDownloadBody;
|
||||||
use crate::network::sonarr_network::SonarrEvent;
|
use crate::network::sonarr_network::SonarrEvent;
|
||||||
use crate::network::{Network, RequestMethod};
|
use crate::network::{Network, RequestMethod};
|
||||||
@@ -31,8 +32,26 @@ impl Network<'_, '_> {
|
|||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
self
|
let result = self
|
||||||
.handle_request::<SonarrReleaseDownloadBody, Value>(request_props, |_, _| ())
|
.handle_request::<SonarrReleaseDownloadBody, Value>(request_props, |_, mut app| {
|
||||||
.await
|
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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
use crate::models::servarr_data::Notification;
|
||||||
use crate::models::sonarr_models::SonarrReleaseDownloadBody;
|
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 crate::network::sonarr_network::SonarrEvent;
|
||||||
|
use pretty_assertions::assert_eq;
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -33,5 +35,54 @@ mod tests {
|
|||||||
|
|
||||||
mock.assert_async().await;
|
mock.assert_async().await;
|
||||||
assert_ok!(result);
|
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,
|
||||||
|
)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+23
-1
@@ -14,6 +14,7 @@ use sonarr_ui::SonarrUi;
|
|||||||
use utils::layout_block;
|
use utils::layout_block;
|
||||||
|
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
|
use crate::models::servarr_data::Notification;
|
||||||
use crate::models::servarr_models::KeybindingItem;
|
use crate::models::servarr_models::KeybindingItem;
|
||||||
use crate::models::{HorizontallyScrollableText, Route, TabState};
|
use crate::models::{HorizontallyScrollableText, Route, TabState};
|
||||||
use crate::ui::radarr_ui::RadarrUi;
|
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::input_box::InputBox;
|
||||||
use crate::ui::widgets::managarr_table::ManagarrTable;
|
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 builtin_themes;
|
||||||
mod lidarr_ui;
|
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() {
|
if app.keymapping_table.is_some() {
|
||||||
draw_help_popup(f, app);
|
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);
|
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 {
|
fn draw_tabs(f: &mut Frame<'_>, area: Rect, title: &str, tab_state: &TabState) -> Rect {
|
||||||
if title.is_empty() {
|
if title.is_empty() {
|
||||||
f.render_widget(layout_block().default_color(), area);
|
f.render_widget(layout_block().default_color(), area);
|
||||||
|
|||||||
+54
@@ -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 │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ╰───────────────────────────────────────╯ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
+54
@@ -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 │ │
|
||||||
|
│ ╰───────────────────────────────────────╯ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
+54
@@ -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 │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ╰───────────────────────────────────────╯ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
+54
@@ -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 │ │
|
||||||
|
│ │ │ │
|
||||||
|
│ ╰───────────────────────────────────────╯ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
│ │
|
||||||
|
╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
mod snapshot_tests {
|
mod snapshot_tests {
|
||||||
use crate::app::App;
|
use crate::app::App;
|
||||||
use crate::handlers::populate_keymapping_table;
|
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::lidarr::lidarr_data::ActiveLidarrBlock;
|
||||||
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
|
||||||
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
use crate::models::servarr_data::sonarr::sonarr_data::ActiveSonarrBlock;
|
||||||
@@ -46,6 +47,40 @@ mod snapshot_tests {
|
|||||||
insta::assert_snapshot!(output);
|
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]
|
#[test]
|
||||||
fn test_sonarr_ui_renders_library_tab() {
|
fn test_sonarr_ui_renders_library_tab() {
|
||||||
let mut app = App::test_default_fully_populated();
|
let mut app = App::test_default_fully_populated();
|
||||||
@@ -84,6 +119,23 @@ mod snapshot_tests {
|
|||||||
insta::assert_snapshot!(output);
|
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]
|
#[test]
|
||||||
fn test_lidarr_ui_renders_library_tab() {
|
fn test_lidarr_ui_renders_library_tab() {
|
||||||
let mut app = App::test_default_fully_populated();
|
let mut app = App::test_default_fully_populated();
|
||||||
@@ -109,6 +161,23 @@ mod snapshot_tests {
|
|||||||
insta::assert_snapshot!(output);
|
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]
|
#[test]
|
||||||
fn test_lidarr_ui_renders_library_tab_error_popup() {
|
fn test_lidarr_ui_renders_library_tab_error_popup() {
|
||||||
let mut app = App::test_default_fully_populated();
|
let mut app = App::test_default_fully_populated();
|
||||||
|
|||||||
Reference in New Issue
Block a user