Expand README with architecture and setup details
This commit is contained in:
128
src-tauri/tests/singbox_service_tests.rs
Normal file
128
src-tauri/tests/singbox_service_tests.rs
Normal file
@@ -0,0 +1,128 @@
|
||||
#[path = "../src/component_detection.rs"]
|
||||
mod component_detection;
|
||||
#[path = "../src/models.rs"]
|
||||
mod models;
|
||||
#[path = "../src/singbox_service.rs"]
|
||||
mod singbox_service;
|
||||
|
||||
use component_detection::DetectedSingBox;
|
||||
use singbox_service::{
|
||||
build_singbox_setup_status, ensure_safe_singbox_install_dir, parse_service_command_output,
|
||||
service_control_script, SingBoxServiceAction,
|
||||
};
|
||||
use std::path::{Path, PathBuf};
|
||||
#[cfg(windows)]
|
||||
use std::process::Command as ProcessCommand;
|
||||
|
||||
#[test]
|
||||
fn setup_status_reports_missing_items_when_singbox_is_absent() {
|
||||
let status = build_singbox_setup_status(None);
|
||||
|
||||
assert!(!status.ready);
|
||||
assert_eq!(status.missing_count, 3);
|
||||
assert_eq!(status.items[0].id, "sing-box-binary");
|
||||
assert!(status.items[0].details.contains("SagerNet/sing-box"));
|
||||
assert_eq!(status.items[1].id, "winsw-wrapper");
|
||||
assert!(status.items[1].details.contains("winsw/winsw"));
|
||||
assert_eq!(status.items[2].id, "windows-service");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_status_reports_ready_when_binary_wrapper_and_service_exist() {
|
||||
let detected = detected_singbox(true, true, true);
|
||||
let status = build_singbox_setup_status(Some(&detected));
|
||||
|
||||
assert!(status.ready);
|
||||
assert_eq!(status.missing_count, 0);
|
||||
assert!(status.items.iter().all(|item| item.installed));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn parses_last_json_service_command_output_line() {
|
||||
let output = br#"
|
||||
noise
|
||||
{"success":true,"code":"started","serviceName":"ProxyWardenSingBox","status":"Running","processId":42}
|
||||
"#;
|
||||
let parsed = parse_service_command_output(output).expect("service json should parse");
|
||||
|
||||
assert!(parsed.success);
|
||||
assert_eq!(parsed.code, "started");
|
||||
assert_eq!(parsed.service_name, Some("ProxyWardenSingBox".to_string()));
|
||||
assert_eq!(parsed.status, Some("Running".to_string()));
|
||||
assert_eq!(parsed.process_id, Some(42));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn safe_install_dir_allows_only_proxywarden_singbox_folder() {
|
||||
assert!(
|
||||
ensure_safe_singbox_install_dir(Path::new(r"C:\Program Files\ProxyWarden\sing-box")).is_ok()
|
||||
);
|
||||
assert!(ensure_safe_singbox_install_dir(Path::new(r"C:\Windows")).is_err());
|
||||
assert!(ensure_safe_singbox_install_dir(Path::new(r"C:\Program Files\sing-box")).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn service_control_script_targets_named_service_and_action() {
|
||||
let script = service_control_script(SingBoxServiceAction::Start, "ProxyWardenSingBox", None, None);
|
||||
|
||||
assert!(script.contains("$serviceName = 'ProxyWardenSingBox'"));
|
||||
assert!(script.contains("$action = 'start'"));
|
||||
assert!(script.contains("ConvertTo-Json -Compress"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn service_control_script_syncs_generated_config_before_start() {
|
||||
let source = Path::new(r"C:\ProgramData\ProxyWarden\generated\sing-box-config.json");
|
||||
let target = Path::new(r"C:\Program Files\ProxyWarden\sing-box\config.json");
|
||||
let script = service_control_script(
|
||||
SingBoxServiceAction::Start,
|
||||
"ProxyWardenSingBox",
|
||||
Some(source),
|
||||
Some(target),
|
||||
);
|
||||
|
||||
assert!(script.contains(
|
||||
"$configSource = 'C:\\ProgramData\\ProxyWarden\\generated\\sing-box-config.json'"
|
||||
));
|
||||
assert!(script.contains(
|
||||
"$configTarget = 'C:\\Program Files\\ProxyWarden\\sing-box\\config.json'"
|
||||
));
|
||||
assert!(script.contains("Copy-Item -LiteralPath $configSource"));
|
||||
assert!(script.contains("'config_sync_failed'"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(windows)]
|
||||
fn install_singbox_script_parses_as_powershell() {
|
||||
let script_path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.join("..")
|
||||
.join("scripts")
|
||||
.join("install-singbox.ps1");
|
||||
let escaped_path = script_path.display().to_string().replace('\'', "''");
|
||||
let parser = format!(
|
||||
"$tokens = $null; $errors = $null; [System.Management.Automation.Language.Parser]::ParseFile('{escaped_path}', [ref]$tokens, [ref]$errors) | Out-Null; if ($errors.Count -gt 0) {{ $errors | ForEach-Object {{ $_.Message }}; exit 1 }}"
|
||||
);
|
||||
let output = ProcessCommand::new("powershell")
|
||||
.args(["-NoProfile", "-NonInteractive", "-Command", &parser])
|
||||
.output()
|
||||
.expect("powershell parser should run");
|
||||
|
||||
assert!(
|
||||
output.status.success(),
|
||||
"install-singbox.ps1 should parse\nstdout:\n{}\nstderr:\n{}",
|
||||
String::from_utf8_lossy(&output.stdout),
|
||||
String::from_utf8_lossy(&output.stderr),
|
||||
);
|
||||
}
|
||||
|
||||
fn detected_singbox(binary_exists: bool, wrapper_exists: bool, running: bool) -> DetectedSingBox {
|
||||
DetectedSingBox {
|
||||
install_dir: PathBuf::from(r"C:\Program Files\ProxyWarden\sing-box"),
|
||||
executable_path: PathBuf::from(r"C:\Program Files\ProxyWarden\sing-box\sing-box.exe"),
|
||||
wrapper_path: PathBuf::from(r"C:\Program Files\ProxyWarden\sing-box\ProxyWardenSingBox.exe"),
|
||||
binary_exists,
|
||||
wrapper_exists,
|
||||
running,
|
||||
service_name: "ProxyWardenSingBox".to_string(),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user