Просмотр исходного кода

test(frontend): broaden golden coverage to remaining inbounds + stream + security DUs

Round out Step 3b. Four more inbound fixtures complete the protocol set
(http with two accounts, mixed with socks-style auth, tunnel with a port
map, hysteria v1). Two parallel test files cover the other DUs:
stream.test.ts walks tcp/ws/grpc fixtures through NetworkSettingsSchema,
and security.test.ts walks none/tls/reality through SecuritySettingsSchema.

Snapshot count is now 16 across three test files. The reality fixture
locks in the array form of serverNames/shortIds (the panel class stores
them comma-joined internally but they ship as arrays on the wire). The
TLS fixture pins the file-vs-inline cert DU on the file branch.

Stream coverage for httpupgrade/xhttp/kcp and security mixed-with-stream
combos follow in the next turn, alongside the shadow harness.
MHSanaei 22 часов назад
Родитель
Сommit
2176e816f0

+ 75 - 0
frontend/src/test/__snapshots__/protocols.test.ts.snap

@@ -1,5 +1,47 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
+exports[`InboundSettingsSchema fixtures > parses http-basic byte-stably 1`] = `
+{
+  "protocol": "http",
+  "settings": {
+    "accounts": [
+      {
+        "pass": "proxypass",
+        "user": "proxyuser",
+      },
+      {
+        "pass": "guest123",
+        "user": "guest",
+      },
+    ],
+    "allowTransparent": false,
+  },
+}
+`;
+
+exports[`InboundSettingsSchema fixtures > parses hysteria-basic byte-stably 1`] = `
+{
+  "protocol": "hysteria",
+  "settings": {
+    "clients": [
+      {
+        "auth": "hyst3ria-v1-token-XYZ",
+        "comment": "legacy v1",
+        "email": "[email protected]",
+        "enable": true,
+        "expiryTime": 0,
+        "limitIp": 0,
+        "reset": 0,
+        "subId": "hy1-001",
+        "tgId": 0,
+        "totalGB": 0,
+      },
+    ],
+    "version": 1,
+  },
+}
+`;
+
 exports[`InboundSettingsSchema fixtures > parses hysteria2-basic byte-stably 1`] = `
 {
   "protocol": "hysteria2",
@@ -23,6 +65,23 @@ exports[`InboundSettingsSchema fixtures > parses hysteria2-basic byte-stably 1`]
 }
 `;
 
+exports[`InboundSettingsSchema fixtures > parses mixed-basic byte-stably 1`] = `
+{
+  "protocol": "mixed",
+  "settings": {
+    "accounts": [
+      {
+        "pass": "sockspass",
+        "user": "socksuser",
+      },
+    ],
+    "auth": "password",
+    "ip": "127.0.0.1",
+    "udp": true,
+  },
+}
+`;
+
 exports[`InboundSettingsSchema fixtures > parses shadowsocks-2022 byte-stably 1`] = `
 {
   "protocol": "shadowsocks",
@@ -73,6 +132,22 @@ exports[`InboundSettingsSchema fixtures > parses trojan-basic byte-stably 1`] =
 }
 `;
 
