feat: naive lidarr root folder tab implementation. Needs improved add logic
This commit is contained in:
@@ -5,6 +5,7 @@ use clap::{ArgAction, Subcommand, arg};
|
||||
use tokio::sync::Mutex;
|
||||
|
||||
use super::LidarrCommand;
|
||||
use crate::models::servarr_models::AddRootFolderBody;
|
||||
use crate::{
|
||||
app::App,
|
||||
cli::{CliCommandHandler, Command},
|
||||
@@ -75,6 +76,11 @@ pub enum LidarrAddCommand {
|
||||
)]
|
||||
no_search_for_missing_albums: bool,
|
||||
},
|
||||
#[command(about = "Add a new root folder")]
|
||||
RootFolder {
|
||||
#[arg(long, help = "The path of the new root folder", required = true)]
|
||||
root_folder_path: String,
|
||||
},
|
||||
#[command(about = "Add new tag")]
|
||||
Tag {
|
||||
#[arg(long, help = "The name of the tag to be added", required = true)]
|
||||
@@ -142,6 +148,16 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, LidarrAddCommand> for LidarrAddCommandHan
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrAddCommand::RootFolder { root_folder_path } => {
|
||||
let add_root_folder_body = AddRootFolderBody {
|
||||
path: root_folder_path,
|
||||
};
|
||||
let resp = self
|
||||
.network
|
||||
.handle_network_event(LidarrEvent::AddRootFolder(add_root_folder_body).into())
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrAddCommand::Tag { name } => {
|
||||
let resp = self
|
||||
.network
|
||||
|
||||
@@ -27,6 +27,41 @@ mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn test_add_root_folder_requires_arguments() {
|
||||
let result =
|
||||
Cli::command().try_get_matches_from(["managarr", "lidarr", "add", "root-folder"]);
|
||||
|
||||
assert_err!(&result);
|
||||
assert_eq!(
|
||||
result.unwrap_err().kind(),
|
||||
ErrorKind::MissingRequiredArgument
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_root_folder_success() {
|
||||
let expected_args = LidarrAddCommand::RootFolder {
|
||||
root_folder_path: "/nfs/test".to_owned(),
|
||||
};
|
||||
|
||||
let result = Cli::try_parse_from([
|
||||
"managarr",
|
||||
"lidarr",
|
||||
"add",
|
||||
"root-folder",
|
||||
"--root-folder-path",
|
||||
"/nfs/test",
|
||||
]);
|
||||
|
||||
assert_ok!(&result);
|
||||
|
||||
let Some(Command::Lidarr(LidarrCommand::Add(add_command))) = result.unwrap().command else {
|
||||
panic!("Unexpected command type");
|
||||
};
|
||||
assert_eq!(add_command, expected_args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_add_tag_requires_arguments() {
|
||||
let result = Cli::command().try_get_matches_from(["managarr", "lidarr", "add", "tag"]);
|
||||
@@ -383,12 +418,44 @@ mod tests {
|
||||
use crate::models::lidarr_models::{
|
||||
AddArtistBody, AddArtistOptions, LidarrSerdeable, MonitorType, NewItemMonitorType,
|
||||
};
|
||||
use crate::models::servarr_models::AddRootFolderBody;
|
||||
use crate::network::lidarr_network::LidarrEvent;
|
||||
use crate::{
|
||||
app::App,
|
||||
network::{MockNetworkTrait, NetworkEvent},
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_add_root_folder_command() {
|
||||
let expected_root_folder_path = "/nfs/test".to_owned();
|
||||
let expected_add_root_folder_body = AddRootFolderBody {
|
||||
path: expected_root_folder_path.clone(),
|
||||
};
|
||||
let mut mock_network = MockNetworkTrait::new();
|
||||
mock_network
|
||||
.expect_handle_network_event()
|
||||
.with(eq::<NetworkEvent>(
|
||||
LidarrEvent::AddRootFolder(expected_add_root_folder_body.clone()).into(),
|
||||
))
|
||||
.times(1)
|
||||
.returning(|_| {
|
||||
Ok(Serdeable::Lidarr(LidarrSerdeable::Value(
|
||||
json!({"testResponse": "response"}),
|
||||
)))
|
||||
});
|
||||
let app_arc = Arc::new(Mutex::new(App::test_default()));
|
||||
let add_root_folder_command = LidarrAddCommand::RootFolder {
|
||||
root_folder_path: expected_root_folder_path,
|
||||
};
|
||||
|
||||
let result =
|
||||
LidarrAddCommandHandler::with(&app_arc, add_root_folder_command, &mut mock_network)
|
||||
.handle()
|
||||
.await;
|
||||
|
||||
assert_ok!(&result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_add_tag_command() {
|
||||
let expected_tag_name = "test".to_owned();
|
||||
|
||||
@@ -42,6 +42,11 @@ pub enum LidarrDeleteCommand {
|
||||
#[arg(long, help = "The ID of the download to delete", required = true)]
|
||||
download_id: i64,
|
||||
},
|
||||
#[command(about = "Delete the root folder with the given ID")]
|
||||
RootFolder {
|
||||
#[arg(long, help = "The ID of the root folder to delete", required = true)]
|
||||
root_folder_id: i64,
|
||||
},
|
||||
#[command(about = "Delete the tag with the specified ID")]
|
||||
Tag {
|
||||
#[arg(long, help = "The ID of the tag to delete", required = true)]
|
||||
@@ -115,6 +120,13 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, LidarrDeleteCommand> for LidarrDeleteComm
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrDeleteCommand::RootFolder { root_folder_id } => {
|
||||
let resp = self
|
||||
.network
|
||||
.handle_network_event(LidarrEvent::DeleteRootFolder(root_folder_id).into())
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrDeleteCommand::Tag { tag_id } => {
|
||||
let resp = self
|
||||
.network
|
||||
|
||||
@@ -179,6 +179,40 @@ mod tests {
|
||||
assert_eq!(delete_command, expected_args);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_root_folder_requires_arguments() {
|
||||
let result =
|
||||
Cli::command().try_get_matches_from(["managarr", "lidarr", "delete", "root-folder"]);
|
||||
|
||||
assert_err!(&result);
|
||||
assert_eq!(
|
||||
result.unwrap_err().kind(),
|
||||
ErrorKind::MissingRequiredArgument
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_delete_root_folder_success() {
|
||||
let expected_args = LidarrDeleteCommand::RootFolder { root_folder_id: 1 };
|
||||
|
||||
let result = Cli::try_parse_from([
|
||||
"managarr",
|
||||
"lidarr",
|
||||
"delete",
|
||||
"root-folder",
|
||||
"--root-folder-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"]);
|
||||
@@ -320,6 +354,32 @@ mod tests {
|
||||
assert_ok!(&result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_delete_root_folder_command() {
|
||||
let expected_root_folder_id = 1;
|
||||
let mut mock_network = MockNetworkTrait::new();
|
||||
mock_network
|
||||
.expect_handle_network_event()
|
||||
.with(eq::<NetworkEvent>(
|
||||
LidarrEvent::DeleteRootFolder(expected_root_folder_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_root_folder_command = LidarrDeleteCommand::RootFolder { root_folder_id: 1 };
|
||||
|
||||
let result =
|
||||
LidarrDeleteCommandHandler::with(&app_arc, delete_root_folder_command, &mut mock_network)
|
||||
.handle()
|
||||
.await;
|
||||
|
||||
assert_ok!(&result);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handle_delete_tag_command() {
|
||||
let expected_tag_id = 1;
|
||||
|
||||
@@ -43,6 +43,8 @@ pub enum LidarrListCommand {
|
||||
MetadataProfiles,
|
||||
#[command(about = "List all Lidarr quality profiles")]
|
||||
QualityProfiles,
|
||||
#[command(about = "List all root folders in Lidarr")]
|
||||
RootFolders,
|
||||
#[command(about = "List all Lidarr tags")]
|
||||
Tags,
|
||||
}
|
||||
@@ -116,6 +118,13 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, LidarrListCommand> for LidarrListCommandH
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrListCommand::RootFolders => {
|
||||
let resp = self
|
||||
.network
|
||||
.handle_network_event(LidarrEvent::GetRootFolders.into())
|
||||
.await?;
|
||||
serde_json::to_string_pretty(&resp)?
|
||||
}
|
||||
LidarrListCommand::Tags => {
|
||||
let resp = self
|
||||
.network
|
||||
|
||||
@@ -25,7 +25,14 @@ mod tests {
|
||||
|
||||
#[rstest]
|
||||
fn test_list_commands_have_no_arg_requirements(
|
||||
#[values("artists", "metadata-profiles", "quality-profiles", "tags")] subcommand: &str,
|
||||
#[values(
|
||||
"artists",
|
||||
"metadata-profiles",
|
||||
"quality-profiles",
|
||||
"tags",
|
||||
"root-folders"
|
||||
)]
|
||||
subcommand: &str,
|
||||
) {
|
||||
let result = Cli::command().try_get_matches_from(["managarr", "lidarr", "list", subcommand]);
|
||||
|
||||
@@ -127,6 +134,7 @@ mod tests {
|
||||
#[case(LidarrListCommand::Artists, LidarrEvent::ListArtists)]
|
||||
#[case(LidarrListCommand::MetadataProfiles, LidarrEvent::GetMetadataProfiles)]
|
||||
#[case(LidarrListCommand::QualityProfiles, LidarrEvent::GetQualityProfiles)]
|
||||
#[case(LidarrListCommand::RootFolders, LidarrEvent::GetRootFolders)]
|
||||
#[case(LidarrListCommand::Tags, LidarrEvent::GetTags)]
|
||||
#[tokio::test]
|
||||
async fn test_handle_list_command(
|
||||
|
||||
Reference in New Issue
Block a user