Compare commits

..

13 Commits

Author SHA1 Message Date
github-actions[bot]
aa43219c29 chore: release v0.1.5 2024-11-03 00:33:11 +00:00
f6f477b124 Added HTTPS support for all Servarrs 2024-11-02 18:32:44 -06:00
Alex Clarke
76f22e7434 Merge pull request #5 from Dark-Alex-17/release-plz-2024-11-01T19-06-52Z
chore: release v0.1.4
2024-11-01 13:13:03 -06:00
github-actions[bot]
28aad8cd14 chore: release v0.1.4 2024-11-01 19:06:53 +00:00
97c8f8fc49 Added the ability to fetch host configs and security configs to the CLI 2024-11-01 13:02:39 -06:00
9da4ebfe11 Updated README to be more clear about what features are supported [skip ci] 2024-10-31 15:53:08 -06:00
9961fe2f82 Hotfix for demo; added the --config flag to specify different config files, and added --disable-terminal-size-checks for running the demo and for users who really know what they're doing 2024-10-31 15:04:36 -06:00
61ce0468c6 Added --config and --disable-terminal-size-checks flags to make the demo work properly [skip ci] 2024-10-31 14:53:49 -06:00
Alex Clarke
29071b11da Create FUNDING.yml
[skip ci] Added funding information to the repo
2024-10-30 17:05:25 -06:00
Alex Clarke
f2129ba321 Merge pull request #4 from Dark-Alex-17/release-plz-2024-10-30T22-44-04Z
chore: release v0.1.2
2024-10-30 16:51:51 -06:00
github-actions[bot]
945dc744bc chore: release v0.1.2 2024-10-30 22:44:04 +00:00
9ee41b7af5 Updated README to a more polished format for the alpha release 2024-10-30 16:43:38 -06:00
Alex Clarke
a1d6df6b85 Merge pull request #3 from Dark-Alex-17/release-plz-2024-10-30T21-26-49Z
chore: release v0.1.1
2024-10-30 16:11:30 -06:00
18 changed files with 609 additions and 163 deletions
+1
View File
@@ -0,0 +1 @@
github: Dark-Alex-17
+1 -1
View File
@@ -1,7 +1,7 @@
# Adapted from https://github.com/joshka/github-workflows/blob/main/.github/workflows/rust-release-plz.yml # Adapted from https://github.com/joshka/github-workflows/blob/main/.github/workflows/rust-release-plz.yml
# Thanks to joshka for permission to use this template! # Thanks to joshka for permission to use this template!
name: Create Release PR and publish to crates.io name: Create Release PR and Publish Release
permissions: permissions:
pull-requests: write pull-requests: write
+19
View File
@@ -7,6 +7,25 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
## [0.1.5](https://github.com/Dark-Alex-17/managarr/compare/v0.1.4...v0.1.5) - 2024-11-03
### Other
- Added HTTPS support for all Servarrs
## [0.1.4](https://github.com/Dark-Alex-17/managarr/compare/v0.1.3...v0.1.4) - 2024-11-01
### Other
- Added the ability to fetch host configs and security configs to the CLI
- Updated README to be more clear about what features are supported [skip ci]
## [0.1.2](https://github.com/Dark-Alex-17/managarr/compare/v0.1.1...v0.1.2) - 2024-10-30
### Other
- Updated README to a more polished format for the alpha release
## [0.1.1](https://github.com/Dark-Alex-17/managarr/compare/v0.1.0...v0.1.1) - 2024-10-30 ## [0.1.1](https://github.com/Dark-Alex-17/managarr/compare/v0.1.0...v0.1.1) - 2024-10-30
### Other ### Other
Generated
+1 -1
View File
@@ -1148,7 +1148,7 @@ dependencies = [
[[package]] [[package]]
name = "managarr" name = "managarr"
version = "0.1.1" version = "0.1.5"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"assert_cmd", "assert_cmd",
+1 -1
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "managarr" name = "managarr"
version = "0.1.1" version = "0.1.5"
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"] authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
description = "A TUI and CLI to manage your Servarrs" description = "A TUI and CLI to manage your Servarrs"
keywords = ["managarr", "tui-rs", "dashboard", "servarr", "tui"] keywords = ["managarr", "tui-rs", "dashboard", "servarr", "tui"]
+1 -1
View File
@@ -23,4 +23,4 @@ FROM debian:stable-slim
# Copy the compiled binary from the builder container # Copy the compiled binary from the builder container
COPY --from=builder --chown=nonroot:nonroot /usr/src/managarr-temp/managarr /usr/local/bin COPY --from=builder --chown=nonroot:nonroot /usr/src/managarr-temp/managarr /usr/local/bin
ENTRYPOINT [ "/usr/local/bin/managarr" ] ENTRYPOINT [ "/usr/local/bin/managarr", "--disable-terminal-size-checks" ]
+46 -25
View File
@@ -17,14 +17,14 @@ Managarr is a TUI and CLI to help you manage your HTPC (Home Theater PC). Built
## What Servarrs are supported? ## What Servarrs are supported?
- ![radarr_logo](logos/radarr.png) [Radarr](https://wiki.servarr.com/radarr) - [x] ![radarr_logo](logos/radarr.png) [Radarr](https://wiki.servarr.com/radarr)
- ![sonarr_logo](logos/sonarr.png) [Sonarr](https://wiki.servarr.com/en/sonarr) - [ ] ![sonarr_logo](logos/sonarr.png) [Sonarr](https://wiki.servarr.com/en/sonarr)
- ![readarr_logo](logos/readarr.png) [Readarr](https://wiki.servarr.com/en/readarr) - [ ] ![readarr_logo](logos/readarr.png) [Readarr](https://wiki.servarr.com/en/readarr)
- ![lidarr_logo](logos/lidarr.png) [Lidarr](https://wiki.servarr.com/en/lidarr) - [ ] ![lidarr_logo](logos/lidarr.png) [Lidarr](https://wiki.servarr.com/en/lidarr)
- ![prowlarr_logo](logos/prowlarr.png) [Prowlarr](https://wiki.servarr.com/en/prowlarr) - [ ] ![prowlarr_logo](logos/prowlarr.png) [Prowlarr](https://wiki.servarr.com/en/prowlarr)
- ![whisparr_logo](logos/whisparr.png) [Whisparr](https://wiki.servarr.com/whisparr) - [ ] ![whisparr_logo](logos/whisparr.png) [Whisparr](https://wiki.servarr.com/whisparr)
- ![bazarr_logo](logos/bazarr.png) [Bazarr](https://www.bazarr.media/) - [ ] ![bazarr_logo](logos/bazarr.png) [Bazarr](https://www.bazarr.media/)
- ![tautulli_logo](logos/tautulli.png) [Tautulli](https://tautulli.com/) - [ ] ![tautulli_logo](logos/tautulli.png) [Tautulli](https://tautulli.com/)
## Try Before You Buy ## Try Before You Buy
To try out Managarr before linking it to your HTPC, you can use the purpose built [managarr-demo](https://github.com/Dark-Alex-17/managarr-demo) repository. To try out Managarr before linking it to your HTPC, you can use the purpose built [managarr-demo](https://github.com/Dark-Alex-17/managarr-demo) repository.
@@ -45,6 +45,14 @@ cargo install managarr
cargo install --locked managarr cargo install --locked managarr
``` ```
### Docker
Run Managarr as a docker container by mounting your `config.yml` file to `/root/.config/managarr/config.yml`. For example:
```shell
docker run --rm -it -v ~/.config/managarr:/root/.config/managarr darkalex17/managarr
```
You can also clone this repo and run `make docker` to build a docker image locally and run it using the above command.
## Features ## Features
### Radarr ### Radarr
@@ -52,6 +60,7 @@ cargo install --locked managarr
- [x] View your library, downloads, collections, and blocklist - [x] View your library, downloads, collections, and blocklist
- [x] View details of a specific movie including description, history, downloaded file info, or the credits - [x] View details of a specific movie including description, history, downloaded file info, or the credits
- [x] View details of any collection and the movies in them - [x] View details of any collection and the movies in them
- [x] View your host and security configs from the CLI to programmatically fetch the API token, among other settings
- [x] Search your library or collections - [x] Search your library or collections
- [x] Add movies to your library - [x] Add movies to your library
- [x] Delete movies, downloads, and indexers - [x] Delete movies, downloads, and indexers
@@ -95,7 +104,8 @@ cargo install --locked managarr
### The Managarr CLI ### The Managarr CLI
Managarr can be used in one of two ways: As a TUI, or as a CLI for managing your Servarrs. Managarr can be used in one of two ways: As a TUI, or as a CLI for managing your Servarrs.
All management features available in the TUI are also available in the CLI. All management features available in the TUI are also available in the CLI. However, the CLI is
equipped with additional features to allow for more advanced usage and automation.
The CLI can be helpful for automating tasks or for use in scripts. For example, you can use the CLI to trigger a search for a movie, or to add a movie to your library. The CLI can be helpful for automating tasks or for use in scripts. For example, you can use the CLI to trigger a search for a movie, or to add a movie to your library.
@@ -103,12 +113,12 @@ To see all available commands, simply run `managarr --help`:
```shell ```shell
$ managarr --help $ managarr --help
managarr 0.0.36 managarr 0.1.3
Alex Clarke <alex.j.tusa@gmail.com> Alex Clarke <alex.j.tusa@gmail.com>
A TUI and CLI to manage your Servarrs A TUI and CLI to manage your Servarrs
Usage: managarr [COMMAND] Usage: managarr [OPTIONS] [COMMAND]
Commands: Commands:
radarr Commands for manging your Radarr instance radarr Commands for manging your Radarr instance
@@ -116,8 +126,10 @@ Commands:
help Print this message or the help of the given subcommand(s) help Print this message or the help of the given subcommand(s)
Options: Options:
-h, --help Print help --config <CONFIG> The Managarr configuration file to use
-V, --version Print version --disable-terminal-size-checks Disable the terminal size checks
-h, --help Print help
-V, --version Print version
``` ```
All subcommands also have detailed help menus to show you how to use them. For example, to see all available commands for Radarr, you would run: All subcommands also have detailed help menus to show you how to use them. For example, to see all available commands for Radarr, you would run:
@@ -126,7 +138,7 @@ All subcommands also have detailed help menus to show you how to use them. For e
$ managarr radarr --help $ managarr radarr --help
Commands for manging your Radarr instance Commands for manging your Radarr instance
Usage: managarr radarr <COMMAND> Usage: managarr radarr [OPTIONS] <COMMAND>
Commands: Commands:
add Commands to add or create new resources within your Radarr instance add Commands to add or create new resources within your Radarr instance
@@ -146,7 +158,9 @@ Commands:
help Print this message or the help of the given subcommand(s) help Print this message or the help of the given subcommand(s)
Options: Options:
-h, --help Print help --config <CONFIG> The Managarr configuration file to use
--disable-terminal-size-checks Disable the terminal size checks
-h, --help Print help
``` ```
**Pro Tip:** The CLI is even more powerful and useful when used in conjunction with the `jq` CLI tool. This allows you to parse the JSON response from the Managarr CLI and use it in your scripts; For example, to extract the `movieId` of the movie "Ad Astra", you would run: **Pro Tip:** The CLI is even more powerful and useful when used in conjunction with the `jq` CLI tool. This allows you to parse the JSON response from the Managarr CLI and use it in your scripts; For example, to extract the `movieId` of the movie "Ad Astra", you would run:
@@ -156,16 +170,6 @@ $ managarr radarr list movies | jq '.[] | select(.title == "Ad Astra") | .id'
277 277
``` ```
## Installation
### Docker
Run Managarr as a docker container by mounting your `config.yml` file to `/root/.config/managarr/config.yml`. For example:
```shell
docker run --rm -it -v ~/.config/managarr:/root/.config/managarr darkalex17/managarr
```
You can also clone this repo and run `make docker` to build a docker image locally and run it using the above command.
# Configuration # Configuration
Managarr assumes reasonable defaults to connect to each service (i.e. Radarr is on localhost:7878), Managarr assumes reasonable defaults to connect to each service (i.e. Radarr is on localhost:7878),
but all servers will require you to input the API token. but all servers will require you to input the API token.
@@ -187,12 +191,23 @@ $HOME/Library/Application Support/managarr/config.yml
%APPDATA%/Roaming/managarr/config.yml %APPDATA%/Roaming/managarr/config.yml
``` ```
## Specify Which Configuration File to Use
It can sometimes be useful to specify the configuration file you wish to use. This is useful in cases
where you may have more than one instance of a given Servarr running. Thus, you can specify the
config file using the `--config` flag:
```shell
managarr --config /path/to/config.yml
```
### Example Configuration: ### Example Configuration:
```yaml ```yaml
radarr: radarr:
host: 127.0.0.1 host: 127.0.0.1
port: 7878 port: 7878
api_token: someApiToken1234567890 api_token: someApiToken1234567890
use_ssl: true
ssl_cert_path: /path/to/radarr.crt
sonarr: sonarr:
host: 127.0.0.1 host: 127.0.0.1
port: 8989 port: 8989
@@ -201,26 +216,32 @@ readarr:
host: 127.0.0.1 host: 127.0.0.1
port: 8787 port: 8787
api_token: someApiToken1234567890 api_token: someApiToken1234567890
use_ssl: false
lidarr: lidarr:
host: 127.0.0.1 host: 127.0.0.1
port: 8686 port: 8686
api_token: someApiToken1234567890 api_token: someApiToken1234567890
use_ssl: false
whisparr: whisparr:
host: 127.0.0.1 host: 127.0.0.1
port: 6969 port: 6969
api_token: someApiToken1234567890 api_token: someApiToken1234567890
use_ssl: false
bazarr: bazarr:
host: 127.0.0.1 host: 127.0.0.1
port: 6767 port: 6767
api_token: someApiToken1234567890 api_token: someApiToken1234567890
use_ssl: false
prowlarr: prowlarr:
host: 127.0.0.1 host: 127.0.0.1
port: 9696 port: 9696
api_token: someApiToken1234567890 api_token: someApiToken1234567890
use_ssl: false
tautulli: tautulli:
host: 127.0.0.1 host: 127.0.0.1
port: 8181 port: 8181
api_token: someApiToken1234567890 api_token: someApiToken1234567890
use_ssl: false
``` ```
## Track My Progress for the Beta release (With Sonarr Support!) ## Track My Progress for the Beta release (With Sonarr Support!)
+2
View File
@@ -224,5 +224,7 @@ mod tests {
assert_str_eq!(radarr_config.host, "localhost"); assert_str_eq!(radarr_config.host, "localhost");
assert_eq!(radarr_config.port, Some(7878)); assert_eq!(radarr_config.port, Some(7878));
assert!(radarr_config.api_token.is_empty()); assert!(radarr_config.api_token.is_empty());
assert!(!radarr_config.use_ssl);
assert_eq!(radarr_config.ssl_cert_path, None);
} }
} }
+5
View File
@@ -176,6 +176,9 @@ pub struct RadarrConfig {
pub host: String, pub host: String,
pub port: Option<u16>, pub port: Option<u16>,
pub api_token: String, pub api_token: String,
#[serde(default)]
pub use_ssl: bool,
pub ssl_cert_path: Option<String>,
} }
impl Default for RadarrConfig { impl Default for RadarrConfig {
@@ -184,6 +187,8 @@ impl Default for RadarrConfig {
host: "localhost".to_string(), host: "localhost".to_string(),
port: Some(7878), port: Some(7878),
api_token: "".to_string(), api_token: "".to_string(),
use_ssl: false,
ssl_cert_path: None,
} }
} }
} }
+10
View File
@@ -21,6 +21,8 @@ mod get_command_handler_tests;
pub enum RadarrGetCommand { pub enum RadarrGetCommand {
#[command(about = "Get the shared settings for all indexers")] #[command(about = "Get the shared settings for all indexers")]
AllIndexerSettings, AllIndexerSettings,
#[command(about = "Fetch the host config for your Radarr instance")]
HostConfig,
#[command(about = "Get detailed information for the movie with the given ID")] #[command(about = "Get detailed information for the movie with the given ID")]
MovieDetails { MovieDetails {
#[arg( #[arg(
@@ -39,6 +41,8 @@ pub enum RadarrGetCommand {
)] )]
movie_id: i64, movie_id: i64,
}, },
#[command(about = "Fetch the security config for your Radarr instance")]
SecurityConfig,
#[command(about = "Get the system status")] #[command(about = "Get the system status")]
SystemStatus, SystemStatus,
} }
@@ -73,12 +77,18 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, RadarrGetCommand> for RadarrGetCommandHan
RadarrGetCommand::AllIndexerSettings => { RadarrGetCommand::AllIndexerSettings => {
execute_network_event!(self, RadarrEvent::GetAllIndexerSettings); execute_network_event!(self, RadarrEvent::GetAllIndexerSettings);
} }
RadarrGetCommand::HostConfig => {
execute_network_event!(self, RadarrEvent::GetHostConfig);
}
RadarrGetCommand::MovieDetails { movie_id } => { RadarrGetCommand::MovieDetails { movie_id } => {
execute_network_event!(self, RadarrEvent::GetMovieDetails(Some(movie_id))); execute_network_event!(self, RadarrEvent::GetMovieDetails(Some(movie_id)));
} }
RadarrGetCommand::MovieHistory { movie_id } => { RadarrGetCommand::MovieHistory { movie_id } => {
execute_network_event!(self, RadarrEvent::GetMovieHistory(Some(movie_id))); execute_network_event!(self, RadarrEvent::GetMovieHistory(Some(movie_id)));
} }
RadarrGetCommand::SecurityConfig => {
execute_network_event!(self, RadarrEvent::GetSecurityConfig);
}
RadarrGetCommand::SystemStatus => { RadarrGetCommand::SystemStatus => {
execute_network_event!(self, RadarrEvent::GetStatus); execute_network_event!(self, RadarrEvent::GetStatus);
} }
@@ -29,6 +29,14 @@ mod test {
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[test]
fn test_get_host_config_has_no_arg_requirements() {
let result =
Cli::command().try_get_matches_from(["managarr", "radarr", "get", "host-config"]);
assert!(result.is_ok());
}
#[test] #[test]
fn test_movie_details_requires_movie_id() { fn test_movie_details_requires_movie_id() {
let result = let result =
@@ -81,6 +89,14 @@ mod test {
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[test]
fn test_get_security_config_has_no_arg_requirements() {
let result =
Cli::command().try_get_matches_from(["managarr", "radarr", "get", "security-config"]);
assert!(result.is_ok());
}
#[test] #[test]
fn test_system_status_has_no_arg_requirements() { fn test_system_status_has_no_arg_requirements() {
let result = let result =
@@ -135,6 +151,29 @@ mod test {
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[tokio::test]
async fn test_handle_get_host_config_command() {
let mut mock_network = MockNetworkTrait::new();
mock_network
.expect_handle_network_event()
.with(eq::<NetworkEvent>(RadarrEvent::GetHostConfig.into()))
.times(1)
.returning(|_| {
Ok(Serdeable::Radarr(RadarrSerdeable::Value(
json!({"testResponse": "response"}),
)))
});
let app_arc = Arc::new(Mutex::new(App::default()));
let get_host_config_command = RadarrGetCommand::HostConfig;
let result =
RadarrGetCommandHandler::with(&app_arc, get_host_config_command, &mut mock_network)
.handle()
.await;
assert!(result.is_ok());
}
#[tokio::test] #[tokio::test]
async fn test_handle_get_movie_details_command() { async fn test_handle_get_movie_details_command() {
let expected_movie_id = 1; let expected_movie_id = 1;
@@ -187,6 +226,29 @@ mod test {
assert!(result.is_ok()); assert!(result.is_ok());
} }
#[tokio::test]
async fn test_handle_get_security_config_command() {
let mut mock_network = MockNetworkTrait::new();
mock_network
.expect_handle_network_event()
.with(eq::<NetworkEvent>(RadarrEvent::GetSecurityConfig.into()))
.times(1)
.returning(|_| {
Ok(Serdeable::Radarr(RadarrSerdeable::Value(
json!({"testResponse": "response"}),
)))
});
let app_arc = Arc::new(Mutex::new(App::default()));
let get_security_config_command = RadarrGetCommand::SecurityConfig;
let result =
RadarrGetCommandHandler::with(&app_arc, get_security_config_command, &mut mock_network)
.handle()
.await;
assert!(result.is_ok());
}
#[tokio::test] #[tokio::test]
async fn test_handle_get_system_status_command() { async fn test_handle_get_system_status_command() {
let mut mock_network = MockNetworkTrait::new(); let mut mock_network = MockNetworkTrait::new();
+93 -15
View File
@@ -1,12 +1,16 @@
#![warn(rust_2018_idioms)] #![warn(rust_2018_idioms)]
use std::fs::{self, File};
use std::io::BufReader;
use std::panic::PanicHookInfo; use std::panic::PanicHookInfo;
use std::path::PathBuf;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::Arc; use std::sync::Arc;
use std::{io, panic, process}; use std::{io, panic, process};
use anyhow::anyhow; use anyhow::anyhow;
use anyhow::Result; use anyhow::Result;
use app::AppConfig;
use clap::{ use clap::{
command, crate_authors, crate_description, crate_name, crate_version, CommandFactory, Parser, command, crate_authors, crate_description, crate_name, crate_version, CommandFactory, Parser,
}; };
@@ -20,6 +24,7 @@ use log::error;
use network::NetworkTrait; use network::NetworkTrait;
use ratatui::backend::CrosstermBackend; use ratatui::backend::CrosstermBackend;
use ratatui::Terminal; use ratatui::Terminal;
use reqwest::{Certificate, Client};
use tokio::sync::mpsc::Receiver; use tokio::sync::mpsc::Receiver;
use tokio::sync::{mpsc, Mutex}; use tokio::sync::{mpsc, Mutex};
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
@@ -62,6 +67,15 @@ static MIN_TERM_HEIGHT: u16 = 40;
struct Cli { struct Cli {
#[command(subcommand)] #[command(subcommand)]
command: Option<Command>, command: Option<Command>,
#[arg(
long,
global = true,
value_parser,
help = "The Managarr configuration file to use"
)]
config: Option<PathBuf>,
#[arg(long, global = true, help = "Disable the terminal size checks")]
disable_terminal_size_checks: bool,
} }
#[tokio::main] #[tokio::main]
@@ -73,7 +87,12 @@ async fn main() -> Result<()> {
let running = Arc::new(AtomicBool::new(true)); let running = Arc::new(AtomicBool::new(true));
let r = running.clone(); let r = running.clone();
let args = Cli::parse(); let args = Cli::parse();
let config = confy::load("managarr", "config")?; let config = if let Some(ref config_file) = args.config {
load_config(config_file.to_str().expect("Invalid config file specified"))?
} else {
confy::load("managarr", "config")?
};
let reqwest_client = build_network_client(&config);
let (sync_network_tx, sync_network_rx) = mpsc::channel(500); let (sync_network_tx, sync_network_rx) = mpsc::channel(500);
let cancellation_token = CancellationToken::new(); let cancellation_token = CancellationToken::new();
let ctrlc_cancellation_token = cancellation_token.clone(); let ctrlc_cancellation_token = cancellation_token.clone();
@@ -95,7 +114,7 @@ async fn main() -> Result<()> {
Some(command) => match command { Some(command) => match command {
Command::Radarr(_) => { Command::Radarr(_) => {
let app_nw = Arc::clone(&app); let app_nw = Arc::clone(&app);
let mut network = Network::new(&app_nw, cancellation_token); let mut network = Network::new(&app_nw, cancellation_token, reqwest_client);
if let Err(e) = cli::handle_command(&app, command, &mut network).await { if let Err(e) = cli::handle_command(&app, command, &mut network).await {
eprintln!("error: {}", e.to_string().red()); eprintln!("error: {}", e.to_string().red());
@@ -109,8 +128,10 @@ async fn main() -> Result<()> {
}, },
None => { None => {
let app_nw = Arc::clone(&app); let app_nw = Arc::clone(&app);
std::thread::spawn(move || start_networking(sync_network_rx, &app_nw, cancellation_token)); std::thread::spawn(move || {
start_ui(&app).await?; start_networking(sync_network_rx, &app_nw, cancellation_token, reqwest_client)
});
start_ui(&app, !args.disable_terminal_size_checks).await?;
} }
} }
@@ -122,8 +143,9 @@ async fn start_networking(
mut network_rx: Receiver<NetworkEvent>, mut network_rx: Receiver<NetworkEvent>,
app: &Arc<Mutex<App<'_>>>, app: &Arc<Mutex<App<'_>>>,
cancellation_token: CancellationToken, cancellation_token: CancellationToken,
client: Client,
) { ) {
let mut network = Network::new(app, cancellation_token); let mut network = Network::new(app, cancellation_token, client);
while let Some(network_event) = network_rx.recv().await { while let Some(network_event) = network_rx.recv().await {
if let Err(e) = network.handle_network_event(network_event).await { if let Err(e) = network.handle_network_event(network_event).await {
@@ -132,16 +154,18 @@ async fn start_networking(
} }
} }
async fn start_ui(app: &Arc<Mutex<App<'_>>>) -> Result<()> { async fn start_ui(app: &Arc<Mutex<App<'_>>>, check_terminal_size: bool) -> Result<()> {
let (width, height) = size()?; if check_terminal_size {
if width < MIN_TERM_WIDTH || height < MIN_TERM_HEIGHT { let (width, height) = size()?;
return Err(anyhow!( if width < MIN_TERM_WIDTH || height < MIN_TERM_HEIGHT {
"Terminal too small. Minimum size required: {}x{}; current terminal size: {}x{}", return Err(anyhow!(
MIN_TERM_WIDTH, "Terminal too small. Minimum size required: {}x{}; current terminal size: {}x{}",
MIN_TERM_HEIGHT, MIN_TERM_WIDTH,
width, MIN_TERM_HEIGHT,
height width,
)); height
));
}
} }
let mut stdout = io::stdout(); let mut stdout = io::stdout();
@@ -212,6 +236,60 @@ fn panic_hook(info: &PanicHookInfo<'_>) {
.unwrap(); .unwrap();
} }
fn load_config(path: &str) -> Result<AppConfig> {
let file = File::open(path).map_err(|e| anyhow!(e))?;
let reader = BufReader::new(file);
let config = serde_yaml::from_reader(reader)?;
Ok(config)
}
fn build_network_client(config: &AppConfig) -> Client {
let mut client_builder = Client::builder();
if config.radarr.use_ssl {
let cert = add_cert_to_builder(config.radarr.ssl_cert_path.clone(), "Radarr");
client_builder = client_builder.add_root_certificate(cert);
}
match client_builder.build() {
Ok(client) => client,
Err(e) => {
error!("Unable to create reqwest client: {}", e);
eprintln!("error: {}", e.to_string().red());
process::exit(1);
}
}
}
fn add_cert_to_builder(cert_path: Option<String>, servarr_name: &str) -> Certificate {
let err = |error: String| {
error!("{}", error);
eprintln!("error: {}", error.red());
process::exit(1);
};
if cert_path.is_none() {
err(format!(
"A {} cert path is required when 'use_ssl' is 'true'",
servarr_name
));
}
match fs::read(cert_path.unwrap()) {
Ok(cert) => match Certificate::from_pem(&cert) {
Ok(certificate) => certificate,
Err(_) => err(format!(
"Unable to read the specified {} SSL certificate",
servarr_name
)),
},
Err(_) => err(format!(
"Unable to open specified {} SSL certificate",
servarr_name
)),
}
}
#[cfg(not(debug_assertions))] #[cfg(not(debug_assertions))]
fn panic_hook(info: &PanicHookInfo<'_>) { fn panic_hook(info: &PanicHookInfo<'_>) {
use human_panic::{handle_dump, print_msg, Metadata}; use human_panic::{handle_dump, print_msg, Metadata};
+89
View File
@@ -57,6 +57,44 @@ pub struct AddRootFolderBody {
pub path: String, pub path: String,
} }
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, ValueEnum)]
#[serde(rename_all = "camelCase")]
pub enum AuthenticationMethod {
#[default]
Basic,
Forms,
None,
}
impl Display for AuthenticationMethod {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let authentication_method = match self {
AuthenticationMethod::Basic => "basic",
AuthenticationMethod::Forms => "forms",
AuthenticationMethod::None => "none",
};
write!(f, "{authentication_method}")
}
}
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, ValueEnum)]
#[serde(rename_all = "camelCase")]
pub enum AuthenticationRequired {
Enabled,
#[default]
DisabledForLocalAddresses,
}
impl Display for AuthenticationRequired {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let authentication_required = match self {
AuthenticationRequired::Enabled => "enabled",
AuthenticationRequired::DisabledForLocalAddresses => "disabledForLocalAddresses",
};
write!(f, "{authentication_required}")
}
}
#[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)] #[derive(Default, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct BlocklistResponse { pub struct BlocklistResponse {
pub records: Vec<BlocklistItem>, pub records: Vec<BlocklistItem>,
@@ -85,6 +123,26 @@ pub struct BlocklistItemMovie {
pub title: HorizontallyScrollableText, pub title: HorizontallyScrollableText,
} }
#[derive(Serialize, Deserialize, Default, PartialEq, Eq, Clone, Copy, Debug, ValueEnum)]
#[serde(rename_all = "camelCase")]
pub enum CertificateValidation {
#[default]
Enabled,
DisabledForLocalAddresses,
Disabled,
}
impl Display for CertificateValidation {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let certificate_validation = match self {
CertificateValidation::Enabled => "enabled",
CertificateValidation::DisabledForLocalAddresses => "disabledForLocalAddresses",
CertificateValidation::Disabled => "disabled",
};
write!(f, "{certificate_validation}")
}
}
#[derive(Serialize, Deserialize, Derivative, Default, Clone, Debug, PartialEq, Eq)] #[derive(Serialize, Deserialize, Derivative, Default, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Collection { pub struct Collection {
@@ -223,6 +281,22 @@ pub struct EditMovieParams {
pub clear_tags: bool, pub clear_tags: bool,
} }
#[derive(Default, Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct HostConfig {
pub bind_address: HorizontallyScrollableText,
#[serde(deserialize_with = "super::from_i64")]
pub port: i64,
pub url_base: Option<HorizontallyScrollableText>,
pub instance_name: Option<HorizontallyScrollableText>,
pub application_url: Option<HorizontallyScrollableText>,
pub enable_ssl: bool,
#[serde(deserialize_with = "super::from_i64")]
pub ssl_port: i64,
pub ssl_cert_path: Option<String>,
pub ssl_cert_password: Option<String>,
}
#[derive(Default, Deserialize, Serialize, Debug, Clone, Eq, PartialEq)] #[derive(Default, Deserialize, Serialize, Debug, Clone, Eq, PartialEq)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct Indexer { pub struct Indexer {
@@ -560,6 +634,17 @@ pub struct RootFolder {
pub unmapped_folders: Option<Vec<UnmappedFolder>>, pub unmapped_folders: Option<Vec<UnmappedFolder>>,
} }
#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub struct SecurityConfig {
pub authentication_method: AuthenticationMethod,
pub authentication_required: AuthenticationRequired,
pub username: String,
pub password: Option<String>,
pub api_key: String,
pub certificate_validation: CertificateValidation,
}
#[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)] #[derive(Default, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
pub struct SystemStatus { pub struct SystemStatus {
@@ -647,6 +732,7 @@ pub enum RadarrSerdeable {
Credits(Vec<Credit>), Credits(Vec<Credit>),
DiskSpaces(Vec<DiskSpace>), DiskSpaces(Vec<DiskSpace>),
DownloadsResponse(DownloadsResponse), DownloadsResponse(DownloadsResponse),
HostConfig(HostConfig),
Indexers(Vec<Indexer>), Indexers(Vec<Indexer>),
IndexerSettings(IndexerSettings), IndexerSettings(IndexerSettings),
LogResponse(LogResponse), LogResponse(LogResponse),
@@ -657,6 +743,7 @@ pub enum RadarrSerdeable {
QueueEvents(Vec<QueueEvent>), QueueEvents(Vec<QueueEvent>),
Releases(Vec<Release>), Releases(Vec<Release>),
RootFolders(Vec<RootFolder>), RootFolders(Vec<RootFolder>),
SecurityConfig(SecurityConfig),
SystemStatus(SystemStatus), SystemStatus(SystemStatus),
Tags(Vec<Tag>), Tags(Vec<Tag>),
Tasks(Vec<Task>), Tasks(Vec<Task>),
@@ -686,6 +773,7 @@ serde_enum_from!(
Credits(Vec<Credit>), Credits(Vec<Credit>),
DiskSpaces(Vec<DiskSpace>), DiskSpaces(Vec<DiskSpace>),
DownloadsResponse(DownloadsResponse), DownloadsResponse(DownloadsResponse),
HostConfig(HostConfig),
Indexers(Vec<Indexer>), Indexers(Vec<Indexer>),
IndexerSettings(IndexerSettings), IndexerSettings(IndexerSettings),
LogResponse(LogResponse), LogResponse(LogResponse),
@@ -696,6 +784,7 @@ serde_enum_from!(
QueueEvents(Vec<QueueEvent>), QueueEvents(Vec<QueueEvent>),
Releases(Vec<Release>), Releases(Vec<Release>),
RootFolders(Vec<RootFolder>), RootFolders(Vec<RootFolder>),
SecurityConfig(SecurityConfig),
SystemStatus(SystemStatus), SystemStatus(SystemStatus),
Tags(Vec<Tag>), Tags(Vec<Tag>),
Tasks(Vec<Task>), Tasks(Vec<Task>),
+31 -4
View File
@@ -5,14 +5,41 @@ mod tests {
use crate::models::{ use crate::models::{
radarr_models::{ radarr_models::{
AddMovieSearchResult, BlocklistItem, BlocklistResponse, Collection, Credit, DiskSpace, AddMovieSearchResult, AuthenticationMethod, AuthenticationRequired, BlocklistItem,
DownloadRecord, DownloadsResponse, Indexer, IndexerSettings, IndexerTestResult, Log, BlocklistResponse, CertificateValidation, Collection, Credit, DiskSpace, DownloadRecord,
LogResponse, MinimumAvailability, Monitor, Movie, MovieHistoryItem, QualityProfile, DownloadsResponse, Indexer, IndexerSettings, IndexerTestResult, Log, LogResponse,
QueueEvent, RadarrSerdeable, Release, RootFolder, SystemStatus, Tag, Task, TaskName, Update, MinimumAvailability, Monitor, Movie, MovieHistoryItem, QualityProfile, QueueEvent,
RadarrSerdeable, Release, RootFolder, SystemStatus, Tag, Task, TaskName, Update,
}, },
Serdeable, Serdeable,
}; };
#[test]
fn test_authentication_method_display() {
assert_str_eq!(AuthenticationMethod::Basic.to_string(), "basic");
assert_str_eq!(AuthenticationMethod::Forms.to_string(), "forms");
assert_str_eq!(AuthenticationMethod::None.to_string(), "none");
}
#[test]
fn test_authentication_required_display() {
assert_str_eq!(AuthenticationRequired::Enabled.to_string(), "enabled");
assert_str_eq!(
AuthenticationRequired::DisabledForLocalAddresses.to_string(),
"disabledForLocalAddresses"
);
}
#[test]
fn test_certificate_validation_display() {
assert_str_eq!(CertificateValidation::Enabled.to_string(), "enabled");
assert_str_eq!(
CertificateValidation::DisabledForLocalAddresses.to_string(),
"disabledForLocalAddresses"
);
assert_str_eq!(CertificateValidation::Disabled.to_string(), "disabled");
}
#[test] #[test]
fn test_task_name_display() { fn test_task_name_display() {
assert_str_eq!( assert_str_eq!(
+6 -2
View File
@@ -62,9 +62,13 @@ impl<'a, 'b> NetworkTrait for Network<'a, 'b> {
} }
impl<'a, 'b> Network<'a, 'b> { impl<'a, 'b> Network<'a, 'b> {
pub fn new(app: &'a Arc<Mutex<App<'b>>>, cancellation_token: CancellationToken) -> Self { pub fn new(
app: &'a Arc<Mutex<App<'b>>>,
cancellation_token: CancellationToken,
client: Client,
) -> Self {
Network { Network {
client: Client::new(), client,
app, app,
cancellation_token, cancellation_token,
} }
+13 -10
View File
@@ -6,6 +6,7 @@ mod tests {
use mockito::{Mock, Server, ServerGuard}; use mockito::{Mock, Server, ServerGuard};
use pretty_assertions::assert_str_eq; use pretty_assertions::assert_str_eq;
use reqwest::Client;
use rstest::rstest; use rstest::rstest;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tokio::sync::{mpsc, Mutex}; use tokio::sync::{mpsc, Mutex};
@@ -37,10 +38,12 @@ mod tests {
host, host,
api_token: String::new(), api_token: String::new(),
port, port,
use_ssl: false,
ssl_cert_path: None,
}; };
app.config.radarr = radarr_config; app.config.radarr = radarr_config;
let app_arc = Arc::new(Mutex::new(app)); let app_arc = Arc::new(Mutex::new(app));
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let _ = network let _ = network
.handle_network_event(RadarrEvent::HealthCheck.into()) .handle_network_event(RadarrEvent::HealthCheck.into())
@@ -64,7 +67,7 @@ mod tests {
.create_async() .create_async()
.await; .await;
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let _ = network let _ = network
.handle_request::<Test, ()>( .handle_request::<Test, ()>(
@@ -90,7 +93,7 @@ mod tests {
#[values(RequestMethod::Get, RequestMethod::Post)] request_method: RequestMethod, #[values(RequestMethod::Get, RequestMethod::Post)] request_method: RequestMethod,
) { ) {
let (async_server, app_arc, server) = mock_api(request_method, 200, true).await; let (async_server, app_arc, server) = mock_api(request_method, 200, true).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let resp = network let resp = network
.handle_request::<(), Test>( .handle_request::<(), Test>(
@@ -122,7 +125,7 @@ mod tests {
#[values(RequestMethod::Get, RequestMethod::Post)] request_method: RequestMethod, #[values(RequestMethod::Get, RequestMethod::Post)] request_method: RequestMethod,
) { ) {
let (async_server, app_arc, server) = mock_api(request_method, 400, true).await; let (async_server, app_arc, server) = mock_api(request_method, 400, true).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let mut test_result = String::new(); let mut test_result = String::new();
let resp = network let resp = network
@@ -160,7 +163,7 @@ mod tests {
cancellation_token.clone(), cancellation_token.clone(),
))); )));
app_arc.lock().await.is_loading = true; app_arc.lock().await.is_loading = true;
let mut network = Network::new(&app_arc, cancellation_token); let mut network = Network::new(&app_arc, cancellation_token, Client::new());
network.cancellation_token.cancel(); network.cancellation_token.cancel();
let resp = network let resp = network
@@ -194,7 +197,7 @@ mod tests {
.create_async() .create_async()
.await; .await;
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let resp = network let resp = network
.handle_request::<(), Test>( .handle_request::<(), Test>(
@@ -226,7 +229,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_handle_request_failure_to_send_request() { async fn test_handle_request_failure_to_send_request() {
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let resp = network let resp = network
.handle_request::<(), Test>( .handle_request::<(), Test>(
@@ -266,7 +269,7 @@ mod tests {
request_method: RequestMethod, request_method: RequestMethod,
) { ) {
let (async_server, app_arc, server) = mock_api(request_method, 404, true).await; let (async_server, app_arc, server) = mock_api(request_method, 404, true).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let resp = network let resp = network
.handle_request::<(), Test>( .handle_request::<(), Test>(
@@ -296,7 +299,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_handle_request_non_success_code_empty_response_body() { async fn test_handle_request_non_success_code_empty_response_body() {
let (async_server, app_arc, server) = mock_api(RequestMethod::Post, 404, false).await; let (async_server, app_arc, server) = mock_api(RequestMethod::Post, 404, false).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let resp = network let resp = network
.handle_request::<(), Test>( .handle_request::<(), Test>(
@@ -354,7 +357,7 @@ mod tests {
async_server = async_server.create_async().await; async_server = async_server.create_async().await;
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
let network = Network::new(&app_arc, CancellationToken::new()); let network = Network::new(&app_arc, CancellationToken::new(), Client::new());
network network
.call_api(RequestProps { .call_api(RequestProps {
+50 -7
View File
@@ -11,10 +11,10 @@ use crate::app::RadarrConfig;
use crate::models::radarr_models::{ use crate::models::radarr_models::{
AddMovieBody, AddMovieSearchResult, AddOptions, AddRootFolderBody, BlocklistResponse, Collection, AddMovieBody, AddMovieSearchResult, AddOptions, AddRootFolderBody, BlocklistResponse, Collection,
CollectionMovie, CommandBody, Credit, CreditType, DeleteMovieParams, DiskSpace, DownloadRecord, CollectionMovie, CommandBody, Credit, CreditType, DeleteMovieParams, DiskSpace, DownloadRecord,
DownloadsResponse, EditCollectionParams, EditIndexerParams, EditMovieParams, Indexer, DownloadsResponse, EditCollectionParams, EditIndexerParams, EditMovieParams, HostConfig, Indexer,
IndexerSettings, IndexerTestResult, LogResponse, Movie, MovieCommandBody, MovieHistoryItem, IndexerSettings, IndexerTestResult, LogResponse, Movie, MovieCommandBody, MovieHistoryItem,
QualityProfile, QueueEvent, RadarrSerdeable, Release, ReleaseDownloadBody, RootFolder, QualityProfile, QueueEvent, RadarrSerdeable, Release, ReleaseDownloadBody, RootFolder,
SystemStatus, Tag, Task, TaskName, Update, SecurityConfig, SystemStatus, Tag, Task, TaskName, Update,
}; };
use crate::models::servarr_data::radarr::modals::{ use crate::models::servarr_data::radarr::modals::{
AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, IndexerTestResultModalItem, AddMovieModal, EditCollectionModal, EditIndexerModal, EditMovieModal, IndexerTestResultModalItem,
@@ -50,6 +50,7 @@ pub enum RadarrEvent {
GetBlocklist, GetBlocklist,
GetCollections, GetCollections,
GetDownloads, GetDownloads,
GetHostConfig,
GetIndexers, GetIndexers,
GetAllIndexerSettings, GetAllIndexerSettings,
GetLogs(Option<u64>), GetLogs(Option<u64>),
@@ -62,6 +63,7 @@ pub enum RadarrEvent {
GetQueuedEvents, GetQueuedEvents,
GetReleases(Option<i64>), GetReleases(Option<i64>),
GetRootFolders, GetRootFolders,
GetSecurityConfig,
GetStatus, GetStatus,
GetTags, GetTags,
GetTasks, GetTasks,
@@ -86,6 +88,7 @@ impl RadarrEvent {
RadarrEvent::GetBlocklist => "/blocklist?page=1&pageSize=10000", RadarrEvent::GetBlocklist => "/blocklist?page=1&pageSize=10000",
RadarrEvent::GetCollections | RadarrEvent::EditCollection(_) => "/collection", RadarrEvent::GetCollections | RadarrEvent::EditCollection(_) => "/collection",
RadarrEvent::GetDownloads | RadarrEvent::DeleteDownload(_) => "/queue", RadarrEvent::GetDownloads | RadarrEvent::DeleteDownload(_) => "/queue",
RadarrEvent::GetHostConfig | RadarrEvent::GetSecurityConfig => "/config/host",
RadarrEvent::GetIndexers | RadarrEvent::EditIndexer(_) | RadarrEvent::DeleteIndexer(_) => { RadarrEvent::GetIndexers | RadarrEvent::EditIndexer(_) | RadarrEvent::DeleteIndexer(_) => {
"/indexer" "/indexer"
} }
@@ -179,14 +182,15 @@ impl<'a, 'b> Network<'a, 'b> {
self.edit_indexer(params).await.map(RadarrSerdeable::from) self.edit_indexer(params).await.map(RadarrSerdeable::from)
} }
RadarrEvent::EditMovie(params) => self.edit_movie(params).await.map(RadarrSerdeable::from), RadarrEvent::EditMovie(params) => self.edit_movie(params).await.map(RadarrSerdeable::from),
RadarrEvent::GetBlocklist => self.get_blocklist().await.map(RadarrSerdeable::from),
RadarrEvent::GetCollections => self.get_collections().await.map(RadarrSerdeable::from),
RadarrEvent::GetDownloads => self.get_downloads().await.map(RadarrSerdeable::from),
RadarrEvent::GetIndexers => self.get_indexers().await.map(RadarrSerdeable::from),
RadarrEvent::GetAllIndexerSettings => self RadarrEvent::GetAllIndexerSettings => self
.get_all_indexer_settings() .get_all_indexer_settings()
.await .await
.map(RadarrSerdeable::from), .map(RadarrSerdeable::from),
RadarrEvent::GetBlocklist => self.get_blocklist().await.map(RadarrSerdeable::from),
RadarrEvent::GetCollections => self.get_collections().await.map(RadarrSerdeable::from),
RadarrEvent::GetDownloads => self.get_downloads().await.map(RadarrSerdeable::from),
RadarrEvent::GetHostConfig => self.get_host_config().await.map(RadarrSerdeable::from),
RadarrEvent::GetIndexers => self.get_indexers().await.map(RadarrSerdeable::from),
RadarrEvent::GetLogs(events) => self.get_logs(events).await.map(RadarrSerdeable::from), RadarrEvent::GetLogs(events) => self.get_logs(events).await.map(RadarrSerdeable::from),
RadarrEvent::GetMovieCredits(movie_id) => { RadarrEvent::GetMovieCredits(movie_id) => {
self.get_credits(movie_id).await.map(RadarrSerdeable::from) self.get_credits(movie_id).await.map(RadarrSerdeable::from)
@@ -209,6 +213,7 @@ impl<'a, 'b> Network<'a, 'b> {
self.get_releases(movie_id).await.map(RadarrSerdeable::from) self.get_releases(movie_id).await.map(RadarrSerdeable::from)
} }
RadarrEvent::GetRootFolders => self.get_root_folders().await.map(RadarrSerdeable::from), RadarrEvent::GetRootFolders => self.get_root_folders().await.map(RadarrSerdeable::from),
RadarrEvent::GetSecurityConfig => self.get_security_config().await.map(RadarrSerdeable::from),
RadarrEvent::GetStatus => self.get_status().await.map(RadarrSerdeable::from), RadarrEvent::GetStatus => self.get_status().await.map(RadarrSerdeable::from),
RadarrEvent::GetTags => self.get_tags().await.map(RadarrSerdeable::from), RadarrEvent::GetTags => self.get_tags().await.map(RadarrSerdeable::from),
RadarrEvent::GetTasks => self.get_tasks().await.map(RadarrSerdeable::from), RadarrEvent::GetTasks => self.get_tasks().await.map(RadarrSerdeable::from),
@@ -1354,6 +1359,22 @@ impl<'a, 'b> Network<'a, 'b> {
.await .await
} }
async fn get_host_config(&mut self) -> Result<HostConfig> {
info!("Fetching Radarr host config");
let request_props = self
.radarr_request_props_from(
RadarrEvent::GetHostConfig.resource(),
RequestMethod::Get,
None::<()>,
)
.await;
self
.handle_request::<(), HostConfig>(request_props, |_, _| ())
.await
}
async fn get_indexers(&mut self) -> Result<Vec<Indexer>> { async fn get_indexers(&mut self) -> Result<Vec<Indexer>> {
info!("Fetching Radarr indexers"); info!("Fetching Radarr indexers");
@@ -1765,6 +1786,22 @@ impl<'a, 'b> Network<'a, 'b> {
.await .await
} }
async fn get_security_config(&mut self) -> Result<SecurityConfig> {
info!("Fetching Radarr security config");
let request_props = self
.radarr_request_props_from(
RadarrEvent::GetSecurityConfig.resource(),
RequestMethod::Get,
None::<()>,
)
.await;
self
.handle_request::<(), SecurityConfig>(request_props, |_, _| ())
.await
}
async fn get_status(&mut self) -> Result<SystemStatus> { async fn get_status(&mut self) -> Result<SystemStatus> {
info!("Fetching Radarr system status"); info!("Fetching Radarr system status");
@@ -2225,8 +2262,14 @@ impl<'a, 'b> Network<'a, 'b> {
host, host,
port, port,
api_token, api_token,
use_ssl,
..
} = &app.config.radarr; } = &app.config.radarr;
let uri = format!("http://{host}:{}/api/v3{resource}", port.unwrap_or(7878)); let protocol = if *use_ssl { "https" } else { "http" };
let uri = format!(
"{protocol}://{host}:{}/api/v3{resource}",
port.unwrap_or(7878)
);
RequestProps { RequestProps {
uri, uri,
+178 -96
View File
@@ -6,6 +6,7 @@ mod test {
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use mockito::{Matcher, Mock, Server, ServerGuard}; use mockito::{Matcher, Mock, Server, ServerGuard};
use pretty_assertions::{assert_eq, assert_str_eq}; use pretty_assertions::{assert_eq, assert_str_eq};
use reqwest::Client;
use rstest::rstest; use rstest::rstest;
use serde_json::{json, Number, Value}; use serde_json::{json, Number, Value};
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
@@ -174,6 +175,13 @@ mod test {
assert_str_eq!(event.resource(), "/queue"); assert_str_eq!(event.resource(), "/queue");
} }
#[rstest]
fn test_resource_host_config(
#[values(RadarrEvent::GetHostConfig, RadarrEvent::GetSecurityConfig)] event: RadarrEvent,
) {
assert_str_eq!(event.resource(), "/config/host");
}
#[rstest] #[rstest]
fn test_resource_command( fn test_resource_command(
#[values( #[values(
@@ -229,7 +237,7 @@ mod test {
RadarrEvent::HealthCheck.resource(), RadarrEvent::HealthCheck.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let _ = network.handle_radarr_event(RadarrEvent::HealthCheck).await; let _ = network.handle_radarr_event(RadarrEvent::HealthCheck).await;
@@ -255,7 +263,7 @@ mod test {
RadarrEvent::GetOverview.resource(), RadarrEvent::GetOverview.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let disk_space_vec = vec![ let disk_space_vec = vec![
DiskSpace { DiskSpace {
free_space: 1111, free_space: 1111,
@@ -294,7 +302,7 @@ mod test {
RadarrEvent::GetStatus.resource(), RadarrEvent::GetStatus.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let date_time = DateTime::from(DateTime::parse_from_rfc3339("2023-02-25T20:16:43Z").unwrap()) let date_time = DateTime::from(DateTime::parse_from_rfc3339("2023-02-25T20:16:43Z").unwrap())
as DateTime<Utc>; as DateTime<Utc>;
@@ -378,7 +386,7 @@ mod test {
.movies .movies
.sorting(vec![title_sort_option]); .sorting(vec![title_sort_option]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Movies(movies) = network if let RadarrSerdeable::Movies(movies) = network
.handle_radarr_event(RadarrEvent::GetMovies) .handle_radarr_event(RadarrEvent::GetMovies)
@@ -433,7 +441,7 @@ mod test {
.radarr_data .radarr_data
.movies .movies
.sorting(vec![title_sort_option]); .sorting(vec![title_sort_option]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetMovies) .handle_radarr_event(RadarrEvent::GetMovies)
@@ -486,7 +494,7 @@ mod test {
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
app_arc.lock().await.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default()); app_arc.lock().await.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Releases(releases_vec) = network if let RadarrSerdeable::Releases(releases_vec) = network
.handle_radarr_event(RadarrEvent::GetReleases(None)) .handle_radarr_event(RadarrEvent::GetReleases(None))
@@ -544,7 +552,7 @@ mod test {
.radarr_data .radarr_data
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetReleases(None)) .handle_radarr_event(RadarrEvent::GetReleases(None))
@@ -603,7 +611,7 @@ mod test {
) )
.await; .await;
app_arc.lock().await.data.radarr_data.add_movie_search = Some("test term".into()); app_arc.lock().await.data.radarr_data.add_movie_search = Some("test term".into());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::AddMovieSearchResults(add_movie_search_results) = network if let RadarrSerdeable::AddMovieSearchResults(add_movie_search_results) = network
.handle_radarr_event(RadarrEvent::SearchNewMovie(None)) .handle_radarr_event(RadarrEvent::SearchNewMovie(None))
@@ -669,7 +677,7 @@ mod test {
&resource, &resource,
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::AddMovieSearchResults(add_movie_search_results) = network if let RadarrSerdeable::AddMovieSearchResults(add_movie_search_results) = network
.handle_radarr_event(RadarrEvent::SearchNewMovie(Some("test term".into()))) .handle_radarr_event(RadarrEvent::SearchNewMovie(Some("test term".into())))
@@ -704,7 +712,7 @@ mod test {
task_name: TaskName::default(), task_name: TaskName::default(),
..Task::default() ..Task::default()
}]); }]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Value(value) = network if let RadarrSerdeable::Value(value) = network
.handle_radarr_event(RadarrEvent::StartTask(None)) .handle_radarr_event(RadarrEvent::StartTask(None))
@@ -729,7 +737,7 @@ mod test {
RadarrEvent::StartTask(None).resource(), RadarrEvent::StartTask(None).resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Value(value) = network if let RadarrSerdeable::Value(value) = network
.handle_radarr_event(RadarrEvent::StartTask(Some(TaskName::default()))) .handle_radarr_event(RadarrEvent::StartTask(Some(TaskName::default())))
@@ -750,7 +758,7 @@ mod test {
let (async_server, app_arc, _server) = let (async_server, app_arc, _server) =
mock_radarr_api(RequestMethod::Get, None, Some(json!([])), None, &resource).await; mock_radarr_api(RequestMethod::Get, None, Some(json!([])), None, &resource).await;
app_arc.lock().await.data.radarr_data.add_movie_search = Some("test term".into()); app_arc.lock().await.data.radarr_data.add_movie_search = Some("test term".into());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::SearchNewMovie(None)) .handle_radarr_event(RadarrEvent::SearchNewMovie(None))
@@ -797,10 +805,12 @@ mod test {
host, host,
port, port,
api_token: "test1234".to_owned(), api_token: "test1234".to_owned(),
use_ssl: false,
ssl_cert_path: None,
}; };
app.config.radarr = radarr_config; app.config.radarr = radarr_config;
let app_arc = Arc::new(Mutex::new(app)); let app_arc = Arc::new(Mutex::new(app));
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::SearchNewMovie(None)) .handle_radarr_event(RadarrEvent::SearchNewMovie(None))
@@ -879,7 +889,7 @@ mod test {
.radarr_data .radarr_data
.indexers .indexers
.set_items(vec![indexer()]); .set_items(vec![indexer()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Value(value) = network if let RadarrSerdeable::Value(value) = network
.handle_radarr_event(RadarrEvent::TestIndexer(None)) .handle_radarr_event(RadarrEvent::TestIndexer(None))
@@ -947,7 +957,7 @@ mod test {
.radarr_data .radarr_data
.indexers .indexers
.set_items(vec![indexer()]); .set_items(vec![indexer()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Value(value) = network if let RadarrSerdeable::Value(value) = network
.handle_radarr_event(RadarrEvent::TestIndexer(None)) .handle_radarr_event(RadarrEvent::TestIndexer(None))
@@ -1008,7 +1018,7 @@ mod test {
.with_body("{}") .with_body("{}")
.create_async() .create_async()
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Value(value) = network if let RadarrSerdeable::Value(value) = network
.handle_radarr_event(RadarrEvent::TestIndexer(Some(1))) .handle_radarr_event(RadarrEvent::TestIndexer(Some(1)))
@@ -1085,7 +1095,7 @@ mod test {
.radarr_data .radarr_data
.indexers .indexers
.set_items(indexers); .set_items(indexers);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::IndexerTestResults(results) = network if let RadarrSerdeable::IndexerTestResults(results) = network
.handle_radarr_event(RadarrEvent::TestAllIndexers) .handle_radarr_event(RadarrEvent::TestAllIndexers)
@@ -1136,7 +1146,7 @@ mod test {
.radarr_data .radarr_data
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::TriggerAutomaticSearch(None)) .handle_radarr_event(RadarrEvent::TriggerAutomaticSearch(None))
@@ -1159,7 +1169,7 @@ mod test {
RadarrEvent::TriggerAutomaticSearch(None).resource(), RadarrEvent::TriggerAutomaticSearch(None).resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::TriggerAutomaticSearch(Some(1))) .handle_radarr_event(RadarrEvent::TriggerAutomaticSearch(Some(1)))
@@ -1189,7 +1199,7 @@ mod test {
.radarr_data .radarr_data
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::UpdateAndScan(None)) .handle_radarr_event(RadarrEvent::UpdateAndScan(None))
@@ -1212,7 +1222,7 @@ mod test {
RadarrEvent::UpdateAndScan(None).resource(), RadarrEvent::UpdateAndScan(None).resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::UpdateAndScan(Some(1))) .handle_radarr_event(RadarrEvent::UpdateAndScan(Some(1)))
@@ -1235,7 +1245,7 @@ mod test {
RadarrEvent::UpdateAllMovies.resource(), RadarrEvent::UpdateAllMovies.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::UpdateAllMovies) .handle_radarr_event(RadarrEvent::UpdateAllMovies)
@@ -1257,7 +1267,7 @@ mod test {
RadarrEvent::UpdateDownloads.resource(), RadarrEvent::UpdateDownloads.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::UpdateDownloads) .handle_radarr_event(RadarrEvent::UpdateDownloads)
@@ -1279,7 +1289,7 @@ mod test {
RadarrEvent::UpdateCollections.resource(), RadarrEvent::UpdateCollections.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::UpdateCollections) .handle_radarr_event(RadarrEvent::UpdateCollections)
@@ -1310,7 +1320,7 @@ mod test {
.set_items(vec![movie()]); .set_items(vec![movie()]);
app_arc.lock().await.data.radarr_data.quality_profile_map = app_arc.lock().await.data.radarr_data.quality_profile_map =
BiMap::from_iter([(2222, "HD - 1080p".to_owned())]); BiMap::from_iter([(2222, "HD - 1080p".to_owned())]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Movie(movie) = network if let RadarrSerdeable::Movie(movie) = network
.handle_radarr_event(RadarrEvent::GetMovieDetails(None)) .handle_radarr_event(RadarrEvent::GetMovieDetails(None))
@@ -1395,7 +1405,7 @@ mod test {
&resource, &resource,
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Movie(movie) = network if let RadarrSerdeable::Movie(movie) = network
.handle_radarr_event(RadarrEvent::GetMovieDetails(Some(1))) .handle_radarr_event(RadarrEvent::GetMovieDetails(Some(1)))
@@ -1449,7 +1459,7 @@ mod test {
.set_items(vec![movie()]); .set_items(vec![movie()]);
app_arc.lock().await.data.radarr_data.quality_profile_map = app_arc.lock().await.data.radarr_data.quality_profile_map =
BiMap::from_iter([(2222, "HD - 1080p".to_owned())]); BiMap::from_iter([(2222, "HD - 1080p".to_owned())]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetMovieDetails(None)) .handle_radarr_event(RadarrEvent::GetMovieDetails(None))
@@ -1523,7 +1533,7 @@ mod test {
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
app_arc.lock().await.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default()); app_arc.lock().await.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::MovieHistoryItems(history) = network if let RadarrSerdeable::MovieHistoryItems(history) = network
.handle_radarr_event(RadarrEvent::GetMovieHistory(None)) .handle_radarr_event(RadarrEvent::GetMovieHistory(None))
@@ -1571,7 +1581,7 @@ mod test {
&resource, &resource,
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::MovieHistoryItems(history) = network if let RadarrSerdeable::MovieHistoryItems(history) = network
.handle_radarr_event(RadarrEvent::GetMovieHistory(Some(1))) .handle_radarr_event(RadarrEvent::GetMovieHistory(Some(1)))
@@ -1611,7 +1621,7 @@ mod test {
.radarr_data .radarr_data
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetMovieHistory(None)) .handle_radarr_event(RadarrEvent::GetMovieHistory(None))
@@ -1760,7 +1770,7 @@ mod test {
.blocklist .blocklist
.sorting(vec![blocklist_sort_option]); .sorting(vec![blocklist_sort_option]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::BlocklistResponse(blocklist) = network if let RadarrSerdeable::BlocklistResponse(blocklist) = network
.handle_radarr_event(RadarrEvent::GetBlocklist) .handle_radarr_event(RadarrEvent::GetBlocklist)
@@ -1881,7 +1891,7 @@ mod test {
.radarr_data .radarr_data
.blocklist .blocklist
.sorting(vec![blocklist_sort_option]); .sorting(vec![blocklist_sort_option]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetBlocklist) .handle_radarr_event(RadarrEvent::GetBlocklist)
@@ -2004,7 +2014,7 @@ mod test {
.collections .collections
.sorting(vec![collection_sort_option]); .sorting(vec![collection_sort_option]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Collections(collections) = network if let RadarrSerdeable::Collections(collections) = network
.handle_radarr_event(RadarrEvent::GetCollections) .handle_radarr_event(RadarrEvent::GetCollections)
@@ -2111,7 +2121,7 @@ mod test {
.radarr_data .radarr_data
.collections .collections
.sorting(vec![collection_sort_option]); .sorting(vec![collection_sort_option]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetCollections) .handle_radarr_event(RadarrEvent::GetCollections)
@@ -2155,7 +2165,7 @@ mod test {
RadarrEvent::GetDownloads.resource(), RadarrEvent::GetDownloads.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::DownloadsResponse(downloads) = network if let RadarrSerdeable::DownloadsResponse(downloads) = network
.handle_radarr_event(RadarrEvent::GetDownloads) .handle_radarr_event(RadarrEvent::GetDownloads)
@@ -2171,6 +2181,40 @@ mod test {
} }
} }
#[tokio::test]
async fn test_handle_get_host_config_event() {
let host_config_response = json!({
"bindAddress": "*",
"port": 7878,
"urlBase": "some.test.site/radarr",
"instanceName": "Radarr",
"applicationUrl": "https://some.test.site:7878/radarr",
"enableSsl": true,
"sslPort": 9898,
"sslCertPath": "/app/radarr.pfx",
"sslCertPassword": "test"
});
let response: HostConfig = serde_json::from_value(host_config_response.clone()).unwrap();
let (async_server, app_arc, _server) = mock_radarr_api(
RequestMethod::Get,
None,
Some(host_config_response),
None,
RadarrEvent::GetHostConfig.resource(),
)
.await;
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::HostConfig(host_config) = network
.handle_radarr_event(RadarrEvent::GetHostConfig)
.await
.unwrap()
{
async_server.assert_async().await;
assert_eq!(host_config, response);
}
}
#[tokio::test] #[tokio::test]
async fn test_handle_get_indexers_event() { async fn test_handle_get_indexers_event() {
let indexers_response_json = json!([{ let indexers_response_json = json!([{
@@ -2212,7 +2256,7 @@ mod test {
RadarrEvent::GetIndexers.resource(), RadarrEvent::GetIndexers.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Indexers(indexers) = network if let RadarrSerdeable::Indexers(indexers) = network
.handle_radarr_event(RadarrEvent::GetIndexers) .handle_radarr_event(RadarrEvent::GetIndexers)
@@ -2251,7 +2295,7 @@ mod test {
RadarrEvent::GetAllIndexerSettings.resource(), RadarrEvent::GetAllIndexerSettings.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::IndexerSettings(settings) = network if let RadarrSerdeable::IndexerSettings(settings) = network
.handle_radarr_event(RadarrEvent::GetAllIndexerSettings) .handle_radarr_event(RadarrEvent::GetAllIndexerSettings)
@@ -2289,7 +2333,7 @@ mod test {
) )
.await; .await;
app_arc.lock().await.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app_arc.lock().await.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetAllIndexerSettings) .handle_radarr_event(RadarrEvent::GetAllIndexerSettings)
@@ -2336,7 +2380,7 @@ mod test {
RadarrEvent::GetQueuedEvents.resource(), RadarrEvent::GetQueuedEvents.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::QueueEvents(events) = network if let RadarrSerdeable::QueueEvents(events) = network
.handle_radarr_event(RadarrEvent::GetQueuedEvents) .handle_radarr_event(RadarrEvent::GetQueuedEvents)
@@ -2397,7 +2441,7 @@ mod test {
&resource, &resource,
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::LogResponse(logs) = network if let RadarrSerdeable::LogResponse(logs) = network
.handle_radarr_event(RadarrEvent::GetLogs(None)) .handle_radarr_event(RadarrEvent::GetLogs(None))
@@ -2467,7 +2511,7 @@ mod test {
&resource, &resource,
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::LogResponse(logs) = network if let RadarrSerdeable::LogResponse(logs) = network
.handle_radarr_event(RadarrEvent::GetLogs(Some(1000))) .handle_radarr_event(RadarrEvent::GetLogs(Some(1000)))
@@ -2508,7 +2552,7 @@ mod test {
RadarrEvent::GetQualityProfiles.resource(), RadarrEvent::GetQualityProfiles.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::QualityProfiles(quality_profiles) = network if let RadarrSerdeable::QualityProfiles(quality_profiles) = network
.handle_radarr_event(RadarrEvent::GetQualityProfiles) .handle_radarr_event(RadarrEvent::GetQualityProfiles)
@@ -2539,7 +2583,7 @@ mod test {
RadarrEvent::GetTags.resource(), RadarrEvent::GetTags.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Tags(tags) = network if let RadarrSerdeable::Tags(tags) = network
.handle_radarr_event(RadarrEvent::GetTags) .handle_radarr_event(RadarrEvent::GetTags)
@@ -2601,7 +2645,7 @@ mod test {
RadarrEvent::GetTasks.resource(), RadarrEvent::GetTasks.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Tasks(tasks) = network if let RadarrSerdeable::Tasks(tasks) = network
.handle_radarr_event(RadarrEvent::GetTasks) .handle_radarr_event(RadarrEvent::GetTasks)
@@ -2694,7 +2738,7 @@ mod test {
RadarrEvent::GetUpdates.resource(), RadarrEvent::GetUpdates.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Updates(updates) = network if let RadarrSerdeable::Updates(updates) = network
.handle_radarr_event(RadarrEvent::GetUpdates) .handle_radarr_event(RadarrEvent::GetUpdates)
@@ -2711,7 +2755,7 @@ mod test {
} }
#[tokio::test] #[tokio::test]
async fn test_add_tag() { async fn test_handle_add_tag() {
let tag_json = json!({ "id": 3, "label": "testing" }); let tag_json = json!({ "id": 3, "label": "testing" });
let response: Tag = serde_json::from_value(tag_json.clone()).unwrap(); let response: Tag = serde_json::from_value(tag_json.clone()).unwrap();
let (async_server, app_arc, _server) = mock_radarr_api( let (async_server, app_arc, _server) = mock_radarr_api(
@@ -2724,7 +2768,7 @@ mod test {
.await; .await;
app_arc.lock().await.data.radarr_data.tags_map = app_arc.lock().await.data.radarr_data.tags_map =
BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]); BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Tag(tag) = network if let RadarrSerdeable::Tag(tag) = network
.handle_radarr_event(RadarrEvent::AddTag("testing".to_owned())) .handle_radarr_event(RadarrEvent::AddTag("testing".to_owned()))
@@ -2749,7 +2793,7 @@ mod test {
let resource = format!("{}/1", RadarrEvent::DeleteTag(1).resource()); let resource = format!("{}/1", RadarrEvent::DeleteTag(1).resource());
let (async_server, app_arc, _server) = let (async_server, app_arc, _server) =
mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await; mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteTag(1)) .handle_radarr_event(RadarrEvent::DeleteTag(1))
@@ -2776,7 +2820,7 @@ mod test {
RadarrEvent::GetRootFolders.resource(), RadarrEvent::GetRootFolders.resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::RootFolders(root_folders) = network if let RadarrSerdeable::RootFolders(root_folders) = network
.handle_radarr_event(RadarrEvent::GetRootFolders) .handle_radarr_event(RadarrEvent::GetRootFolders)
@@ -2792,6 +2836,38 @@ mod test {
} }
} }
#[tokio::test]
async fn test_handle_get_security_config_event() {
let security_config_response = json!({
"authenticationMethod": "forms",
"authenticationRequired": "disabledForLocalAddresses",
"username": "test",
"password": "some password",
"apiKey": "someApiKey12345",
"certificateValidation": "disabledForLocalAddresses",
});
let response: SecurityConfig =
serde_json::from_value(security_config_response.clone()).unwrap();
let (async_server, app_arc, _server) = mock_radarr_api(
RequestMethod::Get,
None,
Some(security_config_response),
None,
RadarrEvent::GetSecurityConfig.resource(),
)
.await;
let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::SecurityConfig(security_config) = network
.handle_radarr_event(RadarrEvent::GetSecurityConfig)
.await
.unwrap()
{
async_server.assert_async().await;
assert_eq!(security_config, response);
}
}
#[tokio::test] #[tokio::test]
async fn test_handle_get_movie_credits_event() { async fn test_handle_get_movie_credits_event() {
let credits_json = json!([ let credits_json = json!([
@@ -2828,7 +2904,7 @@ mod test {
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
app_arc.lock().await.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default()); app_arc.lock().await.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Credits(credits) = network if let RadarrSerdeable::Credits(credits) = network
.handle_radarr_event(RadarrEvent::GetMovieCredits(None)) .handle_radarr_event(RadarrEvent::GetMovieCredits(None))
@@ -2873,7 +2949,7 @@ mod test {
&resource, &resource,
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
if let RadarrSerdeable::Credits(credits) = network if let RadarrSerdeable::Credits(credits) = network
.handle_radarr_event(RadarrEvent::GetMovieCredits(Some(1))) .handle_radarr_event(RadarrEvent::GetMovieCredits(Some(1)))
@@ -2919,7 +2995,7 @@ mod test {
.radarr_data .radarr_data
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::GetMovieCredits(None)) .handle_radarr_event(RadarrEvent::GetMovieCredits(None))
@@ -2948,7 +3024,7 @@ mod test {
app.data.radarr_data.delete_movie_files = true; app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true; app.data.radarr_data.add_list_exclusion = true;
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteMovie(None)) .handle_radarr_event(RadarrEvent::DeleteMovie(None))
@@ -2968,7 +3044,7 @@ mod test {
); );
let (async_server, app_arc, _server) = let (async_server, app_arc, _server) =
mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await; mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let delete_movie_params = DeleteMovieParams { let delete_movie_params = DeleteMovieParams {
id: 1, id: 1,
delete_movie_files: true, delete_movie_files: true,
@@ -3017,7 +3093,7 @@ mod test {
.radarr_data .radarr_data
.blocklist .blocklist
.set_items(blocklist_items); .set_items(blocklist_items);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::ClearBlocklist) .handle_radarr_event(RadarrEvent::ClearBlocklist)
@@ -3039,7 +3115,7 @@ mod test {
.radarr_data .radarr_data
.blocklist .blocklist
.set_items(vec![blocklist_item()]); .set_items(vec![blocklist_item()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteBlocklistItem(None)) .handle_radarr_event(RadarrEvent::DeleteBlocklistItem(None))
@@ -3054,7 +3130,7 @@ mod test {
let resource = format!("{}/1", RadarrEvent::DeleteBlocklistItem(None).resource()); let resource = format!("{}/1", RadarrEvent::DeleteBlocklistItem(None).resource());
let (async_server, app_arc, _server) = let (async_server, app_arc, _server) =
mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await; mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteBlocklistItem(Some(1))) .handle_radarr_event(RadarrEvent::DeleteBlocklistItem(Some(1)))
@@ -3076,7 +3152,7 @@ mod test {
.radarr_data .radarr_data
.downloads .downloads
.set_items(vec![download_record()]); .set_items(vec![download_record()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteDownload(None)) .handle_radarr_event(RadarrEvent::DeleteDownload(None))
@@ -3091,7 +3167,7 @@ mod test {
let resource = format!("{}/1", RadarrEvent::DeleteDownload(None).resource()); let resource = format!("{}/1", RadarrEvent::DeleteDownload(None).resource());
let (async_server, app_arc, _server) = let (async_server, app_arc, _server) =
mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await; mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteDownload(Some(1))) .handle_radarr_event(RadarrEvent::DeleteDownload(Some(1)))
@@ -3113,7 +3189,7 @@ mod test {
.radarr_data .radarr_data
.indexers .indexers
.set_items(vec![indexer()]); .set_items(vec![indexer()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteIndexer(None)) .handle_radarr_event(RadarrEvent::DeleteIndexer(None))
@@ -3128,7 +3204,7 @@ mod test {
let resource = format!("{}/1", RadarrEvent::DeleteIndexer(None).resource()); let resource = format!("{}/1", RadarrEvent::DeleteIndexer(None).resource());
let (async_server, app_arc, _server) = let (async_server, app_arc, _server) =
mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await; mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteIndexer(Some(1))) .handle_radarr_event(RadarrEvent::DeleteIndexer(Some(1)))
@@ -3150,7 +3226,7 @@ mod test {
.radarr_data .radarr_data
.root_folders .root_folders
.set_items(vec![root_folder()]); .set_items(vec![root_folder()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteRootFolder(None)) .handle_radarr_event(RadarrEvent::DeleteRootFolder(None))
@@ -3165,7 +3241,7 @@ mod test {
let resource = format!("{}/1", RadarrEvent::DeleteRootFolder(None).resource()); let resource = format!("{}/1", RadarrEvent::DeleteRootFolder(None).resource());
let (async_server, app_arc, _server) = let (async_server, app_arc, _server) =
mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await; mock_radarr_api(RequestMethod::Delete, None, None, None, &resource).await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DeleteRootFolder(Some(1))) .handle_radarr_event(RadarrEvent::DeleteRootFolder(Some(1)))
@@ -3249,7 +3325,7 @@ mod test {
app.data.radarr_data.add_searched_movies = Some(add_searched_movies); app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
} }
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::AddMovie(None)) .handle_radarr_event(RadarrEvent::AddMovie(None))
@@ -3302,7 +3378,7 @@ mod test {
}, },
}; };
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::AddMovie(Some(body))) .handle_radarr_event(RadarrEvent::AddMovie(Some(body)))
@@ -3388,7 +3464,7 @@ mod test {
add_searched_movies.scroll_to_bottom(); add_searched_movies.scroll_to_bottom();
app.data.radarr_data.add_searched_movies = Some(add_searched_movies); app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::AddMovie(None)) .handle_radarr_event(RadarrEvent::AddMovie(None))
@@ -3432,7 +3508,7 @@ mod test {
.await; .await;
app_arc.lock().await.data.radarr_data.edit_root_folder = Some("/nfs/test".into()); app_arc.lock().await.data.radarr_data.edit_root_folder = Some("/nfs/test".into());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::AddRootFolder(None)) .handle_radarr_event(RadarrEvent::AddRootFolder(None))
@@ -3462,7 +3538,7 @@ mod test {
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::AddRootFolder(Some("/test/test".to_owned()))) .handle_radarr_event(RadarrEvent::AddRootFolder(Some("/test/test".to_owned())))
@@ -3502,7 +3578,7 @@ mod test {
.await; .await;
app_arc.lock().await.data.radarr_data.indexer_settings = Some(indexer_settings()); app_arc.lock().await.data.radarr_data.indexer_settings = Some(indexer_settings());
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditAllIndexerSettings(None)) .handle_radarr_event(RadarrEvent::EditAllIndexerSettings(None))
@@ -3541,7 +3617,7 @@ mod test {
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditAllIndexerSettings( .handle_radarr_event(RadarrEvent::EditAllIndexerSettings(
@@ -3639,7 +3715,7 @@ mod test {
app.data.radarr_data.quality_profile_map = app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]); BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditCollection(None)) .handle_radarr_event(RadarrEvent::EditCollection(None))
@@ -3724,7 +3800,7 @@ mod test {
root_folder_path: Some("/nfs/Test Path".to_owned()), root_folder_path: Some("/nfs/Test Path".to_owned()),
search_on_add: Some(false), search_on_add: Some(false),
}; };
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditCollection(Some(edit_collection_params))) .handle_radarr_event(RadarrEvent::EditCollection(Some(edit_collection_params)))
@@ -3803,7 +3879,7 @@ mod test {
collection_id: 123, collection_id: 123,
..EditCollectionParams::default() ..EditCollectionParams::default()
}; };
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditCollection(Some(edit_collection_params))) .handle_radarr_event(RadarrEvent::EditCollection(Some(edit_collection_params)))
@@ -3899,7 +3975,7 @@ mod test {
app.data.radarr_data.edit_indexer_modal = Some(edit_indexer_modal); app.data.radarr_data.edit_indexer_modal = Some(edit_indexer_modal);
app.data.radarr_data.indexers.set_items(vec![indexer()]); app.data.radarr_data.indexers.set_items(vec![indexer()]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditIndexer(None)) .handle_radarr_event(RadarrEvent::EditIndexer(None))
@@ -4000,7 +4076,7 @@ mod test {
); );
app.data.radarr_data.indexers.set_items(vec![indexer]); app.data.radarr_data.indexers.set_items(vec![indexer]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditIndexer(None)) .handle_radarr_event(RadarrEvent::EditIndexer(None))
@@ -4115,7 +4191,7 @@ mod test {
); );
app.data.radarr_data.indexers.set_items(vec![indexer]); app.data.radarr_data.indexers.set_items(vec![indexer]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditIndexer(None)) .handle_radarr_event(RadarrEvent::EditIndexer(None))
@@ -4210,7 +4286,7 @@ mod test {
.match_body(Matcher::Json(expected_indexer_edit_body_json)) .match_body(Matcher::Json(expected_indexer_edit_body_json))
.create_async() .create_async()
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditIndexer(Some(edit_indexer_params))) .handle_radarr_event(RadarrEvent::EditIndexer(Some(edit_indexer_params)))
@@ -4270,7 +4346,7 @@ mod test {
.match_body(Matcher::Json(indexer_details_json)) .match_body(Matcher::Json(indexer_details_json))
.create_async() .create_async()
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditIndexer(Some(edit_indexer_params))) .handle_radarr_event(RadarrEvent::EditIndexer(Some(edit_indexer_params)))
@@ -4355,7 +4431,7 @@ mod test {
.match_body(Matcher::Json(expected_edit_indexer_body)) .match_body(Matcher::Json(expected_edit_indexer_body))
.create_async() .create_async()
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditIndexer(Some(edit_indexer_params))) .handle_radarr_event(RadarrEvent::EditIndexer(Some(edit_indexer_params)))
@@ -4418,7 +4494,7 @@ mod test {
app.data.radarr_data.quality_profile_map = app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]); BiMap::from_iter([(1111, "Any".to_owned()), (2222, "HD - 1080p".to_owned())]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditMovie(None)) .handle_radarr_event(RadarrEvent::EditMovie(None))
@@ -4469,7 +4545,7 @@ mod test {
tags: Some(vec![1, 2]), tags: Some(vec![1, 2]),
..EditMovieParams::default() ..EditMovieParams::default()
}; };
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditMovie(Some(edit_movie_params))) .handle_radarr_event(RadarrEvent::EditMovie(Some(edit_movie_params)))
@@ -4506,7 +4582,7 @@ mod test {
movie_id: 1, movie_id: 1,
..EditMovieParams::default() ..EditMovieParams::default()
}; };
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditMovie(Some(edit_movie_params))) .handle_radarr_event(RadarrEvent::EditMovie(Some(edit_movie_params)))
@@ -4547,7 +4623,7 @@ mod test {
clear_tags: true, clear_tags: true,
..EditMovieParams::default() ..EditMovieParams::default()
}; };
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::EditMovie(Some(edit_movie_params))) .handle_radarr_event(RadarrEvent::EditMovie(Some(edit_movie_params)))
@@ -4584,7 +4660,7 @@ mod test {
.radarr_data .radarr_data
.movies .movies
.set_items(vec![movie()]); .set_items(vec![movie()]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert!(network assert!(network
.handle_radarr_event(RadarrEvent::DownloadRelease(None)) .handle_radarr_event(RadarrEvent::DownloadRelease(None))
@@ -4608,7 +4684,7 @@ mod test {
RadarrEvent::DownloadRelease(None).resource(), RadarrEvent::DownloadRelease(None).resource(),
) )
.await; .await;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let params = ReleaseDownloadBody { let params = ReleaseDownloadBody {
guid: "1234".to_owned(), guid: "1234".to_owned(),
indexer_id: 2, indexer_id: 2,
@@ -4635,7 +4711,7 @@ mod test {
(3, "hi".to_owned()), (3, "hi".to_owned()),
]); ]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert_eq!( assert_eq!(
network.extract_and_add_tag_ids_vec(tags).await, network.extract_and_add_tag_ids_vec(tags).await,
@@ -4663,7 +4739,7 @@ mod test {
app.data.radarr_data.tags_map = app.data.radarr_data.tags_map =
BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]); BiMap::from_iter([(1, "usenet".to_owned()), (2, "test".to_owned())]);
} }
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let tag_ids_vec = network.extract_and_add_tag_ids_vec(tags).await; let tag_ids_vec = network.extract_and_add_tag_ids_vec(tags).await;
@@ -4692,7 +4768,7 @@ mod test {
id: 1, id: 1,
..Movie::default() ..Movie::default()
}]); }]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert_eq!(network.extract_movie_id().await, 1); assert_eq!(network.extract_movie_id().await, 1);
} }
@@ -4706,7 +4782,7 @@ mod test {
..Movie::default() ..Movie::default()
}]); }]);
app_arc.lock().await.data.radarr_data.movies = filtered_movies; app_arc.lock().await.data.radarr_data.movies = filtered_movies;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert_eq!(network.extract_movie_id().await, 1); assert_eq!(network.extract_movie_id().await, 1);
} }
@@ -4724,7 +4800,7 @@ mod test {
id: 1, id: 1,
..Collection::default() ..Collection::default()
}]); }]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert_eq!(network.extract_collection_id().await, 1); assert_eq!(network.extract_collection_id().await, 1);
} }
@@ -4738,7 +4814,7 @@ mod test {
..Collection::default() ..Collection::default()
}]); }]);
app_arc.lock().await.data.radarr_data.collections = filtered_collections; app_arc.lock().await.data.radarr_data.collections = filtered_collections;
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert_eq!(network.extract_collection_id().await, 1); assert_eq!(network.extract_collection_id().await, 1);
} }
@@ -4756,7 +4832,7 @@ mod test {
id: 1, id: 1,
..Movie::default() ..Movie::default()
}]); }]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert_str_eq!( assert_str_eq!(
network.append_movie_id_param("/test", None).await, network.append_movie_id_param("/test", None).await,
@@ -4777,7 +4853,7 @@ mod test {
id: 1, id: 1,
..Movie::default() ..Movie::default()
}]); }]);
let mut network = Network::new(&app_arc, CancellationToken::new()); let mut network = Network::new(&app_arc, CancellationToken::new(), Client::new());
assert_str_eq!( assert_str_eq!(
network.append_movie_id_param("/test", Some(11)).await, network.append_movie_id_param("/test", Some(11)).await,
@@ -4788,7 +4864,7 @@ mod test {
#[tokio::test] #[tokio::test]
async fn test_radarr_request_props_from_default_radarr_config() { async fn test_radarr_request_props_from_default_radarr_config() {
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::default()));
let network = Network::new(&app_arc, CancellationToken::new()); let network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let request_props = network let request_props = network
.radarr_request_props_from("/test", RequestMethod::Get, None::<()>) .radarr_request_props_from("/test", RequestMethod::Get, None::<()>)
@@ -4803,6 +4879,8 @@ mod test {
host: "192.168.0.123".to_owned(), host: "192.168.0.123".to_owned(),
port: Some(8080), port: Some(8080),
api_token: "testToken1234".to_owned(), api_token: "testToken1234".to_owned(),
use_ssl: false,
ssl_cert_path: None,
}; };
} }
@@ -4814,14 +4892,16 @@ mod test {
host: "192.168.0.123".to_owned(), host: "192.168.0.123".to_owned(),
port: Some(8080), port: Some(8080),
api_token: api_token.clone(), api_token: api_token.clone(),
use_ssl: true,
ssl_cert_path: None,
}; };
let network = Network::new(&app_arc, CancellationToken::new()); let network = Network::new(&app_arc, CancellationToken::new(), Client::new());
let request_props = network let request_props = network
.radarr_request_props_from("/test", RequestMethod::Get, None::<()>) .radarr_request_props_from("/test", RequestMethod::Get, None::<()>)
.await; .await;
assert_str_eq!(request_props.uri, "http://192.168.0.123:8080/api/v3/test"); assert_str_eq!(request_props.uri, "https://192.168.0.123:8080/api/v3/test");
assert_eq!(request_props.method, RequestMethod::Get); assert_eq!(request_props.method, RequestMethod::Get);
assert_eq!(request_props.body, None); assert_eq!(request_props.body, None);
assert_str_eq!(request_props.api_token, api_token); assert_str_eq!(request_props.api_token, api_token);
@@ -4917,6 +4997,8 @@ mod test {
host, host,
port, port,
api_token: "test1234".to_owned(), api_token: "test1234".to_owned(),
use_ssl: false,
ssl_cert_path: None,
}; };
app.config.radarr = radarr_config; app.config.radarr = radarr_config;
let app_arc = Arc::new(Mutex::new(app)); let app_arc = Arc::new(Mutex::new(app));