From 2e2dfa3a46d7c8611a93a2288051fd9a4b66f51d Mon Sep 17 00:00:00 2001 From: Chip Senkbeil Date: Sun, 29 Aug 2021 19:39:37 -0500 Subject: [PATCH] Add cli metadata tests --- tests/cli/action/metadata.rs | 265 +++++++++++++++++++++++++++++++++++ tests/cli/action/mod.rs | 1 + tests/cli/utils.rs | 7 +- 3 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 tests/cli/action/metadata.rs diff --git a/tests/cli/action/metadata.rs b/tests/cli/action/metadata.rs new file mode 100644 index 0000000..9a33f59 --- /dev/null +++ b/tests/cli/action/metadata.rs @@ -0,0 +1,265 @@ +use crate::cli::{ + fixtures::*, + utils::{random_tenant, regex_pred, FAILURE_LINE}, +}; +use assert_cmd::Command; +use assert_fs::prelude::*; +use distant::ExitCode; +use distant_core::{ + data::{Error, ErrorKind, FileType}, + Request, RequestData, Response, ResponseData, +}; +use rstest::*; + +const FILE_CONTENTS: &str = r#" +some text +on multiple lines +that is a file's contents +"#; + +#[rstest] +fn should_output_metadata_for_file(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + let file = temp.child("file"); + file.write_str(FILE_CONTENTS).unwrap(); + + // distant action metdata {path} + action_cmd + .args(&["metadata", file.to_str().unwrap()]) + .assert() + .success() + .stdout(regex_pred(concat!( + "Type: file\n", + "Len: .*\n", + "Readonly: false\n", + "Created: .*\n", + "Last Accessed: .*\n", + "Last Modified: .*\n", + ))) + .stderr(""); +} + +#[rstest] +fn should_output_metadata_for_directory(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + let dir = temp.child("dir"); + dir.create_dir_all().unwrap(); + + // distant action metadata {path} + action_cmd + .args(&["metadata", dir.to_str().unwrap()]) + .assert() + .success() + .stdout(regex_pred(concat!( + "Type: dir\n", + "Len: .*\n", + "Readonly: false\n", + "Created: .*\n", + "Last Accessed: .*\n", + "Last Modified: .*\n", + ))) + .stderr(""); +} + +#[rstest] +fn should_support_including_a_canonicalized_path(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + let file = temp.child("file"); + file.touch().unwrap(); + + // distant action metdata --canonicalize {path} + action_cmd + .args(&["metadata", "--canonicalize", file.to_str().unwrap()]) + .assert() + .success() + .stdout(regex_pred(concat!( + "Type: file\n", + "Len: .*\n", + "Readonly: false\n", + "Created: .*\n", + "Last Accessed: .*\n", + "Last Modified: .*\n", + ))) + .stderr(""); +} + +#[rstest] +fn yield_an_error_when_fails(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + // Don't create file + let file = temp.child("file"); + + // distant action metadata {path} + action_cmd + .args(&["metadata", file.to_str().unwrap()]) + .assert() + .code(ExitCode::Software.to_i32()) + .stdout("") + .stderr(FAILURE_LINE.clone()); +} + +#[rstest] +fn should_support_json_metadata_for_file(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + let file = temp.child("file"); + file.write_str(FILE_CONTENTS).unwrap(); + + let req = Request { + id: rand::random(), + tenant: random_tenant(), + payload: vec![RequestData::Metadata { + path: file.to_path_buf(), + canonicalize: false, + }], + }; + + // distant action --format json --interactive + let cmd = action_cmd + .args(&["--format", "json"]) + .arg("--interactive") + .write_stdin(format!("{}\n", serde_json::to_string(&req).unwrap())) + .assert() + .success() + .stderr(""); + + let res: Response = serde_json::from_slice(&cmd.get_output().stdout).unwrap(); + assert!( + matches!( + res.payload[0], + ResponseData::Metadata { + canonicalized_path: None, + file_type: FileType::File, + readonly: false, + .. + }, + ), + "Unexpected response: {:?}", + res.payload[0], + ); +} + +#[rstest] +fn should_support_json_metadata_for_directory(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + let dir = temp.child("dir"); + dir.create_dir_all().unwrap(); + + let req = Request { + id: rand::random(), + tenant: random_tenant(), + payload: vec![RequestData::Metadata { + path: dir.to_path_buf(), + canonicalize: false, + }], + }; + + // distant action --format json --interactive + let cmd = action_cmd + .args(&["--format", "json"]) + .arg("--interactive") + .write_stdin(format!("{}\n", serde_json::to_string(&req).unwrap())) + .assert() + .success() + .stderr(""); + + let res: Response = serde_json::from_slice(&cmd.get_output().stdout).unwrap(); + assert!( + matches!( + res.payload[0], + ResponseData::Metadata { + canonicalized_path: None, + file_type: FileType::Dir, + readonly: false, + .. + }, + ), + "Unexpected response: {:?}", + res.payload[0], + ); +} + +#[rstest] +fn should_support_json_metadata_for_including_a_canonicalized_path(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + let file = temp.child("file"); + file.touch().unwrap(); + + let req = Request { + id: rand::random(), + tenant: random_tenant(), + payload: vec![RequestData::Metadata { + path: file.to_path_buf(), + canonicalize: true, + }], + }; + + // distant action --format json --interactive + let cmd = action_cmd + .args(&["--format", "json"]) + .arg("--interactive") + .write_stdin(format!("{}\n", serde_json::to_string(&req).unwrap())) + .assert() + .success() + .stderr(""); + + let res: Response = serde_json::from_slice(&cmd.get_output().stdout).unwrap(); + assert!( + matches!( + res.payload[0], + ResponseData::Metadata { + canonicalized_path: Some(_), + file_type: FileType::File, + readonly: false, + .. + }, + ), + "Unexpected response: {:?}", + res.payload[0], + ); +} + +#[rstest] +fn should_support_json_output_for_error(mut action_cmd: Command) { + let temp = assert_fs::TempDir::new().unwrap(); + + // Don't create file + let file = temp.child("file"); + + let req = Request { + id: rand::random(), + tenant: random_tenant(), + payload: vec![RequestData::Metadata { + path: file.to_path_buf(), + canonicalize: false, + }], + }; + + // distant action --format json --interactive + let cmd = action_cmd + .args(&["--format", "json"]) + .arg("--interactive") + .write_stdin(format!("{}\n", serde_json::to_string(&req).unwrap())) + .assert() + .success() + .stderr(""); + + let res: Response = serde_json::from_slice(&cmd.get_output().stdout).unwrap(); + assert!( + matches!( + res.payload[0], + ResponseData::Error(Error { + kind: ErrorKind::NotFound, + .. + }) + ), + "Unexpected response: {:?}", + res.payload[0] + ); +} diff --git a/tests/cli/action/mod.rs b/tests/cli/action/mod.rs index ef457c4..302b8d8 100644 --- a/tests/cli/action/mod.rs +++ b/tests/cli/action/mod.rs @@ -8,5 +8,6 @@ mod file_read; mod file_read_text; mod file_write; mod file_write_text; +mod metadata; mod remove; mod rename; diff --git a/tests/cli/utils.rs b/tests/cli/utils.rs index c707425..8fd1f8f 100644 --- a/tests/cli/utils.rs +++ b/tests/cli/utils.rs @@ -3,7 +3,12 @@ use predicates::prelude::*; lazy_static::lazy_static! { /// Predicate that checks for a single line that is a failure pub static ref FAILURE_LINE: predicates::str::RegexPredicate = - predicate::str::is_match(r"^Failed \(.*\): '.*'\.\n$").unwrap(); + regex_pred(r"^Failed \(.*\): '.*'\.\n$"); +} + +/// Produces a regex predicate using the given string +pub fn regex_pred(s: &str) -> predicates::str::RegexPredicate { + predicate::str::is_match(s).unwrap() } /// Creates a random tenant name