Files

43 lines
6.1 KiB
TypeScript

import { test, expect, type Page } from "@playwright/test"
import {user,server,catalogResponse} from "./fixtures/users"
async function routes(page:Page){
await page.route("**/health",r=>catalogResponse(r, {json:{ok:true}}))
await page.route("**/api/**",r=>{const path=new URL(r.request().url()).pathname;return catalogResponse(r, {json:path==="/api/users"?{users:[user]}:path==="/api/servers"?[server]:path==="/api/auth/config"?{required:false}:{interfaces:[]}})})
}
test.beforeEach(async({page})=>routes(page))
const add=(page:Page)=>page.getByRole("button",{name:"Добавить пользователя",exact:true})
const refresh=(page:Page)=>page.getByRole("button",{name:"Обновить пользователей",exact:true})
for(const kind of ["API","malformed","duplicate"] as const)test("Пользователи: первоначальный отказ "+kind,async({page})=>{
let fail=true;await page.route("**/api/users",r=>catalogResponse(r, fail?(kind==="API"?{status:503,json:{error:"Отказ пользователей"}}:{json:{users:kind==="duplicate"?[user,user]:[{}]}}):{json:{users:[user]}}))
await page.goto("/users");await expect(page.getByRole("alert",{name:"Пользователи",exact:true})).toContainText("Пользователи пока неизвестны");await expect(page.getByText("Нет пользователей",{exact:true})).toHaveCount(0);await expect(add(page)).toBeDisabled();await expect(page.getByText("Алексей Коротaев",{exact:true})).toHaveCount(0)
fail=false;await refresh(page).click();await expect(page.getByText(user.name,{exact:true})).toBeVisible();await expect(add(page)).toBeEnabled();await expect(page.getByRole("alert",{name:"Пользователи",exact:true})).toHaveCount(0)
})
for(const kind of ["API","malformed","duplicate"] as const)test("Пользователи: независимый отказ серверов "+kind,async({page})=>{
let fail=true;await page.route("**/api/servers",r=>catalogResponse(r, fail?(kind==="API"?{status:403,json:{error:"Серверы запрещены"}}:{json:kind==="duplicate"?[server,server]:[{}]}):{json:[server]}))
await page.goto("/users");await expect(page.getByText(user.name,{exact:true})).toBeVisible();await expect(page.getByRole("alert",{name:"Серверы пользователей"})).toContainText("Каталог серверов пока неизвестен");await expect(add(page)).toBeDisabled()
await page.getByText(user.name,{exact:true}).click();await expect(page.getByText("каталог неизвестен",{exact:true})).toBeVisible()
fail=false;await refresh(page).click();await expect(add(page)).toBeEnabled();await expect(page.getByRole("alert",{name:"Серверы пользователей"})).toHaveCount(0)
})
test("Пользователи: подтверждённый пустой список и нули",async({page})=>{
await page.route("**/api/users",r=>catalogResponse(r, {json:{users:[]}}));await page.goto("/users");await expect(page.getByText("Нет пользователей",{exact:true})).toBeVisible();await expect(add(page)).toBeEnabled();await expect(page.getByRole("alert",{name:"Пользователи",exact:true})).toHaveCount(0)
})
for(const part of ["users","servers"])test("Пользователи: фоновый отказ сохраняет снимок "+part,async({page})=>{
let fail=false;await page.route("**/api/"+part,r=>catalogResponse(r, fail?{status:503,json:{error:"ФОНОВЫЙ ОТКАЗ"}}:{json:part==="users"?{users:[user]}:[server]}))
await page.goto("/users");await expect(add(page)).toBeEnabled();fail=true;await refresh(page).click();await expect(page.getByText("ФОНОВЫЙ ОТКАЗ",{exact:true})).toBeVisible();await expect(page.getByText(user.name,{exact:true})).toBeVisible();await expect(add(page)).toBeDisabled();await expect(page.getByRole("button",{name:"Редактировать пользователя "+user.name})).toBeDisabled()
fail=false;await refresh(page).click();await expect(add(page)).toBeEnabled();await expect(page.getByText("ФОНОВЫЙ ОТКАЗ",{exact:true})).toHaveCount(0)
})
test("Пользователи: read права и отсутствие server read",async({page})=>{
await page.addInitScript(()=>localStorage.setItem("mmapp_token","header."+btoa(JSON.stringify({sub:"test",apps:["mm"],permissions:["mm:users:read"],exp:Math.floor(Date.now()/1000)+3600}))+".signature"))
await page.route("**/api/auth/config",r=>catalogResponse(r, {json:{required:true}}));let servers=0;await page.route("**/api/servers",r=>{servers++;return catalogResponse(r, {json:[server]})})
await page.goto("/users");await expect(page.getByText(user.name,{exact:true})).toBeVisible();await expect(add(page)).toBeDisabled();await expect(page.getByRole("button",{name:"Удалить пользователя "+user.name})).toBeDisabled();await expect(page.getByRole("status").filter({hasText:"mm:servers:read"})).toBeVisible();expect(servers).toBe(0)
})
test("Пользователи: до ответа live нет демо-профилей",async({page})=>{
let release!:()=>void;const gate=new Promise<void>(r=>release=r);await page.route("**/api/users",async r=>{await gate;await catalogResponse(r, {json:{users:[user]}}).catch(()=>{})})
await page.goto("/users");await expect(page.getByRole("status").filter({hasText:"Загрузка пользователей…"})).toBeVisible();await expect(page.getByText(user.name,{exact:true})).toHaveCount(0);await expect(add(page)).toBeDisabled();await expect(page.getByText("Нет пользователей",{exact:true})).toHaveCount(0);release();await expect(add(page)).toBeEnabled()
})
test("Пользователи: медленный серверный каталог не задерживает список",async({page})=>{
let release!:()=>void;const gate=new Promise<void>(r=>release=r);await page.route("**/api/servers",async r=>{await gate;await catalogResponse(r, {json:[server]}).catch(()=>{})})
await page.goto("/users");await expect(page.getByText(user.name,{exact:true})).toBeVisible();await expect(add(page)).toBeDisabled();release();await expect(add(page)).toBeEnabled()
})