use rpawomaster::securecrypto::{SecureCrypto, generate_rsa_keypair};
use sled::IVec;
use tempfile::tempdir;
use std::fs;
use walkdir::WalkDir;
#[test]
fn test_encrypt_decrypt_string() {
let (private_pem, public_pem) = generate_rsa_keypair().expect("Failed to generate RSA key pair");
let crypto = SecureCrypto::from_pem_keys(&public_pem, &private_pem).expect("Failed to create SecureCrypto instance");
let test_str = "Hello, World! This is a test string with special characters: )V?(3S8}5mrM?%XW".to_string();
let encrypted_data = crypto.encrypt_string(&test_str).expect("Encryption failed");
let decrypted_str = crypto.decrypt_string(&IVec::from(encrypted_data)).expect("Decryption failed");
assert_eq!(decrypted_str, test_str, "Decrypted string does not match original");
}
#[test]
fn test_encrypt_decrypt_empty_string() {
let (private_pem, public_pem) = generate_rsa_keypair().expect("Failed to generate RSA key pair");
let crypto = SecureCrypto::from_pem_keys(&public_pem, &private_pem).expect("Failed to create SecureCrypto instance");
let test_str = "";
let encrypted_data = crypto.encrypt_string(test_str).expect("Encryption failed");
let decrypted_str = crypto.decrypt_string(&IVec::from(encrypted_data)).expect("Decryption failed");
assert_eq!(decrypted_str, test_str, "Decrypted empty string does not match original");
}
#[test]
fn test_encrypt_decrypt_file() {
let (private_pem, public_pem) = generate_rsa_keypair().expect("Failed to generate RSA key pair");
let crypto = SecureCrypto::from_pem_keys(&public_pem, &private_pem).expect("Failed to create SecureCrypto instance");
let temp_dir = tempdir().expect("Failed to create temp directory");
let temp_file_path = temp_dir.path().join("test_file.txt");
let test_content = b"Test file content with special characters: \xE6\xB5\x8B\xE8\xAF\x95\xE6\x96\x87\xE6\x9C\xAC \xC2\xA3\xC2\xA5\xE2\x82\xAC";
fs::write(&temp_file_path, test_content).expect("Failed to write to temp file");
let filename = "test_file.txt";
let encrypted_path = temp_file_path.parent().unwrap();
let encrypted_file_path = encrypted_path.join(format!("{}.esz", filename));
crypto.encrypt_path(&temp_file_path, &encrypted_path).expect("File encryption failed");
assert!(encrypted_file_path.exists(), "Encrypted file not created");
fs::remove_file(&temp_file_path).expect("Failed to remove original file");
let decrypted_path = temp_dir.path();
let decrypted_file_path = decrypted_path.join(filename);
crypto.decrypt_path(&encrypted_file_path, &decrypted_path).expect("File decryption failed");
assert!(decrypted_file_path.exists(), "Decrypted file not created");
let decrypted_content = fs::read(&decrypted_file_path).expect("Failed to read decrypted file");
assert_eq!(decrypted_content, test_content, "Decrypted file content does not match original");
}
#[test]
fn test_tar_gz_pack_unpack() {
let (private_pem, public_pem) = generate_rsa_keypair().expect("Failed to generate RSA key pair");
let crypto = SecureCrypto::from_pem_keys(&public_pem, &private_pem).expect("Failed to create SecureCrypto instance");
let temp_dir = tempdir().expect("Failed to create temp directory");
let source_dir = temp_dir.path().join("source_dir");
let tar_path = temp_dir.path().join("test_archive.tgz");
let extract_dir = temp_dir.path().join("extracted_dir");
fs::create_dir(&source_dir).expect("Failed to create source directory");
fs::write(source_dir.join("file1.txt"), "Test content 1").expect("Failed to write file1");
fs::write(source_dir.join("file2.bin"), vec![0x00, 0x01, 0x02, 0xFF]).expect("Failed to write binary file");
let subdir = source_dir.join("subdir");
fs::create_dir(&subdir).expect("Failed to create subdirectory");
fs::write(subdir.join("file3.txt"), "Nested file content").expect("Failed to write nested file");
let empty_dir = source_dir.join("empty_dir");
fs::create_dir(&empty_dir).expect("Failed to create empty directory");
crypto.create_tar_archive(&source_dir, &tar_path).expect("Failed to create tgz archive");
assert!(tar_path.exists(), "Archive file not created");
assert!(tar_path.metadata().expect("Failed to get metadata").len() > 0, "Archive file is empty");
crypto.extract_tar_archive(&tar_path, &extract_dir).expect("Failed to extract tgz archive");
let extracted_file1 = extract_dir.join("file1.txt");
assert!(extracted_file1.exists(), "Extracted file1.txt not found");
let content1 = fs::read_to_string(extracted_file1).expect("Failed to read extracted file1");
assert_eq!(content1, "Test content 1", "Content mismatch for file1.txt");
let extracted_bin = extract_dir.join("file2.bin");
assert!(extracted_bin.exists(), "Extracted file2.bin not found");
let bin_content = fs::read(extracted_bin).expect("Failed to read binary file");
assert_eq!(bin_content, vec![0x00, 0x01, 0x02, 0xFF], "Binary content mismatch");
let extracted_nested = extract_dir.join("subdir/file3.txt");
assert!(extracted_nested.exists(), "Extracted nested file not found");
let nested_content = fs::read_to_string(extracted_nested).expect("Failed to read nested file");
assert_eq!(nested_content, "Nested file content", "Content mismatch for nested file");
let extracted_empty = extract_dir.join("empty_dir");
assert!(extracted_empty.exists(), "Empty directory not extracted");
assert!(extracted_empty.is_dir(), "Extracted empty_dir is not a directory");
assert!(extracted_empty.read_dir().expect("Failed to read empty directory").next().is_none(), "Extracted empty directory is not empty");
temp_dir.close().expect("Failed to close temp directory");
}
#[test]
fn test_encrypt_decrypt_directory() {
let (private_pem, public_pem) = generate_rsa_keypair().expect("Failed to generate RSA key pair");
let crypto = SecureCrypto::from_pem_keys(&public_pem, &private_pem).expect("Failed to create SecureCrypto instance");
let temp_dir = tempdir().expect("Failed to create temp directory");
let temp_dir_path = temp_dir.path();
let test_dir = temp_dir_path.join("complex_test_dir");
fs::create_dir(&test_dir).expect("Failed to create test directory");
let nested_dir = test_dir.join("level1").join("level2").join("level3");
fs::create_dir_all(&nested_dir).expect("Failed to create nested directories");
let empty_dir = test_dir.join("empty_dir");
fs::create_dir(&empty_dir).expect("Failed to create empty directory");
let special_dir = test_dir.join("目录_файл_日本語");
fs::create_dir(&special_dir).expect("Failed to create special directory");
let test_files = vec![
(test_dir.join("readme.txt"), b"This is a readme file with basic content.".to_vec()),
(test_dir.join("empty.txt"), b"".to_vec()),
(test_dir.join("large.txt"), vec![b'A'; 10240]),
(test_dir.join("binary.bin"), vec![0x00, 0x01, 0x02, 0xFF, 0xFE, 0xFD]),
(test_dir.join("unicode.txt"), "测试文件内容 🚀 特殊字符: áéíóú 中文 🎉".as_bytes().to_vec()),
(test_dir.join(".hidden"), b"Hidden file content".to_vec()),
(nested_dir.join("deep.txt"), b"This file is deeply nested".to_vec()),
(special_dir.join("特殊文件.txt"), "特殊目录中的文件内容".as_bytes().to_vec()),
(test_dir.join("very_long_filename_that_exceeds_normal_length_limits.txt"), b"File with very long name".to_vec()),
];
for (file_path, content) in &test_files {
fs::create_dir_all(file_path.parent().unwrap()).expect("Failed to create parent directories");
fs::write(file_path, content).expect("Failed to write test file");
}
let mut original_files = Vec::new();
for entry in WalkDir::new(&test_dir) {
let entry = entry.expect("Failed to walk directory");
if entry.file_type().is_file() {
let content = fs::read(entry.path()).expect("Failed to read file");
original_files.push((
entry.path().strip_prefix(&test_dir).unwrap().to_path_buf(),
content,
));
}
}
let encrypted_path = temp_dir_path.join("complex_test_dir.tgz.esz");
crypto.encrypt_path(&test_dir, &temp_dir_path).expect("Directory encryption failed");
assert!(encrypted_path.exists(), "Encrypted directory file not created");
assert!(encrypted_path.metadata().unwrap().len() > 0, "Encrypted file is empty");
assert!(test_dir.exists(), "Original directory should still exist");
let decrypted_dir = temp_dir_path.join("decrypted_complex_dir");
crypto.decrypt_path(&encrypted_path, &decrypted_dir).expect("Directory decryption failed");
assert!(decrypted_dir.exists(), "Decrypted directory not created");
for (relative_path, original_content) in &original_files {
let decrypted_path = decrypted_dir.join(relative_path);
assert!(decrypted_path.exists(), "File not found: {:?}", relative_path);
let decrypted_content = fs::read(&decrypted_path).expect("Failed to read decrypted file");
assert_eq!(&decrypted_content, original_content, "Content mismatch for file: {:?}", relative_path);
}
let mut decrypted_files = Vec::new();
for entry in WalkDir::new(&decrypted_dir) {
let entry = entry.expect("Failed to walk decrypted directory");
if entry.file_type().is_file() {
decrypted_files.push(entry.path().strip_prefix(&decrypted_dir).unwrap().to_path_buf());
}
}
assert_eq!(decrypted_files.len(), original_files.len(), "File count mismatch");
let empty_test_dir = temp_dir_path.join("empty_test_dir");
fs::create_dir(&empty_test_dir).expect("Failed to create empty test directory");
let empty_encrypted_path = temp_dir_path.join("empty_test_dir.tgz.esz");
crypto.encrypt_path(&empty_test_dir, &temp_dir_path).expect("Empty directory encryption failed");
assert!(empty_encrypted_path.exists(), "Empty directory encryption failed");
let empty_decrypted_dir = temp_dir_path.join("decrypted_empty_dir");
crypto.decrypt_path(&empty_encrypted_path, &empty_decrypted_dir).expect("Empty directory decryption failed");
assert!(empty_decrypted_dir.exists(), "Empty directory decryption failed");
assert!(empty_decrypted_dir.read_dir().unwrap().next().is_none(), "Decrypted empty directory should be empty");
}
#[test]
fn test_save_and_read_keypair() {
use rpawomaster::securecrypto::{save_keypair, read_keypair};
let (private_pem, public_pem) = generate_rsa_keypair().expect("Failed to generate RSA key pair");
let temp_dir = tempdir().expect("Failed to create temp directory");
let temp_dir_path = temp_dir.path();
save_keypair(private_pem.clone(), public_pem.clone(), temp_dir_path)
.expect("Failed to save keypair");
let private_key_path = temp_dir_path.join("private_key.esz");
let public_key_path = temp_dir_path.join("public_key.esz");
assert!(private_key_path.exists(), "Private key file not created");
assert!(public_key_path.exists(), "Public key file not created");
let private_key_content = fs::read_to_string(&private_key_path).expect("Failed to read private key file");
let public_key_content = fs::read_to_string(&public_key_path).expect("Failed to read public key file");
assert!(!private_key_content.is_empty(), "Private key file is empty");
assert!(!public_key_content.is_empty(), "Public key file is empty");
assert_eq!(private_key_content, private_pem, "Private key content mismatch");
assert_eq!(public_key_content, public_pem, "Public key content mismatch");
let (read_private, read_public) = read_keypair(temp_dir_path)
.expect("Failed to read keypair");
assert_eq!(read_private, private_pem, "Read private key does not match original");
assert_eq!(read_public, public_pem, "Read public key does not match original");
let crypto_from_read = SecureCrypto::from_pem_keys(&read_public, &read_private)
.expect("Failed to create SecureCrypto from read keys");
let test_str = "Test string for keypair functionality";
let encrypted = crypto_from_read.encrypt_string(test_str)
.expect("Failed to encrypt with read keys");
let decrypted = crypto_from_read.decrypt_string(&IVec::from(encrypted))
.expect("Failed to decrypt with read keys");
assert_eq!(decrypted, test_str, "Decrypted string does not match original");
}