fix(ui): учитывать права на действия мониторинга
This commit is contained in:
1 parent
61950638bc
commit
bb9278fe58
4 files changed
+125
-27
No files matched your search
@@ -1,9 +1,13 @@
|
||||
import { test, expect, type Page } from "@playwright/test"
|
||||
|
||||
async function setup(page: Page, url: string, failed = 0, longNames = false) {
|
||||
async function setup(page: Page, url: string, failed = 0, longNames = false, permission?: string, isAdmin = false) {
|
||||
const control = { writes: [] as { method: string; path: string; body: unknown }[], failed, posts: [] as { path: string; body: unknown }[] }
|
||||
const servers = [{ id: 1, name: "Источник", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", site: "TEST", asn: "64512", status: "online", latency: 1, os: "7", model: "CHR", wanUplinks: [] }]
|
||||
const probes = ["p1", "p/2"].map(id => ({ id, srcServerId: "1", name: "Проверка сети", target: "192.0.2.10", filter: "main", rtt: null, loss: 100, status: "down", series: [0], enabled: true, showOnDashboard: false }))
|
||||
if (permission) {
|
||||
await page.addInitScript(token => localStorage.setItem("mmapp_token", token), uptimeToken(permission, isAdmin))
|
||||
servers.push({ ...servers[0], id: 2, name: "Назначение", host: "192.0.2.2" })
|
||||
}
|
||||
if (longNames) {
|
||||
servers[0].name = "Источник-с-длинным-названием-площадки-для-проверки-переноса"
|
||||
probes.forEach(p => { p.name = "Проверка-доступности-длинного-имени-сетевого-узла"; p.target = "router-with-a-long-hostname.example.test"; p.filter = "Фильтр-с-длинным-названием" })
|
||||
@@ -15,11 +19,11 @@ async function setup(page: Page, url: string, failed = 0, longNames = false) {
|
||||
if (!["GET", "HEAD"].includes(request.method())) control.writes.push({ method: request.method(), path, body: request.postDataJSON() })
|
||||
if (request.method() === "POST") control.posts.push({ path, body: request.postDataJSON() })
|
||||
if (path === "/api/uptime/overview" && control.failed) return route.fulfill({ status: control.failed, json: { error: "Мониторинг недоступен" } })
|
||||
const json = path === "/api/auth/config" ? { required: false }
|
||||
const json = path === "/api/auth/config" ? { required: Boolean(permission) }
|
||||
: path === "/api/evobgp/settings" ? { enabled: false, baseUrl: "", secretConfigured: false }
|
||||
: path === "/api/servers" ? servers
|
||||
: path === "/api/uptime/overview" ? { probes, resources: [] }
|
||||
: path === "/api/uptime/speed-probes" ? { probes: [] }
|
||||
: path === "/api/uptime/speed-probes" ? { probes: permission ? [{ id: "s1", srcServerId: "1", dstServerId: "2", srcInterface: "", dstInterface: "", protocol: "tcp", direction: "both", durationSec: "10", enabled: true }] : [] }
|
||||
: path === "/api/uptime/speed-test/runs" ? { runs: [] }
|
||||
: path === "/api/bgp/sessions" ? []
|
||||
: path === "/api/filters/gre-tunnels" || path === "/api/vxlan" ? { tunnels: [] }
|
||||
@@ -126,3 +130,59 @@ for (const width of [320, 390, 1440]) {
|
||||
await expect.poll(() => control.writes.some(w => w.method === "PUT" && w.path === "/api/uptime/probes")).toBe(true)
|
||||
})
|
||||
}
|
||||
|
||||
// UI claim fixtures; JWT verification remains a separate integration check.
|
||||
function uptimeToken(permission: string, isAdmin = false) {
|
||||
return "fixture." + Buffer.from(JSON.stringify({ apps: ["mm"], permissions: ["mm:servers:read", permission], is_admin: isAdmin, exp: Math.floor(Date.now() / 1000) + 3600 })).toString("base64url") + ".fixture"
|
||||
}
|
||||
|
||||
for (const [permission, isAdmin] of [["mm:uptime:read", false], ["mm:uptime:read", true], ["mm:servers:write", false]] as const) {
|
||||
test(`мониторинг только чтение: ${permission}, is_admin=${isAdmin}`, async ({ page }) => {
|
||||
const control = await setup(page, "/uptime", 0, false, permission, isAdmin)
|
||||
await expect(page.getByText("Только просмотр", { exact: true })).toBeVisible()
|
||||
await expect(page.getByRole("button", { name: "Новая проба", exact: true })).toBeDisabled()
|
||||
const row = page.locator('[data-probe-id="p1"]')
|
||||
for (const name of ["Показать на дашборде", "Редактировать пробу", "Удалить пробу"]) {
|
||||
await expect(row.getByRole("button", { name, exact: true })).toBeDisabled()
|
||||
}
|
||||
await expect(row.getByRole("switch")).toBeDisabled()
|
||||
await expect(page.getByRole("button", { name: /Добавить интерфейс для/ })).toBeDisabled()
|
||||
await expect(page.getByRole("button", { name: "Обновить", exact: true })).toBeDisabled()
|
||||
await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
|
||||
await page.getByRole("button", { name: /Ресурсы/ }).click()
|
||||
await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
|
||||
await page.getByRole("button", { name: /Скорость/ }).click()
|
||||
await expect(page.getByRole("button", { name: "Новая speed-проба", exact: true })).toBeDisabled()
|
||||
for (const name of ["Запустить", "Редактировать speed-пробу", "Удалить speed-пробу"]) {
|
||||
await expect(page.getByRole("button", { name, exact: true })).toBeDisabled()
|
||||
}
|
||||
await expect(page.getByRole("switch")).toBeDisabled()
|
||||
await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
|
||||
expect(control.writes).toEqual([])
|
||||
})
|
||||
}
|
||||
|
||||
for (const permission of ["mm:uptime:write", "mm:uptime:admin"]) {
|
||||
test(`мониторинг: ${permission} разрешает ручной ping`, async ({ page }) => {
|
||||
const control = await setup(page, "/uptime?probe=p1", 0, false, permission)
|
||||
await expect(page.getByRole("button", { name: "Новая проба", exact: true })).toBeEnabled()
|
||||
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
||||
await expect.poll(() => control.posts.map(p => p.path)).toEqual(["/api/uptime/probes/collect-group"])
|
||||
await page.getByRole("button", { name: /Скорость/ }).click()
|
||||
await expect(page.getByRole("button", { name: "Запустить", exact: true })).toBeEnabled()
|
||||
})
|
||||
}
|
||||
|
||||
for (const speed of [false, true]) {
|
||||
test(`мониторинг: отзыв права перед сохранением ${speed ? "Speed" : "Ping"}`, async ({ page }) => {
|
||||
const control = await setup(page, "/uptime?probe=p1", 0, false, "mm:uptime:write")
|
||||
if (speed) await page.getByRole("button", { name: /Скорость/ }).click()
|
||||
await page.getByRole("button", { name: speed ? "Редактировать speed-пробу" : "Редактировать пробу", exact: true }).click()
|
||||
await expect(page.getByRole("dialog")).toBeVisible()
|
||||
await page.evaluate(token => localStorage.setItem("mmapp_token", token), uptimeToken("mm:uptime:read"))
|
||||
await page.getByRole("dialog").getByRole("button", { name: "Сохранить", exact: true }).click()
|
||||
await expect(page.getByRole("dialog")).toBeVisible()
|
||||
await expect(page.getByRole("dialog").getByRole("alert")).toContainText("Недостаточно прав")
|
||||
expect(control.writes).toEqual([])
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user