Files
bootnode/console/lib/dashboard-navigation.test.ts
zeekayandHanzo Dev 7d293212cb refactor: web/ is now console/ — bootnode/bootnode is the backend, bootnode/console the frontend
Names the two halves for what they are. The repo already holds both (12407e9 merged
bootnode/bootnode into this history); this makes the frontend directory say so, so the layout
reads the way the owner describes the system: backend and frontend separate, one repo.

git mv throughout — 187 renames, history preserved. Every path reference follows: hanzo.yml
build context and dockerfile, compose.yml, compose.prod.yml, start.sh, LLM.md,
infra/k8s/web-deployments.yaml, infra/cloud/deploy.sh, and the Dockerfile's own COPY paths.
Image and container names (bootnode-web, the -web tag suffix) are deliberately NOT renamed here:
those are a deploy contract the App CR and ingress bind to on port 3001, and breaking them is a
separate, staged change.

Console builds green after the move; the Go tree builds.

Co-authored-by: Hanzo Dev <[email protected]>
2026-07-26 17:47:51 -07:00

116 lines
4.8 KiB
TypeScript

// The console navigation contract.
//
// Run: `pnpm test`.
import { strict as assert } from "node:assert"
import { describe, it } from "node:test"
import { DASHBOARD_NAVIGATION, buildCommandItems, currentHref, navHrefs } from "./dashboard-navigation.ts"
describe("console navigation", () => {
it("reaches every dashboard route the build emits", () => {
// Taken from `next build`'s route table. Before this nav was rewritten,
// the eight marked routes existed, rendered, and were reachable only by
// typing the URL — no link anywhere in the product pointed at them.
const built = [
"/dashboard",
"/dashboard/analytics",
"/dashboard/api-keys",
"/dashboard/assets",
"/dashboard/assets/nfts", // was unreachable
"/dashboard/assets/tokens", // was unreachable
"/dashboard/gas",
"/dashboard/infrastructure",
"/dashboard/infrastructure/clusters",
"/dashboard/infrastructure/lux", // was unreachable
"/dashboard/infrastructure/monitoring",
"/dashboard/infrastructure/networks",
"/dashboard/infrastructure/nodes",
"/dashboard/infrastructure/observability", // was unreachable
"/dashboard/infrastructure/services", // was unreachable
"/dashboard/infrastructure/storage",
"/dashboard/infrastructure/volumes",
"/dashboard/markets",
"/dashboard/monitoring",
"/dashboard/organization",
"/dashboard/organization/billing",
"/dashboard/organization/settings",
"/dashboard/organization/team",
"/dashboard/settings", // was unreachable
"/dashboard/staking",
"/dashboard/usage",
"/dashboard/wallets",
"/dashboard/webhooks",
"/admin",
"/chains", // was unreachable from the console
"/agents", // was unreachable from the console
"/docs",
]
const hrefs = new Set(navHrefs(true))
const missing = built.filter((r) => !hrefs.has(r))
assert.deepEqual(missing, [], `routes with no nav row: ${missing.join(", ")}`)
})
it("points every row at a real route", () => {
// The reverse direction: a row linking to a page that does not exist is a
// 404 with a friendly name on it.
for (const href of navHrefs(true)) {
assert.match(href, /^\/(dashboard|admin|chains|agents|docs)/, href)
}
})
it("hides the admin row from non-admins", () => {
assert.ok(navHrefs(true).includes("/admin"))
assert.ok(!navHrefs(false).includes("/admin"))
})
it("marks a row current despite the trailing slash the image serves", () => {
// The static export is served as directory indexes, so the live pathname
// always ends in "/". Matching on equality alone highlighted nothing.
const hrefs = navHrefs(true)
assert.equal(currentHref("/dashboard/", hrefs), "/dashboard")
assert.equal(currentHref("/dashboard", hrefs), "/dashboard")
assert.equal(currentHref("/dashboard/analytics/", hrefs), "/dashboard/analytics")
})
it("marks exactly the most specific row current, never two", () => {
const hrefs = navHrefs(true)
// /dashboard/infrastructure/nodes is under /dashboard/infrastructure, and
// both are rows. Only the deeper one is current.
assert.equal(currentHref("/dashboard/infrastructure/nodes/", hrefs), "/dashboard/infrastructure/nodes")
assert.equal(currentHref("/dashboard/infrastructure/", hrefs), "/dashboard/infrastructure")
// A detail page under a row keeps that row current.
assert.equal(currentHref("/dashboard/infrastructure/nodes/node-7/", hrefs), "/dashboard/infrastructure/nodes")
assert.equal(currentHref("/dashboard/organization/team/", hrefs), "/dashboard/organization/team")
// And "/dashboard" must never swallow its children.
for (const path of ["/dashboard/analytics/", "/dashboard/usage/", "/dashboard/wallets/"]) {
assert.notEqual(currentHref(path, hrefs), "/dashboard", path)
}
})
it("marks nothing current off the console", () => {
assert.equal(currentHref("/pricing/", navHrefs(true)), null)
assert.equal(currentHref("/", navHrefs(true)), null)
})
it("indexes the whole nav into the command palette", () => {
const items = buildCommandItems()
const nav = items.filter((i) => i.section === "Navigation")
assert.equal(nav.length, navHrefs(true).length)
for (const item of nav) {
assert.ok(item.title, `${item.href} has no title`)
assert.ok(item.description, `${item.href} has no description`)
assert.ok(item.keywords.length >= 3)
}
assert.ok(items.some((i) => i.section === "Actions"))
})
it("has no duplicate hrefs and no empty groups", () => {
const hrefs = navHrefs(true)
assert.equal(new Set(hrefs).size, hrefs.length, "duplicate href in nav")
for (const group of DASHBOARD_NAVIGATION) {
assert.ok(group.items.length > 0, `${group.label} is empty`)
assert.ok(group.label)
}
})
})