use socket_patch_core::manifest::schema::PatchFileInfo;
use socket_patch_core::patch::rollback::{verify_file_rollback, VerifyRollbackStatus};
use std::path::Path;
fn git_sha256(content: &[u8]) -> String {
use sha2::{Digest, Sha256};
let header = format!("blob {}\0", content.len());
let mut hasher = Sha256::new();
hasher.update(header.as_bytes());
hasher.update(content);
hex::encode(hasher.finalize())
}
#[tokio::test]
async fn verify_new_file_rollback_ready_when_after_hash_matches() {
let tmp = tempfile::tempdir().unwrap();
let pkg = tmp.path();
let blobs = tmp.path().join("blobs");
std::fs::create_dir(&blobs).unwrap();
let patched = b"this file was created by the patch\n";
let after = git_sha256(patched);
std::fs::write(pkg.join("new_file.txt"), patched).unwrap();
let file_info = PatchFileInfo {
before_hash: String::new(),
after_hash: after.clone(),
};
let result = verify_file_rollback(pkg, "package/new_file.txt", &file_info, &blobs).await;
assert_eq!(result.status, VerifyRollbackStatus::Ready);
assert_eq!(result.current_hash.as_deref(), Some(after.as_str()));
}
#[tokio::test]
async fn verify_new_file_rollback_already_original_when_missing() {
let tmp = tempfile::tempdir().unwrap();
let pkg = tmp.path();
let blobs = tmp.path().join("blobs");
std::fs::create_dir(&blobs).unwrap();
let file_info = PatchFileInfo {
before_hash: String::new(),
after_hash: git_sha256(b"never written"),
};
let result = verify_file_rollback(pkg, "package/never_existed.txt", &file_info, &blobs).await;
assert_eq!(result.status, VerifyRollbackStatus::AlreadyOriginal);
}
#[tokio::test]
async fn verify_new_file_rollback_hash_mismatch_when_user_modified() {
let tmp = tempfile::tempdir().unwrap();
let pkg = tmp.path();
let blobs = tmp.path().join("blobs");
std::fs::create_dir(&blobs).unwrap();
let after = git_sha256(b"patched content the file should have had");
std::fs::write(
pkg.join("user_modified.txt"),
b"user wrote something different",
)
.unwrap();
let file_info = PatchFileInfo {
before_hash: String::new(),
after_hash: after,
};
let result = verify_file_rollback(pkg, "package/user_modified.txt", &file_info, &blobs).await;
assert_eq!(result.status, VerifyRollbackStatus::HashMismatch);
assert!(result.message.as_ref().unwrap().contains("modified"));
}
#[tokio::test]
async fn verify_existing_file_rollback_not_found_when_missing() {
let tmp = tempfile::tempdir().unwrap();
let pkg = tmp.path();
let blobs = tmp.path().join("blobs");
std::fs::create_dir(&blobs).unwrap();
let file_info = PatchFileInfo {
before_hash: git_sha256(b"original"),
after_hash: git_sha256(b"patched"),
};
let result = verify_file_rollback(pkg, "package/does_not_exist.txt", &file_info, &blobs).await;
assert_eq!(result.status, VerifyRollbackStatus::NotFound);
assert!(result.message.as_ref().unwrap().contains("not found"));
}
#[tokio::test]
async fn verify_existing_file_rollback_missing_blob() {
let tmp = tempfile::tempdir().unwrap();
let pkg = tmp.path();
let blobs = tmp.path().join("blobs");
std::fs::create_dir(&blobs).unwrap();
std::fs::write(pkg.join("patched.txt"), b"current patched bytes").unwrap();
let file_info = PatchFileInfo {
before_hash: git_sha256(b"original content we cannot recover"),
after_hash: git_sha256(b"current patched bytes"),
};
let result = verify_file_rollback(pkg, "package/patched.txt", &file_info, &blobs).await;
assert_eq!(result.status, VerifyRollbackStatus::MissingBlob);
}
#[allow(dead_code)]
fn _path_marker(_p: &Path) {}