73 lines
4.7 KiB
TypeScript
73 lines
4.7 KiB
TypeScript
import { test, expect } from "@playwright/test"
|
|
|
|
for (const kind of ["rule", "address"] as const) {
|
|
for (const family of ["ip", "ip6"] as const) {
|
|
test(`Firewall: удаление ${kind}/${family} требует подтверждения`, async ({ page }) => {
|
|
let attempts = 0
|
|
let deleted = false
|
|
let release: (() => void) | undefined
|
|
const gate = new Promise<void>(resolve => { release = resolve })
|
|
const rule = { id: "rule-1", rosId: "*R/1", serverId: "1", serverName: "Роутер", family, table: "filter", chain: "forward", action: "accept", proto: "tcp", src: "", dst: "", port: "443", iface: "", comment: "Правило тест", enabled: true, hits: 1 }
|
|
const entry = { id: "address-1", rosId: "*A/1", serverId: "1", serverName: "Роутер", family, list: "trusted", address: family === "ip" ? "192.0.2.10" : "2001:db8::10", comment: "Адрес тест", disabled: false }
|
|
await page.route("**/health", route => route.fulfill({ json: { ok: true } }))
|
|
await page.route("**/api/**", async route => {
|
|
const path = new URL(route.request().url()).pathname
|
|
if (route.request().method() === "DELETE") {
|
|
attempts++
|
|
expect(path).toBe(kind === "rule" ? "/api/firewall/rules" : "/api/firewall/address-lists")
|
|
expect(route.request().postDataJSON()).toEqual(kind === "rule"
|
|
? { serverId: "1", family, table: "filter", rosId: "*R/1" }
|
|
: { serverId: "1", family, rosId: "*A/1" })
|
|
if (attempts === 1) { await gate; return route.fulfill({ status: 403, json: { error: "Удаление запрещено тест" } }) }
|
|
if (attempts === 2) return route.fulfill({ json: {} })
|
|
if (attempts === 3) return route.fulfill({ json: { ok: false } })
|
|
deleted = true
|
|
return route.fulfill({ json: { ok: true } })
|
|
}
|
|
return route.fulfill({ json: path === "/api/auth/config" ? { required: false }
|
|
: path === "/api/firewall/all" ? { rules: kind === "rule" && !deleted ? [rule] : [], addressLists: kind === "address" && !deleted ? [entry] : [] }
|
|
: path === "/api/servers" ? [{ id: 1, name: "Роутер", host: "192.0.2.1", type: "exit-node", enabled: true, country: "RU", status: "online" }] : {} })
|
|
})
|
|
await page.goto("/firewall?server=1")
|
|
if (family === "ip6") await page.getByRole("button", { name: "IPv6", exact: true }).click()
|
|
if (kind === "address") await page.getByRole("button", { name: /Адр. листы/ }).click()
|
|
const open = async () => {
|
|
await page.getByRole("button", { name: kind === "rule" ? "Действия: forward accept" : "Действия: " + entry.address, exact: true }).click()
|
|
await page.getByRole("menuitem", { name: kind === "rule" ? "Удалить правило" : "Удалить", exact: true }).click()
|
|
}
|
|
await open()
|
|
const dialog = page.getByRole("alertdialog")
|
|
await expect(dialog).toContainText("Роутер")
|
|
await expect(dialog).toContainText(kind === "rule" ? rule.comment : entry.address)
|
|
await dialog.getByRole("button", { name: "Отмена" }).click()
|
|
await expect(dialog).toHaveCount(0)
|
|
expect(attempts).toBe(0)
|
|
await open()
|
|
const remove = dialog.getByRole("button", { name: "Удалить", exact: true })
|
|
await remove.evaluate(button => { (button as HTMLButtonElement).click(); (button as HTMLButtonElement).click() })
|
|
await expect.poll(() => attempts).toBe(1)
|
|
await expect(remove).toBeDisabled()
|
|
await expect(dialog.getByRole("button", { name: "Отмена" })).toBeDisabled()
|
|
await expect(dialog.getByRole("status")).toContainText("Ожидание результата")
|
|
await page.keyboard.press("Escape")
|
|
await expect(dialog).toBeVisible()
|
|
release!()
|
|
await expect(dialog.getByRole("alert")).toContainText("Удаление запрещено тест")
|
|
await dialog.getByRole("button", { name: "Отмена" }).click()
|
|
await expect(dialog).toHaveCount(0)
|
|
await open()
|
|
await expect(dialog.getByRole("alert")).toHaveCount(0)
|
|
for (let i = 2; i <= 3; i++) {
|
|
await remove.click()
|
|
await expect.poll(() => attempts).toBe(i)
|
|
await expect(dialog.getByRole("alert")).toContainText("Сервер не подтвердил удаление")
|
|
await expect(page.getByText(kind === "rule" ? "Правило удалено" : "Запись удалена", { exact: true })).toHaveCount(0)
|
|
}
|
|
await remove.click()
|
|
await expect(dialog).toHaveCount(0)
|
|
expect(attempts).toBe(4)
|
|
await expect(page.getByRole("button", { name: kind === "rule" ? "Действия: forward accept" : "Действия: " + entry.address, exact: true })).toHaveCount(0)
|
|
})
|
|
}
|
|
}
|