use std::fs::File; use std::io::Write; use std::path::Path; use sanctum::upgrade::{ detect_package_manager_from_path, is_newer_version, parse_checksum_for_asset, parse_clean_version, GiteaRelease, PackageManager, }; use sha2::{Digest, Sha256}; #[test] fn test_parse_checksum_for_asset() { let sample_checksums = r#" # Offizielle SHA-256 Prüfsummen für Sanctum Release 2f069a8cc41f9fa6a2559e2952e5669523c21c175df15f6d80f0473bbe2fa60e sanctum-v0.5.0-windows-x86_64.zip e0c64ecc12c7f49180487b638f1152eccaf5c90270a93880db52ca56eb1c1d63 sanctum.exe 557dd84f339336899fdd67e69d894dcd6e32f3e0bff2ae8a3057df596eddf4b4 sanctum-v0.5.0-linux-x86_64.tar.gz 2816f00cb15825d92f35f93fd667ed04d36501763a70b9399dd0ab9355c9448d *sanctum "#; // Windows Binary let win_hash = parse_checksum_for_asset(sample_checksums, "sanctum.exe"); assert_eq!( win_hash.as_deref(), Some("e0c64ecc12c7f49180487b638f1152eccaf5c90270a93880db52ca56eb1c1d63") ); // Linux Binary (mit führendem Asterisk im Format) let linux_hash = parse_checksum_for_asset(sample_checksums, "sanctum"); assert_eq!( linux_hash.as_deref(), Some("2816f00cb15825d92f35f93fd667ed04d36501763a70b9399dd0ab9355c9448d") ); // Nicht existentes Asset let non_existent = parse_checksum_for_asset(sample_checksums, "nonexistent.exe"); assert_eq!(non_existent, None); } #[test] fn test_semver_comparisons() { // Normaler Versionssprung assert!(is_newer_version("0.5.0", "0.6.0")); assert!(is_newer_version("0.5.0", "v0.6.0")); assert!(is_newer_version("v0.5.0", "V0.5.1")); assert!(is_newer_version("0.5.0", "1.0.0")); // Gleiche Version assert!(!is_newer_version("0.6.0", "0.6.0")); assert!(!is_newer_version("0.6.0", "v0.6.0")); assert!(!is_newer_version("v0.6.0", "0.6.0")); // Ältere Version assert!(!is_newer_version("0.6.0", "0.5.0")); assert!(!is_newer_version("0.6.0", "v0.4.1")); // Parsing mit führenden 'v' / 'V' let v1 = parse_clean_version("v0.6.0").expect("Parse v0.6.0"); let v2 = parse_clean_version("V1.2.3").expect("Parse V1.2.3"); assert_eq!(v1.major, 0); assert_eq!(v1.minor, 6); assert_eq!(v2.major, 1); assert_eq!(v2.minor, 2); } #[test] fn test_package_manager_detection() { // Scoop Pfade let scoop_path = Path::new(r"C:\Users\harald\scoop\apps\sanctum\current\sanctum.exe"); assert_eq!( detect_package_manager_from_path(scoop_path), Some(PackageManager::Scoop) ); let scoop_shim = Path::new(r"C:\Users\harald\scoop\shims\sanctum.exe"); assert_eq!( detect_package_manager_from_path(scoop_shim), Some(PackageManager::Scoop) ); // Winget Pfade let winget_path = Path::new( r"C:\Users\harald\AppData\Local\Microsoft\WinGet\Packages\HaraldPansi.Sanctum_Microsoft.Winget.Source_8wekyb3d8bbwe\sanctum.exe", ); assert_eq!( detect_package_manager_from_path(winget_path), Some(PackageManager::Winget) ); // Standard Standalone Pfade (kein Paketmanager) let standalone = Path::new(r"C:\Tools\sanctum\sanctum.exe"); assert_eq!(detect_package_manager_from_path(standalone), None); let linux_usr = Path::new("/usr/local/bin/sanctum"); assert_eq!(detect_package_manager_from_path(linux_usr), None); } #[test] fn test_hash_integrity_calculation() { let test_file = std::env::temp_dir().join(format!("sanctum_test_{}.bin", std::process::id())); let payload = b"Sanctum Standalone Binary Payload for Integrity Testing"; { let mut f = File::create(&test_file).expect("create file"); f.write_all(payload).expect("write"); } let mut hasher = Sha256::new(); hasher.update(payload); let expected = hex::encode(hasher.finalize()); // Datei erneut lesen und hashen let mut reader = File::open(&test_file).expect("open"); let mut file_hasher = Sha256::new(); std::io::copy(&mut reader, &mut file_hasher).expect("copy"); let calculated = hex::encode(file_hasher.finalize()); assert_eq!(expected, calculated); let _ = std::fs::remove_file(&test_file); } #[test] fn test_json_deserialization_of_gitea_release() { let gitea_json = r##"{ "id": 27, "tag_name": "v0.5.0", "name": "Sanctum v0.5.0 (Windows x86_64)", "body": "Release v0.5.0 - sanctum sync", "html_url": "https://gitea.pansi.eu/harald/sanctum/releases/tag/v0.5.0", "published_at": "2026-09-16T10:44:18+02:00", "assets": [ { "id": 38, "name": "sanctum.exe", "size": 5467136, "browser_download_url": "https://gitea.pansi.eu/harald/sanctum/releases/download/v0.5.0/sanctum.exe" }, { "id": 40, "name": "sanctum", "size": 5033952, "browser_download_url": "https://gitea.pansi.eu/harald/sanctum/releases/download/v0.5.0/sanctum" }, { "id": 41, "name": "SHA256SUMS.txt", "size": 563, "browser_download_url": "https://gitea.pansi.eu/harald/sanctum/releases/download/v0.5.0/SHA256SUMS.txt" } ] }"##; let release: GiteaRelease = serde_json::from_str(gitea_json).expect("Deserialisierung erfolgreich"); assert_eq!(release.id, 27); assert_eq!(release.tag_name, "v0.5.0"); assert_eq!(release.assets.len(), 3); assert_eq!(release.assets[0].name, "sanctum.exe"); assert_eq!(release.assets[1].name, "sanctum"); assert_eq!(release.assets[2].name, "SHA256SUMS.txt"); }