fix(ui): сохранять поиск и выбранный узел OSPF
This commit is contained in:
1 parent
1d522527b4
commit
7a68ae8184
9 files changed
+113
-32
No files matched your search
@@ -3,10 +3,18 @@ import { test } from "node:test"
|
||||
import { readOspfUrl, patchOspfUrl } from "./ospf-url-state"
|
||||
test("OSPF device/tab URL preserves unrelated context", () => {
|
||||
const url=patchOspfUrl(new URLSearchParams("keep=x"),{server:"2",tab:"bfd"})
|
||||
assert.deepEqual(readOspfUrl(new URL(url,"http://test").searchParams),{server:"2",tab:"bfd",error:null})
|
||||
assert.deepEqual(readOspfUrl(new URL(url,"http://test").searchParams),{server:"2",tab:"bfd",search:"",node:null,error:null})
|
||||
assert.equal(patchOspfUrl(new URL(url,"http://test").searchParams,{server:null,tab:null}),"/ospf?keep=x")
|
||||
})
|
||||
test("invalid or repeated context is explicit instead of widening to all",()=>{
|
||||
for(const raw of ["server=a&server=b","tab=bfd&tab=neighbors","tab=broken","server=", "server="+"x".repeat(65),"server=%2F"]) assert.ok(readOspfUrl(new URLSearchParams(raw)).error)
|
||||
assert.equal(readOspfUrl(new URLSearchParams("server=srv1&tab=neighbors")).error,null)
|
||||
})
|
||||
|
||||
test("OSPF search/node roundtrip and invalid bounds",()=>{
|
||||
const params=new URLSearchParams({server:"1",tab:"neighbors",q:"ether & 1",node:"remote-192.0.2.2",keep:"x"})
|
||||
const state=readOspfUrl(params)
|
||||
assert.equal(state.search,"ether & 1");assert.equal(state.node,"remote-192.0.2.2");assert.equal(state.error,null)
|
||||
for(const raw of ["q=x&q=y","node=1&node=2","node=%2F","q="+"x".repeat(257),"node="+"x".repeat(129)])assert.ok(readOspfUrl(new URLSearchParams(raw)).error)
|
||||
assert.equal(patchOspfUrl(params,{q:null,node:null}),"/ospf?server=1&tab=neighbors&keep=x")
|
||||
})
|
||||
@@ -2,12 +2,16 @@ export const ospfTabs = ["interfaces", "neighbors", "routes", "bfd"] as const
|
||||
export type OspfTab = typeof ospfTabs[number]
|
||||
export function readOspfUrl(params: URLSearchParams) {
|
||||
const server = params.get("server") ?? "all"
|
||||
const search = params.get("q") ?? ""
|
||||
const node = params.get("node")
|
||||
const rawTab = params.get("tab") ?? "interfaces"
|
||||
let error: string | null = null
|
||||
if (["server", "tab"].some(key => params.getAll(key).length > 1)) error = "В ссылке повторяется контекст OSPF."
|
||||
if (["server", "tab", "q", "node"].some(key => params.getAll(key).length > 1)) error = "В ссылке повторяется контекст OSPF."
|
||||
else if (!/^[a-zA-Z0-9_.:-]{1,64}$/.test(server)) error = "В ссылке указан некорректный сервер OSPF."
|
||||
else if (!(ospfTabs as readonly string[]).includes(rawTab)) error = "В ссылке указана неизвестная вкладка OSPF."
|
||||
return { server, tab: (ospfTabs as readonly string[]).includes(rawTab) ? rawTab as OspfTab : "interfaces" as OspfTab, error }
|
||||
else if (search.length > 256) error = "Поиск OSPF в ссылке слишком длинный."
|
||||
else if (node !== null && !/^[a-zA-Z0-9_.:-]{1,128}$/.test(node)) error = "В ссылке указан некорректный узел OSPF."
|
||||
return { server, search, node, tab: (ospfTabs as readonly string[]).includes(rawTab) ? rawTab as OspfTab : "interfaces" as OspfTab, error }
|
||||
}
|
||||
export function patchOspfUrl(params: URLSearchParams, changes: Record<string, string | null>) {
|
||||
const next = new URLSearchParams(params)
|
||||
|
||||
Reference in new issue
Block a user