use std::net::ToSocketAddrs;
use std::time::Instant;
const DEFAULT_PROXY_HOST: &str = "127.0.0.1";
const DEFAULT_PROXY_PORT: u16 = 7897;
const DEFAULT_API_URL: &str = "https://mvsep.com";
fn proxy_host() -> String {
std::env::var("MVSEP_PROXY_HOST").unwrap_or_else(|_| DEFAULT_PROXY_HOST.to_string())
}
fn proxy_port() -> u16 {
std::env::var("MVSEP_PROXY_PORT")
.ok()
.and_then(|v| v.parse().ok())
.unwrap_or(DEFAULT_PROXY_PORT)
}
fn api_url() -> String {
std::env::var("MVSEP_API_URL").unwrap_or_else(|_| DEFAULT_API_URL.to_string())
}
fn api_token() -> Option<String> {
std::env::var("MVSEP_API_TOKEN")
.ok()
.filter(|t| !t.is_empty())
}
fn build_proxy_client() -> reqwest::blocking::Client {
let proxy_url = format!("http://{}:{}", proxy_host(), proxy_port());
let proxy = reqwest::Proxy::all(&proxy_url).expect("Invalid proxy URL");
reqwest::blocking::Client::builder()
.proxy(proxy)
.timeout(std::time::Duration::from_secs(15))
.build()
.expect("Failed to build HTTP client")
}
#[test]
#[ignore]
fn test_tcp_connection() {
let host = proxy_host();
let port = proxy_port();
let addr = format!("{}:{}", host, port);
let socket_addrs: Vec<_> = addr
.to_socket_addrs()
.expect("DNS resolution failed")
.collect();
assert!(!socket_addrs.is_empty(), "No addresses resolved for proxy");
let resolved = socket_addrs[0];
let connected =
std::net::TcpStream::connect_timeout(&resolved, std::time::Duration::from_secs(5));
assert!(
connected.is_ok(),
"TCP connection to proxy {} failed: {:?}",
resolved,
connected.err()
);
}
#[test]
#[ignore]
fn test_dns_resolution() {
let addrs: Vec<_> = format!("{}:443", "mvsep.com")
.to_socket_addrs()
.expect("DNS resolution failed")
.collect();
assert!(!addrs.is_empty(), "Failed to resolve mvsep.com");
}
#[test]
#[ignore]
fn test_generic_http_via_proxy() {
let client = build_proxy_client();
let test_urls = [
("httpbin.org/ip", "https://httpbin.org/ip"),
("ip-api.com/json", "http://ip-api.com/json"),
];
let mut any_ok = false;
for (name, url) in &test_urls {
match client
.get(*url)
.timeout(std::time::Duration::from_secs(8))
.send()
{
Ok(resp) if resp.status().is_success() => {
println!(" ✅ {} responded", name);
any_ok = true;
break;
}
Ok(resp) => println!(" ⚠️ {} HTTP {}", name, resp.status()),
Err(e) => println!(" ❌ {} {}", name, e),
}
}
assert!(any_ok, "All generic HTTP tests failed — proxy may be down");
}
#[test]
#[ignore]
fn test_get_algorithms() {
let client = build_proxy_client();
let url = format!("{}/api/app/algorithms?scopes=single_upload", api_url());
let resp = client.get(&url).send().expect("GET /app/algorithms failed");
assert!(resp.status().is_success(), "HTTP {}", resp.status());
let body: serde_json::Value = resp.json().expect("Invalid JSON response");
let algorithms = body.as_array().expect("Expected array response");
assert!(!algorithms.is_empty(), "Algorithm list is empty");
println!(" ✅ {} algorithms loaded", algorithms.len());
if let Some(name) = algorithms[0].get("name").and_then(|v| v.as_str()) {
println!(" First: {}", name);
}
}
#[test]
#[ignore]
fn test_queue_status() {
let token = api_token().expect("MVSEP_API_TOKEN not set (required for this test)");
let client = build_proxy_client();
let url = format!("{}/api/app/queue", api_url());
let resp = client
.get(&url)
.query(&[("api_token", &token)])
.send()
.expect("GET /queue failed");
assert!(resp.status().is_success(), "HTTP {}", resp.status());
let body: serde_json::Value = resp.json().expect("Invalid JSON");
println!(" ✅ Queue info: {}", body);
}
#[test]
#[ignore]
fn test_user_info() {
let token = api_token().expect("MVSEP_API_TOKEN not set (required for this test)");
let client = build_proxy_client();
let url = format!("{}/api/app/user?api_token={}", api_url(), token);
let resp = client.get(&url).send().expect("GET /user failed");
assert!(resp.status().is_success(), "HTTP {}", resp.status());
let body: serde_json::Value = resp.json().expect("Invalid JSON");
let data = body.get("data").or(Some(&body));
if let Some(d) = data {
let name = d.get("name").and_then(|v| v.as_str()).unwrap_or("?");
let plan = d.get("plan").and_then(|v| v.as_str()).unwrap_or("free");
println!(" ✅ User: {} (Plan: {})", name, plan);
}
}
#[test]
#[ignore]
fn test_toggle_premium() {
let token = api_token().expect("MVSEP_API_TOKEN not set (required for this test)");
let client = build_proxy_client();
for (endpoint, label) in &[
("/app/enable_premium", "Enable Premium"),
("/app/disable_premium", "Disable Premium"),
] {
let url = format!("{}/api{}", api_url(), endpoint);
let form = reqwest::blocking::multipart::Form::new().text("api_token", token.clone());
let resp = client
.post(&url)
.multipart(form)
.send()
.unwrap_or_else(|_| panic!("POST {} failed", endpoint));
assert!(
resp.status().is_success(),
"{} HTTP {}",
label,
resp.status()
);
println!(" ✅ {}", label);
}
}
#[test]
#[ignore]
fn test_toggle_long_filenames() {
let token = api_token().expect("MVSEP_API_TOKEN not set (required for this test)");
let client = build_proxy_client();
for (endpoint, label) in &[
("/app/enable_long_filenames", "Enable Long Filenames"),
("/app/disable_long_filenames", "Disable Long Filenames"),
] {
let url = format!("{}/api{}", api_url(), endpoint);
let form = reqwest::blocking::multipart::Form::new().text("api_token", token.clone());
let resp = client
.post(&url)
.multipart(form)
.send()
.unwrap_or_else(|_| panic!("POST {} failed", endpoint));
assert!(
resp.status().is_success(),
"{} HTTP {}",
label,
resp.status()
);
println!(" ✅ {}", label);
}
}
#[test]
#[ignore]
fn test_full_proxy_coverage() {
println!("\n═══ Full Proxy Coverage Test ═══");
let host = proxy_host();
let port = proxy_port();
let t = Instant::now();
let addrs: Vec<_> = format!("{}:{}", host, port)
.to_socket_addrs()
.expect("DNS resolution failed")
.collect();
assert!(!addrs.is_empty(), "No addresses resolved");
println!(" ✅ DNS ({}ms)", t.elapsed().as_millis());
let t = Instant::now();
let connected =
std::net::TcpStream::connect_timeout(&addrs[0], std::time::Duration::from_secs(5));
assert!(connected.is_ok(), "TCP connection failed");
println!(" ✅ TCP ({}ms)", t.elapsed().as_millis());
let t = Instant::now();
let client = build_proxy_client();
let resp = client
.get("https://httpbin.org/ip")
.timeout(std::time::Duration::from_secs(8))
.send();
assert!(resp.is_ok(), "HTTP via proxy failed: {:?}", resp.err());
println!(" ✅ HTTP via proxy ({}ms)", t.elapsed().as_millis());
let t = Instant::now();
let url = format!("{}/api/app/algorithms?scopes=single_upload", api_url());
let resp = client.get(&url).send().expect("GET algorithms failed");
assert!(resp.status().is_success(), "HTTP {}", resp.status());
println!(" ✅ API algorithms ({}ms)", t.elapsed().as_millis());
if let Some(token) = api_token() {
let t = Instant::now();
let url = format!("{}/api/app/user?api_token={}", api_url(), token);
let resp = client.get(&url).send().expect("GET user failed");
assert!(resp.status().is_success(), "HTTP {}", resp.status());
println!(" ✅ API user info ({}ms)", t.elapsed().as_millis());
} else {
println!(" ⏭️ API user info (no token)");
}
println!("═══ All proxy tests passed ═══");
}