fix(ui): учитывать ошибки устройств в сводке туннелей

This commit is contained in:
Denozordec committed 2026-10-03 23:51:16 +07:00
1 parent 9d3129372b
commit 55c9349677
10 files changed
+56 -33

No files matched your search

+8
View File
@@ -0,0 +1,8 @@
import assert from "node:assert/strict"
import {test} from "node:test"
import {parseDashboardGre,parseDashboardWireGuard,parseDashboardVxlan} from "./dashboard-overlays"
import {dashboardGre,dashboardWg,dashboardVxlan} from "../tests/e2e/fixtures/dashboard-overlays"
for(const [kind,parse,key,row] of [["GRE",parseDashboardGre,"tunnels",dashboardGre],["VXLAN",parseDashboardVxlan,"tunnels",dashboardVxlan],["WG",parseDashboardWireGuard,"interfaces",dashboardWg]] as const)test("strict complete dashboard overlay catalog/"+kind,()=>{
assert.ok(parse({[key]:[row],failures:[]}));assert.ok(parse({[key]:[],failures:[]}))
for(const raw of [{},{[key]:[]},{[key]:[{}],failures:[]},{[key]:[row,row],failures:[]},{[key]:[{...row,status:"unknown"}],failures:[]},{[key]:[row],failures:[{serverId:"2",error:"timeout"}]}])assert.throws(()=>parse(raw))
})
+13
View File
@@ -0,0 +1,13 @@
import {greResponseSchema} from "@/lib/gre-response"
import {vxlanResponseSchema} from "@/lib/vxlan-response"
import {wgListResponseSchema} from "@mmapp/contracts/wireguard"
import type {z} from "zod"
function complete(raw:unknown,failures:Array<{serverId:string;serverName?:string;error:string}>,kind:string){
if(!raw||typeof raw!=="object"||!("failures" in raw)||!Array.isArray(raw.failures))throw Error("Результат опроса устройств "+kind+" не подтверждён")
if(new Set(failures.map(f=>f.serverId)).size!==failures.length||failures.some(f=>!f.serverId.trim()))throw Error("Некорректные ошибки каталога "+kind)
if(failures.length)throw Error("Не опрошены устройства "+kind+": "+failures.map(f=>(f.serverName??f.serverId)+": "+f.error).join("; "))
}
export type DashboardGreTunnel=z.infer<typeof greResponseSchema>["tunnels"][number]
export function parseDashboardGre(raw:unknown){const p=greResponseSchema.safeParse(raw);if(!p.success)throw Error("Некорректный каталог GRE");complete(raw,p.data.failures,"GRE");return p.data}
export function parseDashboardVxlan(raw:unknown){const p=vxlanResponseSchema.safeParse(raw);if(!p.success)throw Error("Некорректный каталог VXLAN");complete(raw,p.data.failures,"VXLAN");return p.data}
export function parseDashboardWireGuard(raw:unknown){const p=wgListResponseSchema.safeParse(raw);if(!p.success)throw Error("Некорректный каталог WireGuard");complete(raw,p.data.failures??[],"WireGuard");if(new Set(p.data.interfaces.map(i=>JSON.stringify([i.serverId,i.id]))).size!==p.data.interfaces.length||new Set(p.data.interfaces.map(i=>JSON.stringify([i.serverId,i.rosId]))).size!==p.data.interfaces.length)throw Error("Повторяющийся интерфейс WireGuard");return p.data}