fix(ui): проверять права и сохранять достоверность общей сводки
This commit is contained in:
1 parent
b109532f33
commit
1999e8160e
9 files changed
+124
-117
No files matched your search
@@ -24,8 +24,8 @@ test("Alerts catalogs: initial partial GRE remains unknown",async({page})=>{awai
|
||||
test("Alerts catalogs: alerts read permission does not grant network catalog access",async({page})=>{
|
||||
const token="header."+Buffer.from(JSON.stringify({sub:"fixture",apps:["mm"],permissions:["mm:alerts:read"],exp:Math.floor(Date.now()/1000)+3600})).toString("base64url")+".fixture"
|
||||
await page.addInitScript(value=>localStorage.setItem("mmapp_token",value),token)
|
||||
const calls:string[]=[];await setup(page,(r,path)=>{if(["/api/bgp/sessions","/api/filters/gre-tunnels"].includes(path))calls.push(path);return r.fulfill({json:[]})},true)
|
||||
const calls:string[]=[];await setup(page,(r,path)=>{if(["/api/bgp/sessions","/api/filters/gre-tunnels","/api/sidebar-counts"].includes(path))calls.push(path);return r.fulfill({json:[]})},true)
|
||||
await expect(page.getByText("Всего: 0",{exact:true})).toBeVisible()
|
||||
for(const label of ["BGP","Серверы","GRE"])await expect(page.getByRole("region",{name:"Каталог "+label,exact:true}).getByRole("alert")).toHaveText("Нет доступа к каталогу")
|
||||
const baseline=[...calls];for(const label of ["BGP","Серверы","GRE"])await page.getByRole("button",{name:"Обновить каталог "+label,exact:true}).click();expect(calls).toEqual(baseline);expect(calls).not.toContain("/api/bgp/sessions")
|
||||
const baseline=[...calls];for(const label of ["BGP","Серверы","GRE"])await page.getByRole("button",{name:"Обновить каталог "+label,exact:true}).click();expect(calls).toEqual(baseline);expect(calls).toEqual([])
|
||||
})
|
||||
@@ -0,0 +1,12 @@
|
||||
import {test,expect,type Page} from "@playwright/test"
|
||||
import {emptyAlerts,emptyOutbox} from "./fixtures/alerts"
|
||||
const counts={servers:4,filterRules:0,uptimeProbes:0,uptimeSpeedProbes:0,monitoringItems:0,recursiveRoutes:0}
|
||||
async function setup(page:Page,reply:(path:string)=>{status?:number;json:unknown}){await page.route("**/health",r=>r.fulfill({json:{status:"ok"}}));await page.route("**/api/**",r=>{const path=new URL(r.request().url()).pathname;return r.fulfill(path==="/api/auth/config"?{json:{required:false}}:path==="/api/alerts"?{json:emptyAlerts}:path==="/api/alerts/outbox"?{json:emptyOutbox}:reply(path))});await page.goto("/alerts")}
|
||||
const badge=(page:Page,name:string)=>page.getByRole("navigation",{name:"Основная навигация"}).getByRole("link",{name:new RegExp(name)}).locator("span").last()
|
||||
test("Sidebar missing optional counts remain unknown; confirmed zero is displayed",async({page})=>{await setup(page,path=>({json:path==="/api/sidebar-counts"?counts:path==="/api/filters/gre-tunnels"?{tunnels:[],failures:[]}:[]}));await expect(badge(page,"Серверы")).toHaveText("4");await expect(badge(page,"GRE-туннели")).toHaveText("0");await expect(badge(page,"Пользователи")).toHaveText("Пользователи")})
|
||||
test("Sidebar partial GRE refresh retains last complete count, other counts update independently",async({page})=>{await page.clock.install();let partial=false;await setup(page,path=>({json:path==="/api/sidebar-counts"?{...counts,servers:partial?5:4}:path==="/api/filters/gre-tunnels"?{tunnels:partial?[]:[{name:"g",serverId:"1"}],failures:partial?[{error:"offline"}]:[]}:[]}));await expect(badge(page,"GRE-туннели")).toHaveText("1");partial=true;await page.clock.fastForward(120001);await expect(badge(page,"Серверы")).toHaveText("5");await expect(badge(page,"GRE-туннели")).toHaveText("1")})
|
||||
test("Sidebar GRE does not wait for unavailable summary reader",async({page})=>{await setup(page,path=>path==="/api/sidebar-counts"?{status:503,json:{error:"counts unavailable"}}:{json:path==="/api/filters/gre-tunnels"?{tunnels:[{name:"g",serverId:"1"}],failures:[]}:[]});await expect(badge(page,"GRE-туннели")).toHaveText("1");await expect(badge(page,"Серверы")).toHaveText("Серверы")})
|
||||
|
||||
test("Sidebar GRE arrives while summary request is pending",async({page})=>{let started=false,release!:()=>void;const gate=new Promise<void>(resolve=>release=resolve);await page.route("**/health",r=>r.fulfill({json:{status:"ok"}}));await page.route("**/api/**",async r=>{const path=new URL(r.request().url()).pathname;if(path==="/api/sidebar-counts"){started=true;await gate;try{await r.fulfill({json:counts})}catch{};return}return r.fulfill({json:path==="/api/auth/config"?{required:false}:path==="/api/alerts"?emptyAlerts:path==="/api/alerts/outbox"?emptyOutbox:path==="/api/filters/gre-tunnels"?{tunnels:[{name:"g",serverId:"1"}],failures:[]}:[]})});try{await page.goto("/alerts");await expect.poll(()=>started).toBe(true);await expect(badge(page,"GRE-туннели")).toHaveText("1");await expect(badge(page,"Серверы")).toHaveText("Серверы");release();await expect(badge(page,"Серверы")).toHaveText("4")}finally{release()}})
|
||||
|
||||
test("System monitor summary failure preserves API health and last confirmed counts",async({page})=>{await page.clock.install();let fail=false;await setup(page,path=>path==="/api/sidebar-counts"&&fail?{status:503,json:{error:"summary unavailable"}}:{json:path==="/api/sidebar-counts"?counts:path==="/api/filters/gre-tunnels"?{tunnels:[],failures:[]}:[]});const button=page.getByRole("button",{name:"Монитор системы"});await expect(button).toContainText("API доступен");await button.click();const popover=page.locator('[data-slot="popover-content"]');await expect(popover.getByText("4шт.",{exact:true})).toBeVisible();fail=true;await page.clock.fastForward(30001);await expect(popover.getByRole("status")).toContainText("Сводка не обновлена");await expect(popover.getByText("4шт.",{exact:true})).toBeVisible();await expect(button).toContainText("API доступен")})
|
||||
Reference in new issue
Block a user