fix(netflow): пропустить загрузку флага неизвестной страны

This commit is contained in:
Codex committed 2026-11-11 23:46:51 +07:00
1 parent cf211f7418
commit 5d181e7cb0
2 files changed
+28 -7

No files matched your search

+11 -5
View File
@@ -59,10 +59,17 @@ function nearestCdnSize(px: number): number {
return CDN_SIZES.find(s => s >= px) ?? CDN_SIZES[CDN_SIZES.length - 1]
}
function flagCode(code: string): string | null {
if (!code) return null
const lower = code.toLowerCase()
// The server catalogue uses UN when the country is unknown.
return lower !== "un" && /^[a-z]{2}$/.test(lower) ? lower : null
}
/** CDN URL for SVG `<image href>` (flagcdn widths only). */
export function flagCdnUrl(code: string, size = 40): string | null {
const lower = code.toLowerCase()
if (!/^[a-z]{2}$/.test(lower)) return null
const lower = flagCode(code)
if (!lower) return null
return `https://flagcdn.com/w${nearestCdnSize(size)}/${lower}.png`
}
@@ -71,9 +78,8 @@ export function flagCdnUrl(code: string, size = 40): string | null {
* Source: https://flagcdn.com — free CDN, no API key needed.
*/
export function Flag({ code, size = 20, className }: FlagProps) {
if (!code) return null
const lower = code.toLowerCase()
if (!/^[a-z]{2}$/.test(lower)) return null
const lower = flagCode(code)
if (!lower) return null
const name = countryName(code.toUpperCase())
const cdnSrc = nearestCdnSize(size)
const cdnSrc2x = nearestCdnSize(size * 2)
+17 -2
View File
@@ -1,7 +1,7 @@
import { installOpenLiveStream, resumeLiveStream, sendLiveHeartbeat } from "./live-stream-fixture"
import { test, expect, type Page } from '@playwright/test'
async function setup(page: Page, liveRefusals = 0) {
async function setup(page: Page, liveRefusals = 0, unknownServer = false) {
const control = { emptyExporters: false, failCatalog: false, hold: '', holdIface: '', fail: false, failList: false, invalidSample: undefined as unknown, mergeSample: false, metrics: {} as Record<string, unknown>, release: () => {}, liveCalls: 0 }
const gate = new Promise<void>(resolve => { control.release = resolve })
const card = { id: '1', name: 'Экспортёр тест', subtitle: '', site: 'TEST', country: 'RU', status: 'online', rxNow: 2, txNow: 3, sessions: 1, rxSeries: [1, 2], txSeries: [2, 3], bytes: 200 }
@@ -27,13 +27,18 @@ async function setup(page: Page, liveRefusals = 0) {
: path === '/api/traffic/flow/exporters' ? { exporters: control.emptyExporters ? [] : [card, { ...card, id: '2', name: 'Экспортёр второй' }] }
: path === '/api/traffic/flow/clients' ? { clients: [{ ...card, id: 'client1', name: 'Клиент тест' }] }
: path === '/api/traffic/flows' ? { exportersOnline: 1, bytesPerMin: 1, uniqueSrc: 1, uniqueDst: 1, topProto: 'TCP', talkers: [], listenerBound: true }
: path === '/api/traffic/servers' ? { servers: [] }
: path === '/api/traffic/servers' ? { servers: unknownServer ? [{ ...card, name: 'Маршрутизатор без страны', country: '', rxPeak: null, txPeak: null, rxTotal: null, txTotal: null }] : [] }
: path.endsWith('/interfaces') || path.endsWith('/bound-interfaces') ? { interfaces: [] }
: path === '/api/traffic/users' ? { users: [] }
: path === '/api/servers' ? [] : {}
return route.fulfill({ json })
})
await page.goto('/traffic')
if (unknownServer) {
const server = page.getByRole('button').filter({ hasText: 'Маршрутизатор без страны' })
await expect(server).toBeVisible()
await expect(server.locator('img[src$="/un.png"]')).toHaveCount(0)
}
await page.getByRole('button', { name: 'Потоки', exact: true }).click()
await expect(page.getByLabel('Скорость потоков')).toBeVisible()
return control
@@ -51,6 +56,16 @@ test('Flow: начальный HTTP 429 сменяется фактически
expect(control.liveCalls).toBe(2)
})
test('Flow: переход с сервера без страны в потоки не загружает флаг UN', async ({ page }) => {
let placeholderRequests = 0
await page.route('https://flagcdn.com/**', async route => {
if (new URL(route.request().url()).pathname.endsWith('/un.png')) placeholderRequests++
await route.abort()
})
await setup(page, 0, true)
expect(placeholderRequests).toBe(0)
})
test('Flow: поздний ответ периода не заменяет текущую аналитику', async ({ page }) => {
const control = await setup(page)
control.hold = '24h'