feat: Downloads tab support in Lidarr
This commit is contained in:
@@ -37,6 +37,11 @@ pub enum LidarrDeleteCommand {
|
||||
#[arg(long, help = "Add a list exclusion for this artist")]
|
||||
add_list_exclusion: bool,
|
||||
},
|
||||
#[command(about = "Delete the specified download")]
|
||||
Download {
|
||||
#[arg(long, help = "The ID of the download to delete", required = true)]
|
||||
download_id: i64,
|
||||
},
|
||||
#[command(about = "Delete the tag with the specified ID")]
|
||||
Tag {
|
||||
#[arg(long, help = "The ID of the tag to delete", required = true)]
|
||||
@@ -103,6 +108,13 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, LidarrDeleteCommand> for LidarrDeleteComm
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrDeleteCommand::Download { download_id } => {
|
||||
let resp = self
|
||||
.network
|
||||
.handle_network_event(LidarrEvent::DeleteDownload(download_id).into())
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrDeleteCommand::Tag { tag_id } => {
|
||||
let resp = self
|
||||
.network
|
||||
|
||||
@@ -145,6 +145,40 @@ mod tests {
|
||||
assert_eq!(delete_command, expected_args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_download_requires_arguments() {
|
||||
let result =
|
||||
Cli::command().try_get_matches_from(["managarr", "lidarr", "delete", "download"]);
|
||||
|
||||
assert_err!(&result);
|
||||
assert_eq!(
|
||||
result.unwrap_err().kind(),
|
||||
ErrorKind::MissingRequiredArgument
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_download_success() {
|
||||
let expected_args = LidarrDeleteCommand::Download { download_id: 1 };
|
||||
|
||||
let result = Cli::try_parse_from([
|
||||
"managarr",
|
||||
"lidarr",
|
||||
"delete",
|
||||
"download",
|
||||
"--download-id",
|
||||
"1",
|
||||
]);
|
||||
|
||||
assert_ok!(&result);
|
||||
|
||||
let Some(Command::Lidarr(LidarrCommand::Delete(delete_command))) = result.unwrap().command
|
||||
else {
|
||||
panic!("Unexpected command type");
|
||||
};
|
||||
assert_eq!(delete_command, expected_args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_tag_requires_arguments() {
|
||||
let result = Cli::command().try_get_matches_from(["managarr", "lidarr", "delete", "tag"]);
|
||||
@@ -260,6 +294,32 @@ mod tests {
|
||||
assert_ok!(&result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_delete_download_command() {
|
||||
let expected_download_id = 1;
|
||||
let mut mock_network = MockNetworkTrait::new();
|
||||
mock_network
|
||||
.expect_handle_network_event()
|
||||
.with(eq::<NetworkEvent>(
|
||||
LidarrEvent::DeleteDownload(expected_download_id).into(),
|
||||
))
|
||||
.times(1)
|
||||
.returning(|_| {
|
||||
Ok(Serdeable::Lidarr(LidarrSerdeable::Value(
|
||||
json!({"testResponse": "response"}),
|
||||
)))
|
||||
});
|
||||
let app_arc = Arc::new(Mutex::new(App::test_default()));
|
||||
let delete_download_command = LidarrDeleteCommand::Download { download_id: 1 };
|
||||
|
||||
let result =
|
||||
LidarrDeleteCommandHandler::with(&app_arc, delete_download_command, &mut mock_network)
|
||||
.handle()
|
||||
.await;
|
||||
|
||||
assert_ok!(&result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_delete_tag_command() {
|
||||
let expected_tag_id = 1;
|
||||
|
||||
@@ -29,6 +29,11 @@ pub enum LidarrListCommand {
|
||||
},
|
||||
#[command(about = "List all artists in your Lidarr library")]
|
||||
Artists,
|
||||
#[command(about = "List all active downloads in Lidarr")]
|
||||
Downloads {
|
||||
#[arg(long, help = "How many downloads to fetch", default_value_t = 500)]
|
||||
count: u64,
|
||||
},
|
||||
#[command(about = "Fetch all Lidarr history events")]
|
||||
History {
|
||||
#[arg(long, help = "How many history events to fetch", default_value_t = 500)]
|
||||
@@ -83,6 +88,13 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, LidarrListCommand> for LidarrListCommandH
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrListCommand::Downloads { count } => {
|
||||
let resp = self
|
||||
.network
|
||||
.handle_network_event(LidarrEvent::GetDownloads(count).into())
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrListCommand::History { events: items } => {
|
||||
let resp = self
|
||||
.network
|
||||
|
||||
@@ -58,6 +58,29 @@ mod tests {
|
||||
assert_eq!(album_command, expected_args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_downloads_count_flag_requires_arguments() {
|
||||
let result =
|
||||
Cli::command().try_get_matches_from(["managarr", "lidarr", "list", "downloads", "--count"]);
|
||||
|
||||
assert_err!(&result);
|
||||
assert_eq!(result.unwrap_err().kind(), ErrorKind::InvalidValue);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_downloads_default_values() {
|
||||
let expected_args = LidarrListCommand::Downloads { count: 500 };
|
||||
let result = Cli::try_parse_from(["managarr", "lidarr", "list", "downloads"]);
|
||||
|
||||
assert_ok!(&result);
|
||||
|
||||
let Some(Command::Lidarr(LidarrCommand::List(downloads_command))) = result.unwrap().command
|
||||
else {
|
||||
panic!("Unexpected command type");
|
||||
};
|
||||
assert_eq!(downloads_command, expected_args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_list_history_events_flag_requires_arguments() {
|
||||
let result =
|
||||
@@ -151,6 +174,32 @@ mod tests {
|
||||
assert_ok!(&result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_list_downloads_command() {
|
||||
let expected_count = 1000;
|
||||
let mut mock_network = MockNetworkTrait::new();
|
||||
mock_network
|
||||
.expect_handle_network_event()
|
||||
.with(eq::<NetworkEvent>(
|
||||
LidarrEvent::GetDownloads(expected_count).into(),
|
||||
))
|
||||
.times(1)
|
||||
.returning(|_| {
|
||||
Ok(Serdeable::Lidarr(LidarrSerdeable::Value(
|
||||
json!({"testResponse": "response"}),
|
||||
)))
|
||||
});
|
||||
let app_arc = Arc::new(Mutex::new(App::test_default()));
|
||||
let list_downloads_command = LidarrListCommand::Downloads { count: 1000 };
|
||||
|
||||
let result =
|
||||
LidarrListCommandHandler::with(&app_arc, list_downloads_command, &mut mock_network)
|
||||
.handle()
|
||||
.await;
|
||||
|
||||
assert_ok!(&result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_list_history_command() {
|
||||
let expected_events = 1000;
|
||||
|
||||
@@ -28,6 +28,8 @@ pub enum LidarrRefreshCommand {
|
||||
)]
|
||||
artist_id: i64,
|
||||
},
|
||||
#[command(about = "Refresh all downloads in Lidarr")]
|
||||
Downloads,
|
||||
}
|
||||
|
||||
impl From<LidarrRefreshCommand> for Command {
|
||||
@@ -73,6 +75,13 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, LidarrRefreshCommand>
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrRefreshCommand::Downloads => {
|
||||
let resp = self
|
||||
.network
|
||||
.handle_network_event(LidarrEvent::UpdateDownloads.into())
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
|
||||
@@ -22,11 +22,14 @@ mod tests {
|
||||
use super::*;
|
||||
use clap::{Parser, error::ErrorKind};
|
||||
use pretty_assertions::assert_eq;
|
||||
use rstest::rstest;
|
||||
|
||||
#[test]
|
||||
fn test_refresh_all_artists_has_no_arg_requirements() {
|
||||
#[rstest]
|
||||
fn test_refresh_commands_have_no_arg_requirements(
|
||||
#[values("all-artists", "downloads")] subcommand: &str,
|
||||
) {
|
||||
let result =
|
||||
Cli::command().try_get_matches_from(["managarr", "lidarr", "refresh", "all-artists"]);
|
||||
Cli::command().try_get_matches_from(["managarr", "lidarr", "refresh", subcommand]);
|
||||
|
||||
assert_ok!(&result);
|
||||
}
|
||||
@@ -67,6 +70,7 @@ mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use mockall::predicate::eq;
|
||||
use rstest::rstest;
|
||||
use serde_json::json;
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
@@ -80,12 +84,18 @@ mod tests {
|
||||
network::{MockNetworkTrait, NetworkEvent},
|
||||
};
|
||||
|
||||
#[rstest]
|
||||
#[case(LidarrRefreshCommand::AllArtists, LidarrEvent::UpdateAllArtists)]
|
||||
#[case(LidarrRefreshCommand::Downloads, LidarrEvent::UpdateDownloads)]
|
||||
#[tokio::test]
|
||||
async fn test_handle_refresh_all_artists_command() {
|
||||
async fn test_handle_refresh_command(
|
||||
#[case] refresh_command: LidarrRefreshCommand,
|
||||
#[case] expected_sonarr_event: LidarrEvent,
|
||||
) {
|
||||
let mut mock_network = MockNetworkTrait::new();
|
||||
mock_network
|
||||
.expect_handle_network_event()
|
||||
.with(eq::<NetworkEvent>(LidarrEvent::UpdateAllArtists.into()))
|
||||
.with(eq::<NetworkEvent>(expected_sonarr_event.into()))
|
||||
.times(1)
|
||||
.returning(|_| {
|
||||
Ok(Serdeable::Lidarr(LidarrSerdeable::Value(
|
||||
@@ -93,7 +103,6 @@ mod tests {
|
||||
)))
|
||||
});
|
||||
let app_arc = Arc::new(Mutex::new(App::test_default()));
|
||||
let refresh_command = LidarrRefreshCommand::AllArtists;
|
||||
|
||||
let result = LidarrRefreshCommandHandler::with(&app_arc, refresh_command, &mut mock_network)
|
||||
.handle()
|
||||
|
||||
Reference in New Issue
Block a user