From 5ed3372ae2bcfc037eefb95355ccc36bf66f474f Mon Sep 17 00:00:00 2001 From: Alex Clarke Date: Fri, 22 Nov 2024 20:00:41 -0700 Subject: [PATCH] feat(cli): Support for downloading a season release in Sonarr --- src/cli/sonarr/download_command_handler.rs | 44 +++++ .../sonarr/download_command_handler_tests.rs | 154 +++++++++++++++++- 2 files changed, 193 insertions(+), 5 deletions(-) diff --git a/src/cli/sonarr/download_command_handler.rs b/src/cli/sonarr/download_command_handler.rs index 3fa624f..4338ee3 100644 --- a/src/cli/sonarr/download_command_handler.rs +++ b/src/cli/sonarr/download_command_handler.rs @@ -35,6 +35,31 @@ pub enum SonarrDownloadCommand { )] series_id: i64, }, + #[command( + about = "Manually download the given season release corresponding to the series specified with the series ID" + )] + Season { + #[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 series ID that the release is associated with", + required = true + )] + series_id: i64, + #[arg( + long, + help = "The season number that the release corresponds to", + required = true + )] + season_number: i64, + }, } impl From for Command { @@ -83,6 +108,25 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrDownloadCommand> .await?; serde_json::to_string_pretty(&resp)? } + SonarrDownloadCommand::Season { + guid, + indexer_id, + series_id, + season_number, + } => { + let params = SonarrReleaseDownloadBody { + guid, + indexer_id, + series_id: Some(series_id), + season_number: Some(season_number), + ..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 870b109..ae7a661 100644 --- a/src/cli/sonarr/download_command_handler_tests.rs +++ b/src/cli/sonarr/download_command_handler_tests.rs @@ -27,9 +27,8 @@ mod tests { use super::*; use clap::error::ErrorKind; use pretty_assertions::assert_eq; - use rstest::rstest; - #[rstest] + #[test] fn test_download_series_requires_series_id() { let result = Cli::command().try_get_matches_from([ "managarr", @@ -49,7 +48,7 @@ mod tests { ); } - #[rstest] + #[test] fn test_download_series_requires_guid() { let result = Cli::command().try_get_matches_from([ "managarr", @@ -69,7 +68,7 @@ mod tests { ); } - #[rstest] + #[test] fn test_download_series_requires_indexer_id() { let result = Cli::command().try_get_matches_from([ "managarr", @@ -106,6 +105,114 @@ mod tests { assert!(result.is_ok()); } + + #[test] + fn test_download_season_requires_series_id() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "season", + "--indexer-id", + "1", + "--season-number", + "1", + "--guid", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_download_season_requires_season_number() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "season", + "--indexer-id", + "1", + "--series-id", + "1", + "--guid", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_download_season_requires_guid() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "season", + "--indexer-id", + "1", + "--season-number", + "1", + "--series-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_download_season_requires_indexer_id() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "season", + "--guid", + "1", + "--season-number", + "1", + "--series-id", + "1", + ]); + + assert!(result.is_err()); + assert_eq!( + result.unwrap_err().kind(), + ErrorKind::MissingRequiredArgument + ); + } + + #[test] + fn test_download_season_requirements_satisfied() { + let result = Cli::command().try_get_matches_from([ + "managarr", + "sonarr", + "download", + "season", + "--guid", + "1", + "--series-id", + "1", + "--season-number", + "1", + "--indexer-id", + "1", + ]); + + assert!(result.is_ok()); + } } mod handler { @@ -129,7 +236,7 @@ mod tests { }; #[tokio::test] - async fn test_download_release_command() { + async fn test_download_series_release_command() { let expected_release_download_body = SonarrReleaseDownloadBody { guid: "guid".to_owned(), indexer_id: 1, @@ -162,5 +269,42 @@ mod tests { assert!(result.is_ok()); } + + #[tokio::test] + async fn test_download_season_release_command() { + let expected_release_download_body = SonarrReleaseDownloadBody { + guid: "guid".to_owned(), + indexer_id: 1, + series_id: Some(1), + season_number: 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::Season { + guid: "guid".to_owned(), + indexer_id: 1, + series_id: 1, + season_number: 1, + }; + + let result = + SonarrDownloadCommandHandler::with(&app_arc, download_release_command, &mut mock_network) + .handle() + .await; + + assert!(result.is_ok()); + } } }