fix(ui): защищать чтение WireGuard при смене источника

This commit is contained in:
Denozordec committed 2026-10-04 12:48:24 +07:00
1 parent e51964b4d2
commit c7aec1500c
11 files changed
+182 -53

No files matched your search

+50
View File
@@ -553,3 +553,53 @@ for(const invalid of ["tab=bad","status=bad","q=a&q=b","tab=peers&tab=cli"])test
await expect(page).toHaveURL(url=>url.searchParams.get("server")==="2"&&url.searchParams.get("interface")==="*/2"&&url.searchParams.get("keep")==="1")
expect(control.posts).toEqual([])
})
test("WireGuard reading: unknown initial/catalog DTO/cache freshness and guarded writes",async({page},info)=>{
const control=await setup(page,"/wireguard?server=1&interface=*%2F2",503)
const read=page.getByRole("alert",{name:"Чтение WireGuard",exact:true})
await expect(read).toContainText("Каталог пока неизвестен")
await expect(page.getByText("Нет WireGuard интерфейсов",{exact:true})).toHaveCount(0)
await expect(page.getByLabel("Сводка WireGuard").getByText("—",{exact:true})).toHaveCount(4)
await expect(page.getByRole("button",{name:"Новый интерфейс",exact:true}).first()).toBeDisabled()
control.failed=0;await page.getByRole("button",{name:"Обновить",exact:true}).click()
const rows=page.locator("tr[data-row-id]");await expect(rows).toHaveCount(1)
await expect(page.getByRole("status",{name:"Чтение WireGuard",exact:true})).toContainText("Получены")
await page.route("**/api/wireguard",r=>r.fulfill({json:{interfaces:[{id:"broken"}]}}))
await page.getByRole("button",{name:"Обновить",exact:true}).click();await expect(read).toContainText("Показаны последние полученные данные")
await expect(rows).toHaveCount(1);await rows.getByRole("button",{name:"Действия: wg-same",exact:true}).click()
await expect(page.getByRole("menuitem",{name:"Удалить",exact:true})).toHaveCount(0);await page.keyboard.press("Escape")
await page.setViewportSize({width:320,height:1000});await expect.poll(()=>page.evaluate(()=>document.documentElement.scrollWidth)).toBeLessThanOrEqual(320)
await page.addStyleTag({content:"nextjs-portal{display:none!important}"});await page.screenshot({path:info.outputPath("wireguard-read-error-320.png"),animations:"disabled"})
expect(control.posts).toEqual([])
})
test("WireGuard partial device: failed source never becomes confirmed empty KPI",async({page})=>{
const control=await setup(page,"/wireguard?server=2&interface=*%2F2")
await expect(page.locator("tr[data-row-id]")).toHaveCount(1)
control.partial=true;await page.getByRole("button",{name:"Обновить",exact:true}).click()
await expect(page.getByRole("status",{name:"WireGuard по ссылке",exact:true})).toContainText("Не удалось получить данные выбранного сервера")
await expect(page.getByLabel("Сводка WireGuard").getByText("—",{exact:true})).toHaveCount(4)
await expect(page.getByText("Нет WireGuard интерфейсов",{exact:true})).toHaveCount(0)
await expect(page.locator("tr[data-row-id]")).toHaveCount(0);expect(control.posts).toEqual([])
})
for(const kind of ["interfaces","peers","overlap","failures"])test("WireGuard invalid identity/failures cannot replace cache/"+kind,async({page})=>{
const control=await setup(page,"/wireguard?server=1&interface=*%2F2")
const rows=page.locator("tr[data-row-id]");await expect(rows).toHaveCount(1)
const peer={id:"p",rosId:"*P",publicKey:"key",allowedIps:[]},iface={id:"*/2",rosId:"*/2",name:"Invalid replacement",serverId:"1",serverName:"Источник",listenPort:13231,mtu:1420,comment:"",enabled:true,status:"up",peers:kind==="peers"?[peer,peer]:[peer]}
await page.route("**/api/wireguard",r=>r.fulfill({json:{interfaces:kind==="interfaces"?[iface,iface]:[iface],failures:kind==="overlap"?[{serverId:"1",error:"failed"}]:kind==="failures"?[{serverId:"2",error:"failed"},{serverId:"2",error:"failed"}]:[]}}))
await page.getByRole("button",{name:"Обновить",exact:true}).click();await expect(page.getByRole("alert",{name:"Чтение WireGuard",exact:true})).toContainText("Показаны последние полученные данные")
await expect(rows).toHaveCount(1);await expect(rows.first()).toContainText("wg-same");await expect(page.getByText("Invalid replacement",{exact:true})).toHaveCount(0)
expect(control.posts).toEqual([])
})
test("WireGuard malformed device catalog cannot publish replacement or freshness",async({page})=>{
const control=await setup(page,"/wireguard?server=1&interface=*%2F2")
const rows=page.locator("tr[data-row-id]");await expect(rows).toHaveCount(1)
await page.route("**/api/servers",r=>r.fulfill({json:[{id:1}]}))
await page.route("**/api/wireguard",r=>r.fulfill({json:{interfaces:[]}}))
await page.getByRole("button",{name:"Обновить",exact:true}).click()
await expect(page.getByRole("alert",{name:"Чтение WireGuard",exact:true})).toContainText("некорректный каталог устройств")
await expect(rows).toHaveCount(1);await expect(rows.first()).toContainText("wg-same")
expect(control.posts).toEqual([])
})