Files
MikrotikManager/tests/e2e/traffic-response-validation.spec.ts

56 lines
4.6 KiB
TypeScript

import { observedTrafficFixturePayload } from "./traffic-observation-fixture"
import { test, expect } from '@playwright/test'
for (const variant of ['missing-sessions', 'negative-series', 'monthly-missing', 'monthly-mismatch'] as const) {
test(`Потоки: некорректный HTTP DTO ${variant} даёт ошибку и повтор без потери контекста`, async ({ page }) => {
let bad = true
const errors: string[] = []
const queries: Array<{ range: string | null; month: string | null; serverId: string | null }> = []
const monthlyCase = variant.startsWith('monthly')
const stats = { bpsNow: 1000000, bytes: 200, packets: 2, conversations: 1, uniqueSrc: 1, uniqueDst: 1, topProto: 'TCP', topCategory: 'Восстановлено', rxSeries: [1], txSeries: [2], applications: [], protocols: [], sources: [], destinations: [], interfaces: [], conversationsList: [], ifaces: [], live: false }
const card = { id: '1', name: 'Экспортёр DTO', subtitle: '', site: 'TEST', country: 'RU', status: 'online', rxNow: 2, txNow: 3, sessions: 1, bytes: 200, rxSeries: [1], txSeries: [2] }
page.on('pageerror', error => errors.push(error.message))
await page.route('**/health', route => route.fulfill({ json: observedTrafficFixturePayload({ ok: true }) }))
await page.route('**/api/**', route => {
const url = new URL(route.request().url()), path = url.pathname
if (path === '/api/traffic/flow/analytics' || path === '/api/traffic/flow/monthly') {
if (path.endsWith(monthlyCase ? '/monthly' : '/analytics')) queries.push({ range: url.searchParams.get('range'), month: url.searchParams.get('month'), serverId: url.searchParams.get('serverId') })
if (path.endsWith('/monthly')) {
const month = url.searchParams.get('month')!
const data = bad && variant === 'monthly-missing' ? { month, bytes: 1500 }
: { month: bad && variant === 'monthly-mismatch' ? (month === '2026-01' ? '2026-02' : '2026-01') : month, bytes: 1500, countries: [], services: [], asns: [] }
return route.fulfill({ json: observedTrafficFixturePayload(data) })
}
const data = bad && variant === 'missing-sessions' ? { ...stats, conversationsList: undefined }
: bad && variant === 'negative-series' ? { ...stats, rxSeries: [-1] } : stats
return route.fulfill({ json: observedTrafficFixturePayload(data) })
}
if (path.endsWith('/live')) return route.fulfill({ status: 503, json: observedTrafficFixturePayload({}) })
const json = path === '/api/auth/config' ? { required: false }
: path === '/api/traffic/flow/exporters' ? { exporters: [card] }
: path === '/api/traffic/flows' ? { exportersOnline: 1, bytesPerMin: 200, uniqueSrc: 1, uniqueDst: 1, topProto: 'TCP', talkers: [], listenerBound: true }
: path === '/api/traffic/servers' ? { servers: [] }
: path === '/api/traffic/users' ? { users: [] }
: path === '/api/traffic/flow/clients' ? { clients: [] }
: path.endsWith('/interfaces') ? { interfaces: [] }
: path === '/api/servers' ? [{ id: 1, name: card.name, host: '127.0.0.1', port: 80, useSsl: false, verifySsl: false, username: 'admin', password: '', type: 'jump-host', site: 'TEST', country: 'RU', asn: '', comment: '', enabled: true, lanSubnet: '', wanUplinks: [], createdAt: '', updatedAt: '', status: null, latency: null, os: null, model: null, uptime: null, cpuLoad: null, freeMemory: null, totalMemory: null, identityName: null, sessions: 0, polledAt: null }] : {}
return route.fulfill({ json: observedTrafficFixturePayload(json) })
})
await page.goto('/traffic')
await page.getByRole('group', { name: 'Разделы трафика' }).getByRole('button', { name: 'Потоки', exact: true }).click()
if (monthlyCase) await page.getByRole('button', { name: 'Месяц', exact: true }).click()
const alert = page.getByRole('alert').filter({ hasText: 'Аналитика недоступна' })
await expect(alert).toBeVisible()
await expect(alert).toContainText(variant === 'monthly-mismatch' ? 'данные другого месяца' : 'некорректный ответ сервера')
await expect(page.getByLabel('Скорость потоков')).toHaveCount(0)
const selected = queries.at(-1)!
expect(selected.serverId).toBe('1')
bad = false
await page.getByRole('button', { name: 'Повторить аналитику', exact: true }).click()
await expect(alert).toHaveCount(0)
expect(queries.at(-1)).toEqual(selected)
if (!monthlyCase) await expect(page.getByLabel('Скорость потоков')).toBeVisible()
expect(errors).toEqual([])
})
}