Added unit and integration tests
This commit is contained in:
Generated
+24
@@ -475,6 +475,12 @@ dependencies = [
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@@ -651,12 +657,14 @@ dependencies = [
|
||||
"indoc",
|
||||
"log",
|
||||
"log4rs",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"rpassword",
|
||||
"secrecy",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_with",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"validator",
|
||||
"zeroize",
|
||||
@@ -1182,6 +1190,16 @@ dependencies = [
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d"
|
||||
dependencies = [
|
||||
"diff",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr2"
|
||||
version = "2.0.0"
|
||||
@@ -2210,6 +2228,12 @@ version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||
|
||||
[[package]]
|
||||
name = "yoke"
|
||||
version = "0.8.0"
|
||||
|
||||
+9
-9
@@ -3,7 +3,7 @@ name = "gman"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
|
||||
description = "Universal secret management and command injection tool"
|
||||
description = "Universal secret management and injection tool"
|
||||
keywords = ["cli", "secrets", "credentials", "command-line", "encryption"]
|
||||
documentation = "https://github.com/Dark-Alex-17/gman"
|
||||
repository = "https://github.com/Dark-Alex-17/gman"
|
||||
@@ -41,19 +41,19 @@ chrono = "0.4.42"
|
||||
indoc = "2.0.6"
|
||||
regex = "1.11.2"
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "1.4.1"
|
||||
tempfile = "3.10.1"
|
||||
|
||||
[[bin]]
|
||||
bench = false
|
||||
name = "gman"
|
||||
|
||||
[[test]]
|
||||
name = "mod_tests"
|
||||
path = "tests/providers/mod_tests.rs"
|
||||
|
||||
[[test]]
|
||||
name = "local_tests"
|
||||
path = "tests/providers/local_tests.rs"
|
||||
|
||||
[profile.release]
|
||||
lto = true
|
||||
strip = true
|
||||
opt-level = "z"
|
||||
|
||||
[[test]]
|
||||
name = "integration"
|
||||
path = "tests/tests.rs"
|
||||
|
||||
+27
-26
@@ -1,5 +1,7 @@
|
||||
use crate::command::preview_command;
|
||||
use anyhow::{Context, Result, anyhow};
|
||||
use gman::config::{Config, RunConfig};
|
||||
use gman::providers::SecretProvider;
|
||||
use heck::ToSnakeCase;
|
||||
use log::{debug, error};
|
||||
use regex::Regex;
|
||||
@@ -8,8 +10,6 @@ use std::ffi::OsString;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use gman::config::{Config, RunConfig};
|
||||
use gman::providers::SecretProvider;
|
||||
|
||||
const ARG_FORMAT_PLACEHOLDER_KEY: &str = "{{key}}";
|
||||
const ARG_FORMAT_PLACEHOLDER_VALUE: &str = "{{value}}";
|
||||
@@ -246,32 +246,33 @@ pub fn parse_args(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
use gman::config::RunConfig;
|
||||
use crate::cli::generate_files_secret_injections;
|
||||
use crate::cli::generate_files_secret_injections;
|
||||
use gman::config::RunConfig;
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[test]
|
||||
fn test_generate_files_secret_injections() {
|
||||
let mut secrets = HashMap::new();
|
||||
secrets.insert("SECRET1".to_string(), "value1".to_string());
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let file_path = temp_dir.path().join("test.txt");
|
||||
std::fs::write(&file_path, "{{secret1}}").unwrap();
|
||||
#[test]
|
||||
fn test_generate_files_secret_injections() {
|
||||
let mut secrets = HashMap::new();
|
||||
secrets.insert("SECRET1".to_string(), "value1".to_string());
|
||||
let temp_dir = tempfile::tempdir().unwrap();
|
||||
let file_path = temp_dir.path().join("test.txt");
|
||||
std::fs::write(&file_path, "{{secret1}}").unwrap();
|
||||
|
||||
let run_config = RunConfig {
|
||||
name: Some("test".to_string()),
|
||||
secrets: Some(vec!["secret1".to_string()]),
|
||||
files: Some(vec![file_path.clone()]),
|
||||
flag: None,
|
||||
flag_position: None,
|
||||
arg_format: None,
|
||||
};
|
||||
let run_config = RunConfig {
|
||||
name: Some("test".to_string()),
|
||||
secrets: Some(vec!["secret1".to_string()]),
|
||||
files: Some(vec![file_path.clone()]),
|
||||
flag: None,
|
||||
flag_position: None,
|
||||
arg_format: None,
|
||||
};
|
||||
|
||||
let result = generate_files_secret_injections(secrets, &run_config).unwrap();
|
||||
let result = generate_files_secret_injections(secrets, &run_config).unwrap();
|
||||
|
||||
assert_eq!(result.len(), 1);
|
||||
assert_eq!(result[0].0, &file_path);
|
||||
assert_eq!(result[0].1, "{{secret1}}");
|
||||
assert_eq!(result[0].2, "value1");
|
||||
}
|
||||
assert_eq!(result.len(), 1);
|
||||
assert_eq!(result[0].0, &file_path);
|
||||
assert_str_eq!(result[0].1, "{{secret1}}");
|
||||
assert_str_eq!(result[0].2, "value1");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,3 +102,23 @@ fn ps_quote(s: &OsStr) -> String {
|
||||
s.into_owned()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::command::preview_command;
|
||||
use pretty_assertions::assert_str_eq;
|
||||
use std::process::Command;
|
||||
|
||||
#[test]
|
||||
fn test_preview_command() {
|
||||
let mut cmd = Command::new("echo");
|
||||
cmd.arg("hello world");
|
||||
cmd.env("MY_VAR", "my_value");
|
||||
let preview = preview_command(&cmd);
|
||||
if cfg!(unix) {
|
||||
assert_str_eq!(preview, "MY_VAR=my_value echo 'hello world'");
|
||||
} else if cfg!(windows) {
|
||||
assert_str_eq!(preview, "set MY_VAR=my_value && \"echo\" \"hello world\"");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
use clap::{
|
||||
crate_authors, crate_description, crate_name, crate_version, CommandFactory, Parser, ValueEnum,
|
||||
CommandFactory, Parser, ValueEnum, crate_authors, crate_description, crate_name, crate_version,
|
||||
};
|
||||
use std::ffi::OsString;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use clap::Subcommand;
|
||||
use crossterm::execute;
|
||||
use crossterm::terminal::{disable_raw_mode, LeaveAlternateScreen};
|
||||
use crossterm::terminal::{LeaveAlternateScreen, disable_raw_mode};
|
||||
use gman::config::Config;
|
||||
use gman::providers::local::LocalProvider;
|
||||
use gman::providers::SupportedProvider;
|
||||
use gman::providers::local::LocalProvider;
|
||||
use heck::ToSnakeCase;
|
||||
use std::io::{self, IsTerminal, Read, Write};
|
||||
use std::panic::PanicHookInfo;
|
||||
|
||||
@@ -41,3 +41,20 @@ pub fn get_log_path() -> PathBuf {
|
||||
log_path.push("gman.log");
|
||||
log_path
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::utils::get_log_path;
|
||||
|
||||
#[test]
|
||||
fn test_get_log_path() {
|
||||
let log_path = get_log_path();
|
||||
if cfg!(target_os = "linux") {
|
||||
assert!(log_path.ends_with(".cache/gman/gman.log"));
|
||||
} else if cfg!(target_os = "macos") {
|
||||
assert!(log_path.ends_with("Library/Logs/gman/gman.log"));
|
||||
} else if cfg!(target_os = "windows") {
|
||||
assert!(log_path.ends_with("Logs\\gman\\gman.log"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -157,6 +157,7 @@ pub fn decrypt_string(password: impl Into<SecretString>, envelope: &str) -> Resu
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn round_trip() {
|
||||
|
||||
@@ -330,3 +330,27 @@ fn get_password(config: &Config) -> Result<SecretString> {
|
||||
Ok(SecretString::new(password.into()))
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crate::derive_key;
|
||||
use crate::providers::local::derive_key_with_params;
|
||||
use pretty_assertions::assert_eq;
|
||||
use secrecy::SecretString;
|
||||
|
||||
#[test]
|
||||
fn test_derive_key() {
|
||||
let password = SecretString::new("test_password".to_string().into());
|
||||
let salt = [0u8; 16];
|
||||
let key = derive_key(&password, &salt).unwrap();
|
||||
assert_eq!(key.as_slice().len(), 32);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_derive_key_with_params() {
|
||||
let password = SecretString::new("test_password".to_string().into());
|
||||
let salt = [0u8; 16];
|
||||
let key = derive_key_with_params(&password, &salt, 10, 1, 1).unwrap();
|
||||
assert_eq!(key.as_slice().len(), 32);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
use gman::providers::SupportedProvider;
|
||||
use gman::providers::local::LocalProvider;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
#[test]
|
||||
fn test_provider_kind_from() {
|
||||
enum ProviderKind {
|
||||
Local,
|
||||
}
|
||||
|
||||
impl From<ProviderKind> for SupportedProvider {
|
||||
fn from(k: ProviderKind) -> Self {
|
||||
match k {
|
||||
ProviderKind::Local => SupportedProvider::Local(LocalProvider),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let provider_kind = ProviderKind::Local;
|
||||
let supported_provider: SupportedProvider = provider_kind.into();
|
||||
assert_eq!(supported_provider, SupportedProvider::Local(LocalProvider));
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
mod main_tests;
|
||||
@@ -0,0 +1 @@
|
||||
mod gman;
|
||||
@@ -3,6 +3,7 @@ mod tests {
|
||||
use gman::config::{Config, RunConfig};
|
||||
use gman::providers::SupportedProvider;
|
||||
use gman::providers::local::LocalProvider;
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
|
||||
use validator::Validate;
|
||||
|
||||
@@ -190,7 +191,7 @@ mod tests {
|
||||
fn test_config_extract_provider() {
|
||||
let config = Config::default();
|
||||
let provider = config.extract_provider();
|
||||
assert_eq!(provider.name(), "LocalProvider");
|
||||
assert_str_eq!(provider.name(), "LocalProvider");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
use anyhow::Result;
|
||||
use validator::Validate;
|
||||
|
||||
// Redefining the struct here for testing purposes
|
||||
pub struct SyncOpts<'a> {
|
||||
pub remote_url: &'a Option<String>,
|
||||
pub branch: &'a Option<String>,
|
||||
}
|
||||
|
||||
impl<'a> Validate for SyncOpts<'a> {
|
||||
fn validate(&self) -> Result<(), validator::ValidationErrors> {
|
||||
if self.remote_url.is_none() {
|
||||
return Err(validator::ValidationErrors::new());
|
||||
}
|
||||
if self.branch.is_none() {
|
||||
return Err(validator::ValidationErrors::new());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync_opts_validation_valid() {
|
||||
let remote_url = Some("https://github.com/user/repo.git".to_string());
|
||||
let branch = Some("main".to_string());
|
||||
let opts = SyncOpts {
|
||||
remote_url: &remote_url,
|
||||
branch: &branch,
|
||||
};
|
||||
assert!(opts.validate().is_ok());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync_opts_validation_missing_remote_url() {
|
||||
let remote_url = None;
|
||||
let branch = Some("main".to_string());
|
||||
let opts = SyncOpts {
|
||||
remote_url: &remote_url,
|
||||
branch: &branch,
|
||||
};
|
||||
assert!(opts.validate().is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_sync_opts_validation_missing_branch() {
|
||||
let remote_url = Some("https://github.com/user/repo.git".to_string());
|
||||
let branch = None;
|
||||
let opts = SyncOpts {
|
||||
remote_url: &remote_url,
|
||||
branch: &branch,
|
||||
};
|
||||
assert!(opts.validate().is_err());
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
use gman::providers::local::LocalProviderConfig;
|
||||
use pretty_assertions::assert_str_eq;
|
||||
|
||||
#[test]
|
||||
fn test_local_provider_config_default() {
|
||||
@@ -7,5 +8,14 @@ fn test_local_provider_config_default() {
|
||||
.map(|p| p.join(".gman_vault"))
|
||||
.and_then(|p| p.to_str().map(|s| s.to_string()))
|
||||
.unwrap_or_else(|| ".gman_vault".into());
|
||||
assert_eq!(config.vault_path, expected_path);
|
||||
assert_str_eq!(config.vault_path, expected_path);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_local_provider_name() {
|
||||
use gman::providers::SecretProvider;
|
||||
use gman::providers::local::LocalProvider;
|
||||
|
||||
let provider = LocalProvider;
|
||||
assert_str_eq!(provider.name(), "LocalProvider");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
mod git_sync_tests;
|
||||
mod local_tests;
|
||||
mod provider_tests;
|
||||
@@ -1,7 +1,29 @@
|
||||
use gman::providers::local::LocalProvider;
|
||||
use gman::providers::{ParseProviderError, SupportedProvider};
|
||||
use pretty_assertions::{assert_eq, assert_str_eq};
|
||||
use std::str::FromStr;
|
||||
|
||||
#[test]
|
||||
fn test_supported_provider_from_str() {
|
||||
assert_eq!(
|
||||
SupportedProvider::from_str("local").unwrap(),
|
||||
SupportedProvider::Local(LocalProvider)
|
||||
);
|
||||
assert_eq!(
|
||||
SupportedProvider::from_str(" Local ").unwrap(),
|
||||
SupportedProvider::Local(LocalProvider)
|
||||
);
|
||||
assert!(matches!(
|
||||
SupportedProvider::from_str("invalid"),
|
||||
Err(ParseProviderError::Unsupported(_))
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_supported_provider_display() {
|
||||
assert_str_eq!(SupportedProvider::Local(LocalProvider).to_string(), "local");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_supported_provider_from_str_valid() {
|
||||
assert_eq!(
|
||||
@@ -17,13 +39,7 @@ fn test_supported_provider_from_str_valid() {
|
||||
#[test]
|
||||
fn test_supported_provider_from_str_invalid() {
|
||||
let err = SupportedProvider::from_str("invalid").unwrap_err();
|
||||
assert_eq!(err.to_string(), "unsupported provider 'invalid'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_supported_provider_display() {
|
||||
let provider = SupportedProvider::Local(LocalProvider);
|
||||
assert_eq!(provider.to_string(), "local");
|
||||
assert_str_eq!(err.to_string(), "unsupported provider 'invalid'");
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -0,0 +1,3 @@
|
||||
mod bin;
|
||||
mod config_tests;
|
||||
mod providers;
|
||||
Reference in New Issue
Block a user