Files
MikrotikManager/backend/src/services/recursive-effective-properties.test.ts
T
Denozordec e6a2e4009d
Docker images / prepare-release (push) Successful in 10s
Docker images / backend-test (push) Successful in 5m2s
Docker images / frontend-image (push) Successful in 2m46s
Docker images / updater-image (push) Successful in 42s
Docker images / backend-image (push) Successful in 1m54s
Docker images / publish-release (push) Successful in 15s
Docker images / notify-webhook (push) Successful in 2s
fix(routes): читать рекурсивные маршруты с незаданными свойствами
2026-10-16 00:28:45 +07:00

45 lines
2.9 KiB
TypeScript

import assert from "node:assert/strict"
import { readRecursiveEffectiveProperties, parseRecursiveCatalog } from "./recursive-route-catalog.js"
const row = { ".id": "*1", static: "true", "dst-address": "10.9.9.2/32", gateway: "192.0.2.1%gre-test", distance: "1", scope: "30", "target-scope": "10", "routing-table": "main", comment: "MikrotikManager:recursive Тест" }
const calls: string[] = []
const result = await readRecursiveEffectiveProperties([row], async (id, property) => {
calls.push(id + ":" + property)
return property === "disabled" ? { ret: "false" } : []
})
assert.equal(parseRecursiveCatalog(result)[0].disabled, false)
assert.equal(parseRecursiveCatalog(result)[0].checkGateway, "none")
assert.deepEqual(calls.sort(), ["*1:check-gateway", "*1:disabled"])
assert.equal("disabled" in row, false)
let reads = 0
const complete = { ...row, disabled: "true", "check-gateway": "ping" }
assert.deepEqual(await readRecursiveEffectiveProperties([complete, { ".id": "*other", comment: "user-owned" }], async () => { reads++; return null }), [complete, { ".id": "*other", comment: "user-owned" }])
assert.equal(reads, 0)
for (const payload of [null, {}, [null], [{ ...row, ".id": "" }], [row, row]]) {
await assert.rejects(readRecursiveEffectiveProperties(payload, async () => { reads++; return null }))
assert.equal(reads, 0)
}
for (const property of ["disabled", "check-gateway"] as const) {
for (const response of [null, {}, { ret: false }, { ret: "" }, { ret: "unknown" }, [{}], ...(property === "disabled" ? [[]] : [])]) {
const input = { ...complete }; delete (input as Record<string, unknown>)[property]
await assert.rejects(readRecursiveEffectiveProperties([input], async () => response), /Не подтверждён/)
}
}
await assert.rejects(readRecursiveEffectiveProperties([row], async () => { throw Error("RouterOS недоступен") }), /недоступен/)
const explicit = await readRecursiveEffectiveProperties([row], async (_id, property) => ({ ret: property === "disabled" ? "true" : "bfd" }))
assert.equal(parseRecursiveCatalog(explicit)[0].disabled, true)
assert.equal(parseRecursiveCatalog(explicit)[0].checkGateway, "bfd")
// Explicit invalid values are not replaced with defaults or re-read.
const invalid = { ...complete, disabled: "unknown" }
const untouched = await readRecursiveEffectiveProperties([invalid], async () => { throw Error("unexpected read") })
assert.throws(() => parseRecursiveCatalog(untouched))
let active = 0, maximum = 0
await readRecursiveEffectiveProperties(Array.from({ length: 12 }, (_, i) => ({ ...row, ".id": "*" + i })), async (_id, property) => {
maximum = Math.max(maximum, ++active)
await new Promise(resolve => setTimeout(resolve, 1)); active--
return { ret: property === "disabled" ? "false" : "arp" }
})
assert.equal(maximum, 2)
console.log("Recursive effective properties: omitted flags/unset check, strict envelopes, ownership, no mutation, errors and bounded reads passed")