Clarify active Windows client architecture
This commit is contained in:
178
apps/windows-client/src-tauri/tests/proxifyre_adapter_tests.rs
Normal file
178
apps/windows-client/src-tauri/tests/proxifyre_adapter_tests.rs
Normal file
@@ -0,0 +1,178 @@
|
||||
#[path = "../src/models.rs"]
|
||||
mod models;
|
||||
#[path = "../src/adapters/proxy_router.rs"]
|
||||
mod proxy_router;
|
||||
#[path = "../src/adapters/proxifyre.rs"]
|
||||
mod proxifyre;
|
||||
|
||||
use models::{
|
||||
ComponentId, ComponentState, ComponentStatus, Profile, ProfileItem, ProfileItemType, Protocol,
|
||||
ProxyProtocol, Target, TargetKind,
|
||||
};
|
||||
use proxifyre::{ProxiFyreAdapter, ProxiFyreConfig, PROXIFYRE_OUTPUT_FILE};
|
||||
use proxy_router::{ProxyRouterAdapter, ProxyRouterErrorKind, ProxyRouterRequest};
|
||||
|
||||
#[test]
|
||||
fn generates_proxifyre_config_for_discord_external_socks5_target() {
|
||||
let adapter = ProxiFyreAdapter::default();
|
||||
let profiles = vec![discord_profile("home-gateway")];
|
||||
let targets = vec![external_socks5_target()];
|
||||
let components = vec![missing_singbox_component()];
|
||||
|
||||
let generated = adapter
|
||||
.generate_config(ProxyRouterRequest::new(&profiles, &targets, &components))
|
||||
.expect("external socks5 target should not require sing-box");
|
||||
let config: ProxiFyreConfig =
|
||||
serde_json::from_str(&generated.contents).expect("generated config json");
|
||||
|
||||
assert_eq!(generated.adapter_id, "proxifyre");
|
||||
assert_eq!(generated.output_file_name, PROXIFYRE_OUTPUT_FILE);
|
||||
assert_eq!(generated.enabled_profiles, 1);
|
||||
assert_eq!(generated.routed_apps, 1);
|
||||
assert_eq!(config.log_level, "Info");
|
||||
assert!(config.bypass_lan);
|
||||
assert_eq!(config.proxies.len(), 1);
|
||||
assert_eq!(config.proxies[0].app_names, vec!["Discord"]);
|
||||
assert_eq!(config.proxies[0].socks5_proxy_endpoint, "192.168.50.111:8080");
|
||||
assert_eq!(config.proxies[0].supported_protocols, vec!["TCP", "UDP"]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn skips_disabled_profiles_when_generating_proxifyre_config() {
|
||||
let adapter = ProxiFyreAdapter::default();
|
||||
let mut disabled = discord_profile("home-gateway");
|
||||
disabled.enabled = false;
|
||||
let profiles = vec![disabled];
|
||||
let targets = vec![external_socks5_target()];
|
||||
let components = Vec::new();
|
||||
|
||||
let generated = adapter
|
||||
.generate_config(ProxyRouterRequest::new(&profiles, &targets, &components))
|
||||
.expect("disabled profiles should produce empty config");
|
||||
let config: ProxiFyreConfig =
|
||||
serde_json::from_str(&generated.contents).expect("generated config json");
|
||||
|
||||
assert_eq!(generated.enabled_profiles, 0);
|
||||
assert_eq!(generated.routed_apps, 0);
|
||||
assert!(config.proxies.is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn blocks_local_singbox_target_when_required_component_is_missing() {
|
||||
let adapter = ProxiFyreAdapter::default();
|
||||
let profiles = vec![discord_profile("local-singbox")];
|
||||
let targets = vec![local_singbox_target()];
|
||||
let components = Vec::new();
|
||||
|
||||
let error = adapter
|
||||
.generate_config(ProxyRouterRequest::new(&profiles, &targets, &components))
|
||||
.expect_err("local sing-box target should require installed running sing-box");
|
||||
|
||||
assert_eq!(error.kind, ProxyRouterErrorKind::MissingRequiredComponent);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_singbox_target_generates_when_required_component_is_running() {
|
||||
let adapter = ProxiFyreAdapter::default();
|
||||
let profiles = vec![discord_profile("local-singbox")];
|
||||
let targets = vec![local_singbox_target()];
|
||||
let components = vec![running_singbox_component()];
|
||||
|
||||
let generated = adapter
|
||||
.generate_config(ProxyRouterRequest::new(&profiles, &targets, &components))
|
||||
.expect("running sing-box should satisfy local target dependency");
|
||||
let config: ProxiFyreConfig =
|
||||
serde_json::from_str(&generated.contents).expect("generated config json");
|
||||
|
||||
assert_eq!(config.proxies.len(), 1);
|
||||
assert_eq!(config.proxies[0].socks5_proxy_endpoint, "127.0.0.1:1080");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn rejects_http_target_because_proxifyre_adapter_is_socks5_only() {
|
||||
let adapter = ProxiFyreAdapter::default();
|
||||
let profiles = vec![discord_profile("office-http")];
|
||||
let targets = vec![Target {
|
||||
id: "office-http".to_string(),
|
||||
name: "Office HTTP".to_string(),
|
||||
kind: TargetKind::External,
|
||||
protocol: ProxyProtocol::Http,
|
||||
host: "192.168.50.111".to_string(),
|
||||
port: 3128,
|
||||
requires_component: None,
|
||||
}];
|
||||
let components = Vec::new();
|
||||
|
||||
let error = adapter
|
||||
.generate_config(ProxyRouterRequest::new(&profiles, &targets, &components))
|
||||
.expect_err("ProxiFyre should reject HTTP targets");
|
||||
|
||||
assert_eq!(error.kind, ProxyRouterErrorKind::UnsupportedTargetProtocol);
|
||||
}
|
||||
|
||||
fn discord_profile(target_id: &str) -> Profile {
|
||||
Profile {
|
||||
id: "discord".to_string(),
|
||||
name: "Discord".to_string(),
|
||||
enabled: true,
|
||||
target_id: target_id.to_string(),
|
||||
protocols: vec![Protocol::Tcp, Protocol::Udp],
|
||||
items: vec![ProfileItem {
|
||||
item_type: ProfileItemType::Process,
|
||||
value: "Discord".to_string(),
|
||||
recursive: false,
|
||||
}],
|
||||
}
|
||||
}
|
||||
|
||||
fn external_socks5_target() -> Target {
|
||||
Target {
|
||||
id: "home-gateway".to_string(),
|
||||
name: "Home Gateway".to_string(),
|
||||
kind: TargetKind::External,
|
||||
protocol: ProxyProtocol::Socks5,
|
||||
host: "192.168.50.111".to_string(),
|
||||
port: 8080,
|
||||
requires_component: None,
|
||||
}
|
||||
}
|
||||
|
||||
fn local_singbox_target() -> Target {
|
||||
Target {
|
||||
id: "local-singbox".to_string(),
|
||||
name: "Local sing-box".to_string(),
|
||||
kind: TargetKind::Local,
|
||||
protocol: ProxyProtocol::Socks5,
|
||||
host: "127.0.0.1".to_string(),
|
||||
port: 1080,
|
||||
requires_component: Some(ComponentId::Singbox),
|
||||
}
|
||||
}
|
||||
|
||||
fn missing_singbox_component() -> ComponentStatus {
|
||||
ComponentStatus {
|
||||
id: ComponentId::Singbox,
|
||||
name: "Local sing-box".to_string(),
|
||||
state: ComponentState::Missing,
|
||||
installed: false,
|
||||
running: false,
|
||||
version: None,
|
||||
path: None,
|
||||
problems: vec!["Local sing-box is not installed".to_string()],
|
||||
actions: vec!["Install Local sing-box".to_string()],
|
||||
}
|
||||
}
|
||||
|
||||
fn running_singbox_component() -> ComponentStatus {
|
||||
ComponentStatus {
|
||||
id: ComponentId::Singbox,
|
||||
name: "Local sing-box".to_string(),
|
||||
state: ComponentState::Running,
|
||||
installed: true,
|
||||
running: true,
|
||||
version: Some("1.11.0".to_string()),
|
||||
path: Some(r"C:\Tools\VpnProxy\sing-box\sing-box.exe".to_string()),
|
||||
problems: Vec::new(),
|
||||
actions: vec!["Restart".to_string(), "Stop".to_string()],
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user