|
| 1 | +import XCTest |
| 2 | +@testable import ShadowSpaceKit |
| 3 | + |
| 4 | +final class AnyTLSTests: XCTestCase { |
| 5 | + |
| 6 | + func testParseAnyTLSURI() throws { |
| 7 | + let node = try XCTUnwrap(URIParser.parseAnyTLS( |
| 8 | + "anytls://mypassword@anytls.example.com:8443?sni=example.com&insecure=1#AnyTLS-Node")) |
| 9 | + XCTAssertEqual(node.proto, .anytls) |
| 10 | + XCTAssertEqual(node.name, "AnyTLS-Node") |
| 11 | + XCTAssertEqual(node.server, "anytls.example.com") |
| 12 | + XCTAssertEqual(node.port, 8443) |
| 13 | + XCTAssertEqual(node.password, "mypassword") |
| 14 | + XCTAssertTrue(node.tls) |
| 15 | + XCTAssertEqual(node.sni, "example.com") |
| 16 | + XCTAssertTrue(node.insecure) |
| 17 | + } |
| 18 | + |
| 19 | + func testParseAnyTLSViaGenericEntry() { |
| 20 | + // 經由 URIParser.parse 分派 |
| 21 | + let node = URIParser.parse("anytls://pw@h.com:443#x") |
| 22 | + XCTAssertEqual(node?.proto, .anytls) |
| 23 | + } |
| 24 | + |
| 25 | + func testClashAnyTLS() throws { |
| 26 | + let yaml = """ |
| 27 | + proxies: |
| 28 | + - name: AnyTLS-A |
| 29 | + type: anytls |
| 30 | + server: a.example.com |
| 31 | + port: 443 |
| 32 | + password: secret |
| 33 | + sni: a.example.com |
| 34 | + skip-cert-verify: true |
| 35 | + """ |
| 36 | + let node = try XCTUnwrap(ClashYAMLParser.parse(yaml).first) |
| 37 | + XCTAssertEqual(node.proto, .anytls) |
| 38 | + XCTAssertEqual(node.password, "secret") |
| 39 | + XCTAssertTrue(node.tls) |
| 40 | + XCTAssertTrue(node.insecure) |
| 41 | + } |
| 42 | + |
| 43 | + func testShareLinkRoundTrip() throws { |
| 44 | + let original = try XCTUnwrap(URIParser.parseAnyTLS( |
| 45 | + "anytls://pw123@srv.example.com:8443?sni=srv.example.com#Node")) |
| 46 | + let link = try XCTUnwrap(NodeShare.uri(for: original)) |
| 47 | + XCTAssertTrue(link.hasPrefix("anytls://")) |
| 48 | + let parsed = try XCTUnwrap(URIParser.parse(link)) |
| 49 | + XCTAssertEqual(parsed.proto, .anytls) |
| 50 | + XCTAssertEqual(parsed.password, "pw123") |
| 51 | + XCTAssertEqual(parsed.server, "srv.example.com") |
| 52 | + XCTAssertEqual(parsed.sni, "srv.example.com") |
| 53 | + } |
| 54 | + |
| 55 | + /// 產出含 anytls outbound 的 sing-box 設定,欄位正確,並寫到 /tmp 供 `sing-box check`。 |
| 56 | + func testAnyTLSConfigStructureAndDump() throws { |
| 57 | + let node = try XCTUnwrap(URIParser.parseAnyTLS( |
| 58 | + "anytls://mypassword@anytls.example.com:8443?sni=example.com&insecure=1#AnyTLS")) |
| 59 | + let result = SingBoxConfigBuilder.build( |
| 60 | + nodes: [node], selectedID: node.id, settings: AppSettings(), mode: .rule) |
| 61 | + let data = try SingBoxConfigBuilder.jsonData(result.json) |
| 62 | + let obj = try XCTUnwrap(try JSONSerialization.jsonObject(with: data) as? [String: Any]) |
| 63 | + let outbounds = try XCTUnwrap(obj["outbounds"] as? [[String: Any]]) |
| 64 | + let anytls = try XCTUnwrap(outbounds.first { $0["type"] as? String == "anytls" }) |
| 65 | + XCTAssertEqual(anytls["password"] as? String, "mypassword") |
| 66 | + XCTAssertEqual(anytls["server"] as? String, "anytls.example.com") |
| 67 | + XCTAssertEqual(anytls["server_port"] as? Int, 8443) |
| 68 | + let tls = try XCTUnwrap(anytls["tls"] as? [String: Any]) |
| 69 | + XCTAssertEqual(tls["enabled"] as? Bool, true) |
| 70 | + XCTAssertEqual(tls["server_name"] as? String, "example.com") |
| 71 | + XCTAssertEqual(tls["insecure"] as? Bool, true) |
| 72 | + try data.write(to: URL(fileURLWithPath: "/tmp/shadowspace-anytls-check.json")) |
| 73 | + } |
| 74 | +} |
0 commit comments