use gen_pass::{PassConfig, PasswordGenerator, UPPERCASE, DIGITS, SYMBOLS};
fn charset_only_contains(password: &str, allowed: &str) {
assert!(password.chars().all(|c| allowed.contains(c)), "password contains disallowed characters");
}
#[test]
fn default_generation_length() {
let cfg = PassConfig::default();
let gen = PasswordGenerator::from_config(&cfg).expect("generator");
let pw = gen.generate(cfg.length);
assert_eq!(pw.len(), cfg.length);
}
#[test]
fn default_salt_is_suenot() {
let cfg = PassConfig::default();
assert_eq!(cfg.salt, Some("suenot".to_string()), "Default salt should be 'suenot'");
}
#[test]
fn uppercase_only() {
let cfg = PassConfig {
length: 20,
use_lowercase: false,
use_uppercase: true,
use_digits: false,
use_symbols: false,
salt: None,
};
let gen = PasswordGenerator::from_config(&cfg).unwrap();
let pw = gen.generate(cfg.length);
charset_only_contains(&pw, UPPERCASE);
}
#[test]
fn digits_and_symbols() {
let cfg = PassConfig {
length: 30,
use_lowercase: false,
use_uppercase: false,
use_digits: true,
use_symbols: true,
salt: None,
};
let allowed: String = format!("{}{}", DIGITS, SYMBOLS);
let gen = PasswordGenerator::from_config(&cfg).unwrap();
let pw = gen.generate(cfg.length);
charset_only_contains(&pw, &allowed);
}
#[test]
fn error_on_empty_charset() {
let cfg = PassConfig {
length: 10,
use_lowercase: false,
use_uppercase: false,
use_digits: false,
use_symbols: false,
salt: None,
};
assert!(PasswordGenerator::from_config(&cfg).is_err());
}
#[test]
fn randomness() {
let cfg = PassConfig { length: 32, ..Default::default() };
let gen = PasswordGenerator::from_config(&cfg).unwrap();
let pw1 = gen.generate(cfg.length);
let pw2 = gen.generate(cfg.length);
assert_ne!(pw1, pw2, "two consecutive passwords should differ");
}
#[test]
fn salt_changes_output() {
let cfg_no_salt = PassConfig { length: 16, ..Default::default() };
let gen_no_salt = PasswordGenerator::from_config(&cfg_no_salt).unwrap();
let pw_no_salt = gen_no_salt.generate(cfg_no_salt.length);
let cfg_with_salt = PassConfig {
length: 16,
salt: Some("test_salt".to_string()),
..Default::default()
};
let gen_with_salt = PasswordGenerator::from_config(&cfg_with_salt).unwrap();
let pw_with_salt = gen_with_salt.generate(cfg_with_salt.length);
assert_ne!(pw_no_salt, pw_with_salt, "salt should change password output");
}
#[test]
fn different_salts_different_outputs() {
let cfg_salt1 = PassConfig {
length: 16,
salt: Some("salt1".to_string()),
..Default::default()
};
let gen_salt1 = PasswordGenerator::from_config(&cfg_salt1).unwrap();
let pw_salt1 = gen_salt1.generate(cfg_salt1.length);
let cfg_salt2 = PassConfig {
length: 16,
salt: Some("salt2".to_string()),
..Default::default()
};
let gen_salt2 = PasswordGenerator::from_config(&cfg_salt2).unwrap();
let pw_salt2 = gen_salt2.generate(cfg_salt2.length);
assert_ne!(pw_salt1, pw_salt2, "different salts should produce different passwords");
}