fix(api): сохранять каталог пинг-проб атомарно

This commit is contained in:
Denozordec committed 2026-10-04 11:53:48 +07:00
1 parent 9c22fa8a68
commit 53c1bfbd3b
15 files changed
+243 -122

No files matched your search

+1 -1
View File
@@ -19,7 +19,7 @@ for (const status of [200, 500]) {
}
}
const servers = [{ id: 1, name: isNew ? 'Новый источник' : 'Старый источник', host: '192.0.2.1', type: 'exit-node', enabled: true, country: 'RU', site: 'TEST', status: 'online', wanUplinks: [] }]
const probes = [{ id: 'p1', srcServerId: '1', name: isNew ? 'Новая проверка' : 'Старая проверка', target: '192.0.2.10', filter: 'main', rtt: 10, loss: 0, status: 'up', series: [10], enabled: true }]
const probes = [{ id: 'p1', srcServerId: '1', name: isNew ? 'Новая проверка' : 'Старая проверка', target: '192.0.2.10', filter: 'main', rtt: 10, loss: 0, status: 'up', series: [10], enabled: true, showOnDashboard: false }]
const json = url.pathname === '/api/auth/config' ? { required: false }
: url.pathname === '/api/servers' ? servers
: url.pathname === '/api/uptime/overview' ? { probes, resources: [] }
+39
View File
@@ -724,3 +724,42 @@ for (const malformed of [false, true]) test("Speed save requires confirmation an
}
expect(calls).toBe(1)
})
for (const malformed of [false, true]) test("Ping save requires confirmation and separates scheduler failure/" + malformed, async ({ page }) => {
await setup(page, "/uptime?probe=p1", 0, false, "mm:uptime:write")
await page.getByRole("button", { name: "Пауза", exact: true }).click()
let calls = 0
await page.route("**/api/uptime/probes", route => { if (route.request().method() !== "PUT") return route.fallback(); calls++; return route.fulfill({ json: malformed ? {} : { ok: true, warning: "Ping-пробы сохранены, но расписание не обновлено. Проверьте состояние сборщика данных." } }) })
await page.getByRole("button", { name: "Редактировать пробу", exact: true }).click()
const dialog = page.getByRole("dialog"), input = dialog.getByPlaceholder("youtube.com")
await input.fill("Черновик")
await dialog.getByRole("button", { name: "Сохранить", exact: true }).click()
if (malformed) { await expect(dialog.getByRole("alert")).toContainText("Ответ о сохранении Ping-проб не подтверждён"); await expect(input).toHaveValue("Черновик") }
else { await expect(dialog).toBeHidden(); await expect(page.getByRole("status").filter({ hasText: "Ping-пробы сохранены, но расписание" })).toBeVisible() }
expect(calls).toBe(1)
})
test("Ping catalog: malformed initial/refresh disables replacement, recovery and history deletion copy", async ({ page }, info) => {
const control = await setup(page, "/uptime?probe=p1", 0, false, "mm:uptime:write")
await page.getByRole("button", { name: "Пауза", exact: true }).click()
let malformed = true
await page.route("**/api/uptime/overview*", route => malformed ? route.fulfill({ json: { probes: [{ id: "broken" }], resources: [] } }) : route.fallback())
await page.reload(); await page.getByRole("button", { name: "Пауза", exact: true }).click()
const warning = page.getByRole("alert", { name: "Чтение Ping-проб", exact: true })
await expect(warning).toContainText("Данные пока неизвестны")
await expect(page.getByRole("button", { name: "Новая проба", exact: true }).first()).toBeDisabled()
await expect(page.getByText("Пробы не найдены", { exact: true })).toHaveCount(0)
malformed = false; await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
await expect(warning).toHaveCount(0); await expect(page.getByRole("button", { name: "Редактировать пробу", exact: true })).toHaveCount(1)
malformed = true; await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
await expect(warning).toContainText("Показан последний успешный список")
await expect(page.getByRole("button", { name: "Редактировать пробу", exact: true }).first()).toBeDisabled()
await page.setViewportSize({ width: 320, height: 1000 })
expect(await page.evaluate(() => document.documentElement.scrollWidth <= innerWidth)).toBe(true)
await page.addStyleTag({ content: "nextjs-portal { display: none !important; }" })
await page.screenshot({ path: info.outputPath("ping-catalog-error-320.png"), animations: "disabled" })
malformed = false; await page.getByRole("button", { name: "Обновить данные", exact: true }).click()
await page.getByRole("button", { name: "Удалить пробу", exact: true }).first().click()
await expect(page.getByRole("alertdialog")).toContainText("Вместе с ней будет удалена история её измерений")
await page.getByRole("alertdialog").getByRole("button", { name: "Отмена", exact: true }).click()
expect(control.writes).toEqual([])
})