83 lines
5.7 KiB
TypeScript
83 lines
5.7 KiB
TypeScript
import { test, expect } from "@playwright/test"
|
|
|
|
const summary = (id: string) => ({ serverId: id, serverName: "Роутер " + id, initialized: false, ike2Ready: false, natRuleManaged: false, clientsTotal: 1, clientsOnline: 0, peers: [] })
|
|
const client = (id: string, name = "Клиент " + id) => ({ id: id + "-*1", rosId: "*1", serverId: id, serverName: "Роутер " + id, name, authMethod: "certificate", online: false, disabled: false, managed: true })
|
|
const servers = [1, 2].map(id => ({ id, name: "Роутер " + id, host: "192.0.2." + id, enabled: true, country: "RU", type: "exit-node", status: "online" }))
|
|
const full = { servers: [summary("1"), summary("2")], clients: [client("1"), client("2")] }
|
|
|
|
for (const broken of ["http", "payload", "duplicate", "conflict"]) {
|
|
test(`IPsec: неизвестное начало и сохранение данных при ${broken}`, async ({ page }) => {
|
|
let phase = 0
|
|
await page.route("**/health", r => r.fulfill({ json: { ok: true } }))
|
|
await page.route("**/api/**", r => {
|
|
const path = new URL(r.request().url()).pathname
|
|
if (path === "/api/ipsec") {
|
|
if (phase === 0) return r.fulfill({ status: 503, json: { error: "Начальный отказ IPsec" } })
|
|
if (phase === 1 || phase === 3) return r.fulfill({ json: full })
|
|
return broken === "http" ? r.fulfill({ status: 503, json: { error: "Повторный отказ IPsec" } })
|
|
: r.fulfill({ json: broken === "payload" ? { servers: [], clients: [{}] }
|
|
: broken === "duplicate" ? { ...full, clients: [client("1"), client("1")] }
|
|
: { ...full, failures: [{ serverId: "1", error: "Сбой устройства" }] } })
|
|
}
|
|
return r.fulfill({ json: path === "/api/servers" ? servers : path === "/api/auth/config" ? { required: false } : {} })
|
|
})
|
|
await page.goto("/ipsec")
|
|
const alert = page.getByRole("alert").filter({ hasText: "Не удалось загрузить IPsec" })
|
|
await expect(alert).toContainText("Данные пока неизвестны")
|
|
await expect(page.getByText("Нет клиентов IKEv2", { exact: true })).toHaveCount(0)
|
|
await expect(page.locator("tr[data-row-id]")).toHaveCount(0)
|
|
await expect(page.getByLabel("Сводка IPsec")).toContainText("неизвестно")
|
|
phase = 1
|
|
await alert.getByRole("button", { name: "Повторить загрузку IPsec" }).click()
|
|
await expect(page.locator("tr[data-row-id]")).toHaveCount(2)
|
|
phase = 2
|
|
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
|
await expect(alert).toContainText("Показаны последние полученные данные")
|
|
await expect(page.locator("tr[data-row-id]")).toHaveCount(2)
|
|
await expect(page.getByLabel("Сводка IPsec")).toContainText("неизвестно")
|
|
phase = 3
|
|
await alert.getByRole("button", { name: "Повторить загрузку IPsec" }).click()
|
|
await expect(alert).toHaveCount(0)
|
|
await expect(page.locator("tr[data-row-id]")).toHaveCount(2)
|
|
})
|
|
}
|
|
|
|
test("IPsec: частичный отказ сохраняет строки роутера, восстановление удаляет устаревшие", async ({ page }) => {
|
|
let phase = 0
|
|
await page.route("**/health", r => r.fulfill({ json: { ok: true } }))
|
|
await page.route("**/api/**", r => {
|
|
const path = new URL(r.request().url()).pathname
|
|
return r.fulfill({ json: path === "/api/ipsec" ? phase === 0 ? full : phase === 1 ? {
|
|
servers: [summary("1")], clients: [client("1", "Обновлённый клиент")], failures: [{ serverId: "2", serverName: "Роутер 2", error: "Таймаут тест" }],
|
|
} : { servers: [summary("1"), { ...summary("2"), clientsTotal: 0 }], clients: [client("1", "Обновлённый клиент")] }
|
|
: path === "/api/servers" ? servers : path === "/api/auth/config" ? { required: false } : {} })
|
|
})
|
|
await page.goto("/ipsec")
|
|
const rows = page.locator("tr[data-row-id]")
|
|
await expect(rows).toHaveCount(2)
|
|
phase = 1
|
|
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
|
await expect(page.getByRole("alert").filter({ hasText: "Не удалось опросить часть роутеров" })).toContainText("Роутер 2: Таймаут тест")
|
|
await expect(rows).toHaveCount(2)
|
|
await expect(rows.filter({ hasText: "Обновлённый клиент" })).toHaveCount(1)
|
|
await expect(rows.filter({ hasText: "Клиент 2" })).toHaveCount(1)
|
|
await expect(page.getByLabel("Сводка IPsec")).toContainText("неизвестно")
|
|
phase = 2
|
|
await page.getByRole("button", { name: "Обновить", exact: true }).click()
|
|
await expect(page.getByRole("alert").filter({ hasText: "Не удалось опросить часть роутеров" })).toHaveCount(0)
|
|
await expect(rows).toHaveCount(1)
|
|
await expect(rows.filter({ hasText: "Клиент 2" })).toHaveCount(0)
|
|
})
|
|
|
|
test("IPsec: ошибка списка устройств не стирает успешный опрос", async ({ page }) => {
|
|
await page.route("**/health", r => r.fulfill({ json: { ok: true } }))
|
|
await page.route("**/api/**", r => {
|
|
const path = new URL(r.request().url()).pathname
|
|
if (path === "/api/servers") return r.fulfill({ status: 503, json: { error: "Устройства недоступны тест" } })
|
|
return r.fulfill({ json: path === "/api/ipsec" ? full : path === "/api/auth/config" ? { required: false } : {} })
|
|
})
|
|
await page.goto("/ipsec")
|
|
await expect(page.getByRole("alert").filter({ hasText: "Не удалось загрузить устройства" })).toBeVisible()
|
|
await expect(page.locator("tr[data-row-id]")).toHaveCount(2)
|
|
})
|