diff --git a/src/album.rs b/src/album.rs index c51b1d9..9fdbd4a 100644 --- a/src/album.rs +++ b/src/album.rs @@ -2,7 +2,7 @@ use serde::Deserialize; use serde_json::{from_str, json}; use tabled::Tabled; use hyper::{Method, Request, body::Body, header::{AUTHORIZATION, CONTENT_TYPE, COOKIE}}; -use crate::{LycheeClient, utils::{display_option_string, body_to_str}}; +use crate::{LycheeClient, utils::{body_to_str, display_option_string, numeric_validator}}; #[derive(Deserialize, Debug, Tabled)] pub struct Album { @@ -67,9 +67,27 @@ pub async fn add_album(c: &LycheeClient, lychee_session: &str, title: &str, pare let s = res.status(); let b = body_to_str(res.into_body()).await; assert_ne!(s, 500, "The server returned an internal error."); + assert!(numeric_validator(b.clone()).is_ok(), "The server didn't return a numeric value, instead returned {}.", b); return b; } +pub async fn delete_album(c: &LycheeClient, lychee_session: &str, id: &str) { + let b = json!({"albumIDs" : id}); + let req = Request::builder() + .method(Method::POST) + .uri(c.endpoint.to_string() + "/api/Album::delete") + .header(COOKIE, lychee_session) + .header(AUTHORIZATION, c.api_key.to_string()) + .header(CONTENT_TYPE, "application/json") + .body(Body::from(b.to_string())) + .expect("Cannot request /api/Album:delete."); + let res = c.client.request(req).await.unwrap(); + let s = res.status(); + let b = body_to_str(res.into_body()).await; + assert_ne!(s, 500, "The server returned an internal error."); + assert_eq!(b, "true", "The server returned an unexpected value: {}.", b); +} + #[cfg(test)] mod album_tests { use hyper_tls::HttpsConnector; @@ -78,7 +96,7 @@ mod album_tests { use serde_json::json; use crate::{LycheeClient, get_album}; - use super::add_album; + use super::{add_album, delete_album}; fn setup() -> LycheeClient { let https = HttpsConnector::new(); @@ -89,6 +107,44 @@ mod album_tests { }; } + #[test] + fn delete_album_correct_values() { + let client = setup(); + let m1 = mock("POST", "/api/Album::delete") + .match_header("cookie", "v") + .match_header("content-type", "application/json") + .with_body("true") + .match_body(json!({"albumIDs": "1"}).to_string().as_str()) + .create(); + + tokio_test::block_on(delete_album(&client, "v", "1")); + m1.assert(); + + let m2 = mock("POST", "/api/Album::delete") + .match_header("cookie", "v") + .match_header("content-type", "application/json") + .with_body("true") + .match_body(json!({"albumIDs": "1,2,3"}).to_string().as_str()) + .create(); + + tokio_test::block_on(delete_album(&client, "v", "1,2,3")); + m2.assert(); + } + + #[test] + #[should_panic] + fn delete_album_false_returned() { + let client = setup(); + let m = mock("POST", "/api/Album::delete") + .match_header("cookie", "v") + .match_header("content-type", "application/json") + .with_body("false") + .create(); + + tokio_test::block_on(delete_album(&client, "v", "1")); + m.assert(); + } + #[test] #[should_panic] fn add_album_title_too_long() { diff --git a/src/main.rs b/src/main.rs index a7a4a52..e539ddf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use crate::{album::{add_album, get_album}, albums::get_albums, config::{get_session_file, read_config, setup_config_data_storage}, session::login, utils::{body_to_str, numeric_validator, read_from_file, write_to_file}}; +use crate::{album::{add_album, delete_album, get_album}, albums::get_albums, config::{get_session_file, read_config, setup_config_data_storage}, session::login, utils::{body_to_str, numeric_validator, read_from_file, write_to_file}}; use hyper_tls::HttpsConnector; use hyper::{Client, client::HttpConnector}; use clap::{App, Arg, SubCommand, crate_version}; @@ -28,7 +28,7 @@ async fn main() -> Result<(), Box> { .about("A Lychee CLI client written in Rust.") .subcommand( SubCommand::with_name("login") - .about("Log into a Lychee instance") + .about("Log into a Lychee instance.") .arg(Arg::with_name("username") .long("username") .short("u") @@ -52,7 +52,7 @@ async fn main() -> Result<(), Box> { ) .subcommand( SubCommand::with_name("get_album") - .about("Query some information on a given album") + .about("Query some information on a given album.") .arg(Arg::with_name("id") .long("id") .short("i") @@ -71,6 +71,16 @@ async fn main() -> Result<(), Box> { .arg(Arg::with_name("parent_id") .long("parent").short("p").help("The parent id for the album to create.") .value_name("PARENT_ID").validator(numeric_validator)) + ) + .subcommand( + SubCommand::with_name("delete_album") + .about("Delete an album.") + .arg(Arg::with_name("id") + .short("i") + .long("id") + .help("The album ID to delete. For multiple IDs, separate them using commas.") + .required(true) + .value_name("ID(s)")) ); let matches = app.clone().get_matches(); @@ -105,6 +115,9 @@ async fn main() -> Result<(), Box> { let parent_id = if m.is_present("parent_id") { Some(m.value_of("parent_id").unwrap().parse::().unwrap()) } else {None}; let a = add_album(&client, &lychee_session_cookie, title, parent_id).await; println!("{}", a); + } else if let Some(m) = matches.subcommand_matches("delete_album") { + let id = m.value_of("id").unwrap(); + delete_album(&client, &lychee_session_cookie, id).await; } else { App::print_long_help(&mut app).unwrap(); }