+exports[`InboundSettingsSchema fixtures > parses tunnel-basic byte-stably 1`] = `
+{
+  "protocol": "tunnel",
+  "settings": {
+    "allowedNetwork": "tcp,udp",
+    "followRedirect": false,
+    "portMap": {
+      "8080": "10.0.0.5:80",
+      "8443": "10.0.0.5:443",
+    },
+    "rewriteAddress": "1.1.1.1",
+    "rewritePort": 53,
+  },
+}
+`;
+
 exports[`InboundSettingsSchema fixtures > parses vless-tcp-none byte-stably 1`] = `
 {
   "protocol": "vless",

+ 72 - 0
frontend/src/test/__snapshots__/security.test.ts.snap

@@ -0,0 +1,72 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`SecuritySettingsSchema fixtures > parses none byte-stably 1`] = `
+{
+  "security": "none",
+}
+`;
+
+exports[`SecuritySettingsSchema fixtures > parses reality-basic byte-stably 1`] = `
+{
+  "realitySettings": {
+    "maxClientVer": "",
+    "maxTimediff": 0,
+    "minClientVer": "",
+    "mldsa65Seed": "",
+    "privateKey": "wM-2_oQRWXyLcXhV5q1ifTBcS3K8mYR3wQI3PqGFK1k",
+    "serverNames": [
+      "yahoo.com",
+      "www.yahoo.com",
+    ],
+    "settings": {
+      "fingerprint": "chrome",
+      "mldsa65Verify": "",
+      "publicKey": "Tx5yj1bRcOPHkdvT2pIAQ2zh0gQ8m4OPdnzqXJxxV3o",
+      "serverName": "",
+      "spiderX": "/",
+    },
+    "shortIds": [
+      "a3f1",
+      "b8c2",
+      "d9e4",
+    ],
+    "show": false,
+    "target": "yahoo.com:443",
+    "xver": 0,
+  },
+  "security": "reality",
+}
+`;
+
+exports[`SecuritySettingsSchema fixtures > parses tls-cert-file byte-stably 1`] = `
+{
+  "security": "tls",
+  "tlsSettings": {
+    "alpn": [
+      "h2",
+      "http/1.1",
+    ],
+    "certificates": [
+      {
+        "buildChain": false,
+        "certificateFile": "/etc/ssl/certs/cdn.example.test.crt",
+        "keyFile": "/etc/ssl/private/cdn.example.test.key",
+        "oneTimeLoading": false,
+        "usage": "encipherment",
+      },
+    ],
+    "cipherSuites": "",
+    "disableSystemRoot": false,
+    "echServerKeys": "",
+    "enableSessionResumption": false,
+    "maxVersion": "1.3",
+    "minVersion": "1.2",
+    "rejectUnknownSni": false,
+    "serverName": "cdn.example.test",
+    "settings": {
+      "echConfigList": "",
+      "fingerprint": "chrome",
+    },
+  },
+}
+`;

+ 34 - 0
frontend/src/test/__snapshots__/stream.test.ts.snap

@@ -0,0 +1,34 @@
+// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
+
+exports[`NetworkSettingsSchema fixtures > parses grpc-basic byte-stably 1`] = `
+{
+  "grpcSettings": {
+    "authority": "grpc.example.test",
+    "multiMode": false,
+    "serviceName": "GunService",
+  },
+  "network": "grpc",
+}
+`;
+
+exports[`NetworkSettingsSchema fixtures > parses tcp-none byte-stably 1`] = `
+{
+  "network": "tcp",
+  "tcpSettings": {},
+}
+`;
+
+exports[`NetworkSettingsSchema fixtures > parses ws-default byte-stably 1`] = `
+{
+  "network": "ws",
+  "wsSettings": {
+    "acceptProxyProtocol": false,
+    "headers": {
+      "X-Forwarded-Proto": "https",
+    },
+    "heartbeatPeriod": 30,
+    "host": "cdn.example.test",
+    "path": "/api/v2",
+  },
+}
+`;

+ 10 - 0
frontend/src/test/golden/fixtures/inbound/http-basic.json

@@ -0,0 +1,10 @@
+{
+  "protocol": "http",
+  "settings": {
+    "accounts": [
+      { "user": "proxyuser", "pass": "proxypass" },
+      { "user": "guest", "pass": "guest123" }
+    ],
+    "allowTransparent": false
+  }
+}

+ 20 - 0
frontend/src/test/golden/fixtures/inbound/hysteria-basic.json

@@ -0,0 +1,20 @@
+{
+  "protocol": "hysteria",
+  "settings": {
+    "version": 1,
+    "clients": [
+      {
+        "auth": "hyst3ria-v1-token-XYZ",
+        "email": "[email protected]",
+        "limitIp": 0,
+        "totalGB": 0,
+        "expiryTime": 0,
+        "enable": true,
+        "tgId": 0,
+        "subId": "hy1-001",
+        "comment": "legacy v1",
+        "reset": 0
+      }
+    ]
+  }
+}

+ 11 - 0
frontend/src/test/golden/fixtures/inbound/mixed-basic.json

@@ -0,0 +1,11 @@
+{
+  "protocol": "mixed",
+  "settings": {
+    "auth": "password",
+    "accounts": [
+      { "user": "socksuser", "pass": "sockspass" }
+    ],
+    "udp": true,
+    "ip": "127.0.0.1"
+  }
+}

+ 13 - 0
frontend/src/test/golden/fixtures/inbound/tunnel-basic.json

@@ -0,0 +1,13 @@
+{
+  "protocol": "tunnel",
+  "settings": {
+    "rewriteAddress": "1.1.1.1",
+    "rewritePort": 53,
+    "portMap": {
+      "8080": "10.0.0.5:80",
+      "8443": "10.0.0.5:443"
+    },
+    "allowedNetwork": "tcp,udp",
+    "followRedirect": false
+  }
+}

+ 3 - 0
frontend/src/test/golden/fixtures/security/none.json

@@ -0,0 +1,3 @@
+{
+  "security": "none"
+}

+ 22 - 0
frontend/src/test/golden/fixtures/security/reality-basic.json

@@ -0,0 +1,22 @@
+{
+  "security": "reality",
+  "realitySettings": {
+    "show": false,
+    "xver": 0,
+    "target": "yahoo.com:443",
+    "serverNames": ["yahoo.com", "www.yahoo.com"],
+    "privateKey": "wM-2_oQRWXyLcXhV5q1ifTBcS3K8mYR3wQI3PqGFK1k",
+    "minClientVer": "",
+    "maxClientVer": "",
+    "maxTimediff": 0,
+    "shortIds": ["a3f1", "b8c2", "d9e4"],
+    "mldsa65Seed": "",
+    "settings": {
+      "publicKey": "Tx5yj1bRcOPHkdvT2pIAQ2zh0gQ8m4OPdnzqXJxxV3o",
+      "fingerprint": "chrome",
+      "serverName": "",
+      "spiderX": "/",
+      "mldsa65Verify": ""
+    }
+  }
+}

+ 27 - 0
frontend/src/test/golden/fixtures/security/tls-cert-file.json

@@ -0,0 +1,27 @@
+{
+  "security": "tls",
+  "tlsSettings": {
+    "serverName": "cdn.example.test",
+    "minVersion": "1.2",
+    "maxVersion": "1.3",
+    "cipherSuites": "",
+    "rejectUnknownSni": false,
+    "disableSystemRoot": false,
+    "enableSessionResumption": false,
+    "certificates": [
+      {
+        "certificateFile": "/etc/ssl/certs/cdn.example.test.crt",
+        "keyFile": "/etc/ssl/private/cdn.example.test.key",
+        "oneTimeLoading": false,
+        "usage": "encipherment",
+        "buildChain": false
+      }
+    ],
+    "alpn": ["h2", "http/1.1"],
+    "echServerKeys": "",
+    "settings": {
+      "fingerprint": "chrome",
+      "echConfigList": ""
+    }
+  }
+}

+ 8 - 0
frontend/src/test/golden/fixtures/stream/grpc-basic.json

@@ -0,0 +1,8 @@
+{
+  "network": "grpc",
+  "grpcSettings": {
+    "serviceName": "GunService",
+    "authority": "grpc.example.test",
+    "multiMode": false
+  }
+}

+ 4 - 0
frontend/src/test/golden/fixtures/stream/tcp-none.json

@@ -0,0 +1,4 @@
+{
+  "network": "tcp",
+  "tcpSettings": {}
+}

+ 12 - 0
frontend/src/test/golden/fixtures/stream/ws-default.json

@@ -0,0 +1,12 @@
+{
+  "network": "ws",
+  "wsSettings": {
+    "acceptProxyProtocol": false,
+    "path": "/api/v2",
+    "host": "cdn.example.test",
+    "headers": {
+      "X-Forwarded-Proto": "https"
+    },
+    "heartbeatPeriod": 30
+  }
+}

+ 26 - 0
frontend/src/test/security.test.ts

@@ -0,0 +1,26 @@
+/// <reference types="vite/client" />
+import { describe, expect, it } from 'vitest';
+
+import { SecuritySettingsSchema } from '@/schemas/protocols';
+
+const securityFixtures = import.meta.glob<unknown>(
+  './golden/fixtures/security/*.json',
+  { eager: true, import: 'default' },
+);
+
+function fixtureName(path: string): string {
+  const file = path.split('/').pop() ?? path;
+  return file.replace(/\.json$/, '');
+}
+
+describe('SecuritySettingsSchema fixtures', () => {
+  const entries = Object.entries(securityFixtures).sort(([a], [b]) => a.localeCompare(b));
+  expect(entries.length, 'expected at least one fixture under golden/fixtures/security').toBeGreaterThan(0);
+
+  for (const [path, raw] of entries) {
+    it(`parses ${fixtureName(path)} byte-stably`, () => {
+      const parsed = SecuritySettingsSchema.parse(raw);
+      expect(parsed).toMatchSnapshot();
+    });
+  }
+});

+ 26 - 0
frontend/src/test/stream.test.ts

@@ -0,0 +1,26 @@
+/// <reference types="vite/client" />
+import { describe, expect, it } from 'vitest';
+
+import { NetworkSettingsSchema } from '@/schemas/protocols';
+
+const streamFixtures = import.meta.glob<unknown>(
+  './golden/fixtures/stream/*.json',
+  { eager: true, import: 'default' },
+);
+
+function fixtureName(path: string): string {
+  const file = path.split('/').pop() ?? path;
+  return file.replace(/\.json$/, '');
+}
+
+describe('NetworkSettingsSchema fixtures', () => {
+  const entries = Object.entries(streamFixtures).sort(([a], [b]) => a.localeCompare(b));
+  expect(entries.length, 'expected at least one fixture under golden/fixtures/stream').toBeGreaterThan(0);
+
+  for (const [path, raw] of entries) {
+    it(`parses ${fixtureName(path)} byte-stably`, () => {
+      const parsed = NetworkSettingsSchema.parse(raw);
+      expect(parsed).toMatchSnapshot();
+    });
+  }
+});