use std::fs;
use std::path::PathBuf;
use std::process::Command;
use tempfile::TempDir;
#[cfg(test)]
mod cli_tests {
use super::*;
fn get_binary_path() -> PathBuf {
let mut path = std::env::current_exe().unwrap();
path.pop(); if path.ends_with("deps") {
path.pop(); }
path.join("proofmode")
}
fn create_test_file(dir: &std::path::Path, name: &str, content: &[u8]) -> PathBuf {
let file_path = dir.join(name);
fs::write(&file_path, content).expect("Failed to write test file");
file_path
}
#[test]
fn test_cli_version() {
let output = Command::new(get_binary_path())
.arg("--version")
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("proofmode"));
let version = env!("CARGO_PKG_VERSION");
assert!(stdout.contains(version));
}
#[test]
fn test_cli_help() {
let output = Command::new(get_binary_path())
.arg("--help")
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Capture, share, and preserve verifiable photos and videos"));
assert!(stdout.contains("check"));
assert!(stdout.contains("generate"));
}
#[test]
fn test_cli_generate_help() {
let output = Command::new(get_binary_path())
.args(["generate", "--help"])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("--file"));
assert!(stdout.contains("--dir"));
assert!(stdout.contains("--storage"));
assert!(stdout.contains("--email"));
assert!(stdout.contains("--passphrase"));
}
#[test]
fn test_cli_check_help() {
let output = Command::new(get_binary_path())
.args(["check", "--help"])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("--file"));
assert!(stdout.contains("--dir"));
assert!(stdout.contains("--url"));
assert!(stdout.contains("--cid"));
}
#[test]
fn test_cli_generate_single_file() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let storage_dir = TempDir::new().expect("Failed to create storage dir");
let test_file = create_test_file(temp_dir.path(), "test.txt", b"CLI test content");
let output = Command::new(get_binary_path())
.args([
"generate",
"--file",
test_file.to_str().unwrap(),
"--storage",
storage_dir.path().to_str().unwrap(),
"--email",
"cli-test@example.com",
"--passphrase",
"clipassword123",
])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(stdout.contains("Generated proof for"));
assert!(stdout.contains(test_file.file_name().unwrap().to_str().unwrap()));
let lines: Vec<&str> = stdout.lines().collect();
let proof_line = lines
.iter()
.find(|line| line.contains("Generated proof for"))
.unwrap();
let hash = proof_line.split(": ").last().unwrap().trim();
assert_eq!(hash.len(), 64);
let proof_dir = storage_dir.path().join("proofmode").join(hash);
assert!(proof_dir.exists());
let json_file = proof_dir.join(format!("{}.proof.json", hash));
let csv_file = proof_dir.join(format!("{}.proof.csv", hash));
let asc_file = proof_dir.join(format!("{}.asc", hash));
assert!(json_file.exists());
assert!(csv_file.exists());
assert!(asc_file.exists());
}
#[test]
fn test_cli_generate_multiple_files() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let storage_dir = TempDir::new().expect("Failed to create storage dir");
let file1 = create_test_file(temp_dir.path(), "file1.txt", b"First file content");
let file2 = create_test_file(temp_dir.path(), "file2.txt", b"Second file content");
let output = Command::new(get_binary_path())
.args([
"generate",
"--file",
file1.to_str().unwrap(),
"--file",
file2.to_str().unwrap(),
"--storage",
storage_dir.path().to_str().unwrap(),
"--email",
"multi-test@example.com",
"--passphrase",
"multipass123",
])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let proof_lines: Vec<&str> = stdout
.lines()
.filter(|line| line.contains("Generated proof for"))
.collect();
assert_eq!(proof_lines.len(), 2);
let mut hashes = Vec::new();
for line in proof_lines {
let hash = line.split(": ").last().unwrap().trim();
hashes.push(hash);
}
assert_ne!(hashes[0], hashes[1]);
for hash in hashes {
let proof_dir = storage_dir.path().join("proofmode").join(hash);
assert!(proof_dir.exists());
}
}
#[test]
fn test_cli_generate_directory() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let storage_dir = TempDir::new().expect("Failed to create storage dir");
let test_dir = temp_dir.path().join("testdir");
fs::create_dir(&test_dir).expect("Failed to create test directory");
create_test_file(&test_dir, "dirfile1.txt", b"Directory file 1");
create_test_file(&test_dir, "dirfile2.txt", b"Directory file 2");
let output = Command::new(get_binary_path())
.args([
"generate",
"--dir",
test_dir.to_str().unwrap(),
"--storage",
storage_dir.path().to_str().unwrap(),
"--email",
"dir-test@example.com",
"--passphrase",
"dirpass123",
])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
let proof_lines: Vec<&str> = stdout
.lines()
.filter(|line| line.contains("Generated proof for"))
.collect();
assert_eq!(proof_lines.len(), 2);
}
#[test]
fn test_cli_check_file() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let test_file = create_test_file(temp_dir.path(), "check_test.txt", b"Check test content");
let output = Command::new(get_binary_path())
.args(["check", "--file", test_file.to_str().unwrap()])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
let stdout = String::from_utf8(output.stdout).unwrap();
assert!(
stdout.contains("Starting ProofCheck")
|| stdout.contains("Extracting files")
|| stdout.contains("Checking integrity")
);
}
#[test]
fn test_cli_invalid_arguments() {
let output = Command::new(get_binary_path())
.args([
"generate",
"--file",
"/non/existent/file.txt",
"--storage",
"/tmp/test",
"--email",
"test@example.com",
"--passphrase",
"test123",
])
.output()
.expect("Failed to execute CLI");
assert!(!output.status.success());
let stderr = String::from_utf8(output.stderr).unwrap();
assert!(!stderr.is_empty());
}
#[test]
fn test_cli_missing_required_args() {
let output = Command::new(get_binary_path())
.args(["generate"])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
}
#[test]
fn test_cli_check_with_output_file() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let test_file =
create_test_file(temp_dir.path(), "output_test.txt", b"Output test content");
let output_file = temp_dir.path().join("check_results.json");
let output = Command::new(get_binary_path())
.args([
"check",
"--file",
test_file.to_str().unwrap(),
"--output-file",
output_file.to_str().unwrap(),
])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
assert!(output_file.exists());
let json_content = fs::read_to_string(&output_file).unwrap();
assert!(json_content.contains("{") && json_content.contains("}"));
}
#[test]
fn test_cli_generate_custom_storage_path() {
let temp_dir = TempDir::new().expect("Failed to create temp dir");
let storage_dir = TempDir::new().expect("Failed to create storage dir");
let custom_storage = storage_dir
.path()
.join("custom")
.join("proof")
.join("storage");
let test_file = create_test_file(
temp_dir.path(),
"custom_storage.txt",
b"Custom storage test",
);
let output = Command::new(get_binary_path())
.args([
"generate",
"--file",
test_file.to_str().unwrap(),
"--storage",
custom_storage.to_str().unwrap(),
"--email",
"custom@example.com",
"--passphrase",
"custompass123",
])
.output()
.expect("Failed to execute CLI");
assert!(output.status.success());
assert!(custom_storage.exists());
let stdout = String::from_utf8(output.stdout).unwrap();
let hash = stdout
.lines()
.find(|line| line.contains("Generated proof for"))
.unwrap()
.split(": ")
.last()
.unwrap()
.trim();
let proof_dir = custom_storage.join("proofmode").join(hash);
assert!(proof_dir.exists());
}
}