From 1b5979c36cbb6db286f8b352e98a153e37daa792 Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Fri, 22 Nov 2024 20:04:57 -0700 Subject: [PATCH] feat(cli): Support for downloading an episode release in Sonarr --- src/cli/sonarr/download_command_handler.rs | 34 ++++++ .../sonarr/download_command_handler_tests.rs | 113 ++++++++++++++++++ 2 files changed, 147 insertions(+) diff --git a/src/cli/sonarr/download_command_handler.rs b/src/cli/sonarr/download_command_handler.rs index 4338ee3..88055b8 100644 --- a/src/cli/sonarr/download_command_handler.rs +++ b/src/cli/sonarr/download_command_handler.rs @@ -60,6 +60,23 @@ pub enum SonarrDownloadCommand { )] season_number: i64, }, + #[command(about = "Manually download the given episode release for the specified episode ID")] + Episode { + #[arg(long, help = "The GUID of the release to download", required = true)] + guid: String, + #[arg( + long, + help = "The indexer ID to download the release from", + required = true + )] + indexer_id: i64, + #[arg( + long, + help = "The episode ID that the release is associated with", + required = true + )] + episode_id: i64, + }, } impl From for Command { @@ -127,6 +144,23 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrDownloadCommand> .await?; serde_json::to_string_pretty(&resp)? } + SonarrDownloadCommand::Episode { + guid, + indexer_id, + episode_id, + } => { + let params = SonarrReleaseDownloadBody { + guid, + indexer_id, + episode_id: Some(episode_id), + ..SonarrReleaseDownloadBody::default() + }; + let resp = self + .network + .handle_network_event(SonarrEvent::DownloadRelease(params).into()) + .await?; + serde_json::to_string_pretty(&resp)? + } }; Ok(result) diff --git a/src/cli/sonarr/download_command_handler_tests.rs b/src/cli/sonarr/download_command_handler_tests.rs index ae7a661..c1a617b 100644 --- a/src/cli/sonarr/download_command_handler_tests.rs +++ b/src/cli/sonarr/download_command_handler_tests.rs @@ -213,6 +213,84 @@ mod tests { assert!(result.is_ok()); } + + #[test] + fn test_download_episode_requires_episode_id() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "episode", + "--indexer-id", + "1", + "--guid", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_download_episode_requires_guid() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "episode", + "--indexer-id", + "1", + "--episode-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_download_episode_requires_indexer_id() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "episode", + "--guid", + "1", + "--episode-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_download_episode_requirements_satisfied() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "episode", + "--guid", + "1", + "--episode-id", + "1", + "--indexer-id", + "1", + ]); + + assert!(result.is_ok()); + } } mod handler { @@ -306,5 +384,40 @@ mod tests { assert!(result.is_ok()); } + + #[tokio::test] + async fn test_download_episode_release_command() { + let expected_release_download_body = SonarrReleaseDownloadBody { + guid: "guid".to_owned(), + indexer_id: 1, + episode_id: Some(1), + ..SonarrReleaseDownloadBody::default() + }; + let mut mock_network = MockNetworkTrait::new(); + mock_network + .expect_handle_network_event() + .with(eq::( + SonarrEvent::DownloadRelease(expected_release_download_body).into(), + )) + .times(1) + .returning(|_| { + Ok(Serdeable::Sonarr(SonarrSerdeable::Value( + json!({"testResponse": "response"}), + ))) + }); + let app_arc = Arc::new(Mutex::new(App::default())); + let download_release_command = SonarrDownloadCommand::Episode { + guid: "guid".to_owned(), + indexer_id: 1, + episode_id: 1, + }; + + let result = + SonarrDownloadCommandHandler::with(&app_arc, download_release_command, &mut mock_network) + .handle() + .await; + + assert!(result.is_ok()); + } } }