use dotstate::utils::sync_validation;
use std::collections::HashSet;
use std::path::PathBuf;
use tempfile::TempDir;
#[test]
fn test_validation_prevents_file_inside_synced_directory() {
let temp_dir = TempDir::new().unwrap();
let repo_path = temp_dir.path();
let mut synced_files = HashSet::new();
synced_files.insert(".nvim".to_string());
let file_path = PathBuf::from("/home/user/.nvim/init.lua");
let relative_path = ".nvim/init.lua";
let result =
sync_validation::validate_before_sync(relative_path, &file_path, &synced_files, repo_path);
assert!(!result.is_safe, "Should block file inside synced directory");
assert!(
result.error_message.is_some(),
"Should provide error message"
);
let error_msg = result.error_message.unwrap();
assert!(
error_msg.contains("already inside a synced directory")
|| error_msg.contains("synced directory"),
"Error message should mention synced directory, got: {error_msg}"
);
}
#[test]
fn test_validation_prevents_directory_containing_synced_files() {
let temp_dir = TempDir::new().unwrap();
let repo_path = temp_dir.path();
let mut synced_files = HashSet::new();
synced_files.insert(".nvim/init.lua".to_string());
let dir_path = temp_dir.path().join(".nvim");
std::fs::create_dir_all(&dir_path).unwrap();
let relative_path = ".nvim";
let result =
sync_validation::validate_before_sync(relative_path, &dir_path, &synced_files, repo_path);
assert!(
!result.is_safe,
"Should block directory containing synced files. Synced: {synced_files:?}, Trying to add: {relative_path}"
);
assert!(
result.error_message.is_some(),
"Should provide error message"
);
let error_msg = result.error_message.unwrap();
assert!(
error_msg.contains("contains files") || error_msg.contains("already synced"),
"Error message should mention containing files or already synced, got: {error_msg}"
);
}
#[test]
fn test_validation_handles_path_normalization() {
let temp_dir = TempDir::new().unwrap();
let repo_path = temp_dir.path();
let mut synced_files = HashSet::new();
synced_files.insert("nvim".to_string());
let file_path = PathBuf::from("/home/user/.nvim/init.lua");
let relative_path = ".nvim/init.lua";
synced_files.clear();
synced_files.insert(".nvim".to_string());
let result =
sync_validation::validate_before_sync(relative_path, &file_path, &synced_files, repo_path);
assert!(!result.is_safe, "Should block file inside synced directory");
}
#[test]
fn test_validation_detects_git_repositories() {
let temp_dir = TempDir::new().unwrap();
let repo_path = temp_dir.path();
let git_dir = temp_dir.path().join("my-project");
std::fs::create_dir_all(&git_dir).unwrap();
std::fs::create_dir_all(git_dir.join(".git")).unwrap();
let synced_files = HashSet::new();
let relative_path = "my-project";
let result =
sync_validation::validate_before_sync(relative_path, &git_dir, &synced_files, repo_path);
assert!(!result.is_safe, "Should block git repository");
assert!(
result.error_message.is_some(),
"Should provide error message"
);
assert!(
result.error_message.unwrap().to_lowercase().contains("git"),
"Error message should mention git"
);
}
#[test]
fn test_validation_allows_safe_files() {
let temp_dir = TempDir::new().unwrap();
let repo_path = temp_dir.path();
let synced_files = HashSet::new();
let file_path = PathBuf::from("/home/user/.zshrc");
let relative_path = ".zshrc";
let result =
sync_validation::validate_before_sync(relative_path, &file_path, &synced_files, repo_path);
assert!(result.is_safe, "Should allow safe files");
}
#[test]
fn test_symlink_validation_checks_source_exists() {
let temp_dir = TempDir::new().unwrap();
let source_file = temp_dir.path().join("source.txt");
std::fs::write(&source_file, "test content").unwrap();
let target = temp_dir.path().join("target.txt");
let symlink_source = temp_dir.path().join("repo").join("source.txt");
let result = sync_validation::validate_symlink_creation(
&source_file, &symlink_source, &target, )
.unwrap();
assert!(
result.is_safe,
"Should allow symlink creation when source exists"
);
}
#[test]
fn test_symlink_validation_fails_when_source_missing() {
let temp_dir = TempDir::new().unwrap();
let source_file = temp_dir.path().join("nonexistent.txt");
let target = temp_dir.path().join("target.txt");
let symlink_source = temp_dir.path().join("repo").join("source.txt");
let result = sync_validation::validate_symlink_creation(
&source_file, &symlink_source,
&target,
)
.unwrap();
assert!(
!result.is_safe,
"Should block symlink when source doesn't exist"
);
assert!(
result.error_message.is_some(),
"Should provide error message"
);
}