Files
MikrotikManager/tests/e2e/evobgp-provider.spec.ts
T

17 lines
7.2 KiB
TypeScript

import {test,expect,type Page} from "@playwright/test"
import {evoSettings as settings,evoCatalog as catalog} from "./fixtures/evobgp"
async function setup(page:Page){await page.route("**/health",r=>r.fulfill({json:{ok:true}}));await page.route("**/api/**",r=>{const p=new URL(r.request().url()).pathname;return r.fulfill(p==="/api/auth/config"?{json:{required:false}}:p==="/api/evobgp/settings"?{json:settings}:p==="/api/evobgp/catalog"?{json:catalog}:{status:503,json:{error:"outside Evolution fixture"}})})}
async function open(page:Page){await page.goto("/settings");await page.getByRole("button",{name:"EvoBGP",exact:true}).click()}
const base=(page:Page)=>page.getByPlaceholder("http://localhost:8080",{exact:true})
const settingsStamp=(page:Page)=>page.getByRole("status").filter({hasText:/^Настройки EvoBGP получены:/})
const catalogStamp=(page:Page)=>page.getByRole("status").filter({hasText:/^Каталог EvoBGP получен:/})
async function ready(page:Page){await expect(base(page)).toHaveValue(settings.baseUrl);await expect(catalogStamp(page)).toBeVisible();await expect(page.getByText("Обновление каталога EvoBGP…",{exact:true})).toHaveCount(0)}
test("Evolution provider: malformed settings остаются unknown",async({page})=>{await setup(page);await page.route("**/api/evobgp/settings",r=>r.fulfill({json:{}}));await open(page);await expect(page.getByText("Настройки EvoBGP неизвестны",{exact:true})).toBeVisible();await expect(page.getByText("Ключ: —",{exact:true})).toBeVisible();await expect(settingsStamp(page)).toHaveCount(0);await expect(base(page)).toHaveValue("")})
test("Evolution provider: каталог не задерживает known настройки",async({page})=>{await setup(page);let started=false,release!:()=>void;const gate=new Promise<void>(resolve=>release=resolve);await page.route("**/api/evobgp/catalog",async r=>{started=true;await gate;try{await r.fulfill({json:catalog})}catch{}});try{await open(page);await expect.poll(()=>started).toBe(true);await expect(base(page)).toHaveValue(settings.baseUrl);await expect(settingsStamp(page)).toBeVisible();await expect(page.getByText("Загрузка каталога EvoBGP…",{exact:true})).toBeVisible();release();await expect(catalogStamp(page)).toBeVisible()}finally{release()}})
test("Evolution provider: ошибка settings GET сохраняет настройки, каталог и время",async({page})=>{await setup(page);let failed=false;await page.route("**/api/evobgp/settings",r=>r.fulfill(failed?{status:503,json:{error:"settings unavailable"}}:{json:settings}));await open(page);await ready(page);const before=await settingsStamp(page).textContent(),catBefore=await catalogStamp(page).textContent();failed=true;await page.getByRole("button",{name:"Обновить настройки EvoBGP",exact:true}).click();await expect(page.getByText("Настройки EvoBGP не обновлены",{exact:true})).toBeVisible();await expect(settingsStamp(page)).toHaveText(before!);await expect(catalogStamp(page)).toHaveText(catBefore!);await expect(base(page)).toHaveValue(settings.baseUrl)})
test("Evolution provider: ошибка каталога сохраняет последний снимок и время",async({page})=>{await setup(page);let failed=false;await page.route("**/api/evobgp/catalog",r=>r.fulfill(failed?{status:503,json:{error:"catalog unavailable"}}:{json:catalog}));await open(page);await ready(page);const before=await catalogStamp(page).textContent();failed=true;await page.getByRole("button",{name:"Обновить каталог",exact:true}).click();await expect(page.getByText("Каталог EvoBGP не обновлён; показаны последние данные",{exact:true})).toBeVisible();await expect(catalogStamp(page)).toHaveText(before!);await page.locator('a[href="/domains"]').first().click();await expect(page.getByText("kept.example.test",{exact:true})).toBeVisible()})
test("Evolution provider: отключение подтверждённой интеграции очищает каталог",async({page})=>{await setup(page);let enabled=true,posts=0;await page.route("**/api/evobgp/settings",r=>r.fulfill({json:{...settings,enabled}}));await page.route("**/api/evobgp/catalog",r=>{posts++;return r.fulfill({json:catalog})});await open(page);await ready(page);const before=posts;enabled=false;await page.getByRole("button",{name:"Обновить настройки EvoBGP",exact:true}).click();await expect(page.getByText("Интеграция: выключена",{exact:true})).toBeVisible();await expect(page.getByText("Каталог EvoBGP отключён в сохранённых настройках",{exact:true})).toBeVisible();await expect(catalogStamp(page)).toHaveCount(0);expect(posts).toBe(before)})
test("Evolution provider: сохранение не ждёт каталог и не отменяется его отказом",async({page})=>{await setup(page);let failed=false,writes=0;await page.route("**/api/evobgp/catalog",r=>r.fulfill(failed?{status:503,json:{error:"catalog after save unavailable"}}:{json:catalog}));await page.route("**/api/evobgp/settings",r=>{if(r.request().method()!=="PUT")return r.fallback();writes++;failed=true;const patch=r.request().postDataJSON();return r.fulfill({json:{...settings,...patch,ok:true,savedFields:Object.keys(patch)}})});await open(page);await ready(page);await page.getByRole("button",{name:"Сохранить",exact:true}).click();await expect(page.getByText("Настройки EvoBGP сохранены",{exact:true})).toBeVisible();await expect(page.getByText("Каталог EvoBGP не обновлён; показаны последние данные",{exact:true})).toBeVisible();expect(writes).toBe(1)})
test("Evolution provider: malformed PUT не подтверждает сохранение",async({page})=>{await setup(page);let writes=0;await page.route("**/api/evobgp/settings",r=>{if(r.request().method()!=="PUT")return r.fallback();writes++;return r.fulfill({json:{}})});await open(page);await ready(page);await base(page).fill("https://new.example.test");await page.getByRole("button",{name:"Сохранить",exact:true}).click();await expect(page.locator("#main-content").getByText("Сохранение EvoBGP не подтверждено сервером",{exact:true})).toBeVisible();await expect(base(page)).toHaveValue("https://new.example.test");expect(writes).toBe(1)})
test("Evolution provider: права settings admin проверяются до GET",async({page})=>{const token="header."+Buffer.from(JSON.stringify({sub:"fixture",apps:["mm"],permissions:["mm:dashboard:read"],exp:Math.floor(Date.now()/1000)+3600})).toString("base64url")+".fixture";await page.addInitScript(value=>localStorage.setItem("mmapp_token",value),token);await setup(page);await page.route("**/api/auth/config",r=>r.fulfill({json:{required:true}}));let reads=0;page.on("request",r=>{if(new URL(r.url()).pathname.startsWith("/api/evobgp/"))reads++});await open(page);await expect(page.getByText("Нет доступа к настройкам EvoBGP",{exact:true})).toBeVisible();await expect(page.getByRole("button",{name:"Обновить настройки EvoBGP",exact:true})).toBeDisabled();expect(reads).toBe(0)})