#[path = "../src/models.rs"] mod models; #[path = "../src/subscription.rs"] mod subscription; use base64::{engine::general_purpose, Engine}; use models::redact_subscription_url; use subscription::{parse_subscription_body, parse_user_info}; #[test] fn parses_singbox_json_config_servers() { let parsed = parse_subscription_body( r#"{ "outbounds": [ { "type": "direct", "tag": "direct" }, { "type": "vless", "tag": "nl-1", "server": "nl.example.test", "server_port": 443 }, { "type": "trojan", "tag": "de-1", "server": "de.example.test", "server_port": 8443 } ] }"#, ) .expect("json subscription should parse"); assert_eq!(parsed.servers.len(), 2); assert_eq!(parsed.servers[0].tag, "nl-1"); assert_eq!(parsed.servers[0].server_type, "vless"); assert_eq!(parsed.servers[1].server_port, 8443); } #[test] fn parses_base64_vless_link_list() { let link = sample_vless_link("nl-1"); let encoded = general_purpose::STANDARD.encode(format!("{link}\n")); let parsed = parse_subscription_body(&encoded).expect("base64 vless list should parse"); let outbound = &parsed.config["outbounds"][0]; assert_eq!(parsed.servers.len(), 1); assert_eq!(parsed.servers[0].tag, "nl-1"); assert_eq!(outbound["type"], "vless"); assert_eq!(outbound["server"], "nl.example.test"); assert_eq!(outbound["packet_encoding"], "xudp"); } #[test] fn rejects_body_without_supported_outbounds() { let error = parse_subscription_body(r#"{"outbounds":[{"type":"direct","tag":"direct"}]}"#) .expect_err("unsupported subscription should fail"); assert!(error.message.contains("No supported proxy outbounds found")); } #[test] fn rejects_vless_without_reality_parameters() { let error = parse_subscription_body("vless://uuid@nl.example.test:443#nl-1") .expect_err("missing reality params should fail"); assert!(error.message.contains("pbk and sid")); } #[test] fn parses_subscription_user_info_header() { let user_info = parse_user_info(Some("upload=10; download=20; total=30; expire=bad")); assert_eq!(user_info["upload"], 10); assert_eq!(user_info["download"], 20); assert_eq!(user_info["total"], 30); assert!(!user_info.contains_key("expire")); } #[test] fn rejects_invalid_or_non_http_subscription_url_before_network() { let invalid = subscription::fetch_subscription("not a url") .expect_err("invalid url should fail before request"); let unsupported = subscription::fetch_subscription("file:///C:/subscription.txt") .expect_err("non-http url should fail before request"); assert!(invalid.message.contains("Invalid subscription URL")); assert!(unsupported.message.contains("http or https")); } #[test] fn redacts_subscription_url_for_display() { assert_eq!( redact_subscription_url("https://sub.example.test/path?token=secret"), "https://sub.example.test/..." ); assert_eq!( redact_subscription_url("vless://uuid@example.test"), "vless://uuid@example.test/..." ); } fn sample_vless_link(tag: &str) -> String { format!( "vless://{}@nl.example.test:443?security=reality&sni=example.test&fp=chrome&pbk=public-key&sid=short-id&flow=xtls-rprx-vision#{}", "11111111-1111-1111-1111-111111111111", tag ) }