//! Tests for snapshot operations. use std::path::PathBuf; use gitks::snapshot::ops::{create_snapshot, restore_snapshot}; use gitks::snapshot::storage::{LocalSnapshotStorage, SnapshotStorageBackend}; fn temp_bare_repo() -> PathBuf { let dir = tempfile::tempdir().unwrap().path().to_path_buf(); let result = std::process::Command::new("git") .args(["init", "--bare"]) .arg(&dir) .output() .expect("git init --bare should work"); assert!(result.status.success()); // Create an initial commit so HEAD exists // We need a working tree to create a commit, so we create one temporarily let work_dir = tempfile::tempdir().unwrap().path().to_path_buf(); let result2 = std::process::Command::new("git") .args(["init"]) .arg(&work_dir) .output() .expect("git init should work"); assert!(result2.status.success()); // Create a file and commit std::fs::write(work_dir.join("test.txt"), "hello world").unwrap(); let result3 = std::process::Command::new("git") .args(["add", "test.txt"]) .current_dir(&work_dir) .output(); let _ = result3; let result4 = std::process::Command::new("git") .args(["commit", "-m", "initial commit"]) .env("GIT_AUTHOR_NAME", "test") .env("GIT_AUTHOR_EMAIL", "test@test.com") .env("GIT_COMMITTER_NAME", "test") .env("GIT_COMMITTER_EMAIL", "test@test.com") .current_dir(&work_dir) .output(); let _ = result4; // Push to bare repo let result5 = std::process::Command::new("git") .args(["push", &dir.to_string_lossy(), "master:refs/heads/master"]) .current_dir(&work_dir) .output(); let _ = result5; dir } #[test] fn test_snapshot_create_and_restore() { let repo = temp_bare_repo(); let gb = gitks::bare::GitBare::new(repo.clone()); // Create snapshot let result = create_snapshot(&gb); if let Ok(data) = result { assert!(!data.is_empty()); // Restore to a different location let target = tempfile::tempdir().unwrap().path().to_path_buf(); // Initialize target as bare repo first let init_result = std::process::Command::new("git") .args(["init", "--bare"]) .arg(&target) .output(); if let Ok(init_output) = init_result && init_output.status.success() { let restore_result = restore_snapshot(&target, &data); // May succeed or fail depending on git bundle compatibility let _ = restore_result; } } } #[test] fn test_local_snapshot_storage_write_and_read() { let dir = tempfile::tempdir().unwrap().path().to_path_buf(); let storage = LocalSnapshotStorage::new(dir); // Write snapshot let result = storage.write_snapshot("snap001", "test.git", "abc123", b"bundle_data"); assert!(result.is_ok()); // Read snapshot let result = storage.read_snapshot("snap001"); assert!(result.is_ok()); assert_eq!(result.unwrap(), b"bundle_data".to_vec()); // Read non-existent let result = storage.read_snapshot("nonexistent"); assert!(result.is_err()); } #[test] fn test_local_snapshot_storage_list() { let dir = tempfile::tempdir().unwrap().path().to_path_buf(); let storage = LocalSnapshotStorage::new(dir); // Write two snapshots storage .write_snapshot("snap001", "repo1.git", "abc123", b"data1") .unwrap(); storage .write_snapshot("snap002", "repo2.git", "def456", b"data2") .unwrap(); // List all let result = storage.list_snapshots(""); assert!(result.is_ok()); assert_eq!(result.unwrap().len(), 2); // List filtered let result = storage.list_snapshots("repo1.git"); assert!(result.is_ok()); let snapshots = result.unwrap(); assert_eq!(snapshots.len(), 1); assert_eq!(snapshots[0].relative_path, "repo1.git"); } #[test] fn test_local_snapshot_storage_delete() { let dir = tempfile::tempdir().unwrap().path().to_path_buf(); let storage = LocalSnapshotStorage::new(dir); storage .write_snapshot("snap001", "test.git", "abc123", b"data") .unwrap(); assert!(storage.read_snapshot("snap001").is_ok()); storage.delete_snapshot("snap001").unwrap(); assert!(storage.read_snapshot("snap001").is_err()); // Delete non-existent assert!(storage.delete_snapshot("nonexistent").is_err()); }