Files
ClusterCanvas/webui/src/navigation.test.ts
T
Squid 32af91fd30 Add per-node action groups with schedules, runs, and logs.
Let operators manage ordered action groups on each host, run them manually or on a schedule over SSH, and inspect disk-backed JSON run logs from a node detail UI.
2026-07-19 20:01:11 +02:00

118 lines
3.6 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { parseLocation, pathFor } from './navigation'
describe('pathFor', () => {
it('maps sections and config tabs to paths', () => {
expect(pathFor('overview')).toBe('/')
expect(pathFor('vms')).toBe('/vms')
expect(pathFor('docker')).toBe('/docker')
expect(pathFor('containers')).toBe('/containers')
expect(pathFor('vms', 'overview', 'security')).toBe('/vms/security')
expect(pathFor('containers', 'overview', 'add')).toBe('/containers/add')
expect(pathFor('docker', 'overview', 'add')).toBe('/docker/add')
expect(pathFor('profile')).toBe('/profile')
expect(pathFor('logs')).toBe('/logs')
expect(pathFor('setup')).toBe('/setup')
expect(pathFor('login')).toBe('/login')
expect(pathFor('configuration')).toBe('/configuration')
expect(pathFor('configuration', 'overview')).toBe('/configuration')
expect(pathFor('configuration', 'groups')).toBe('/configuration/groups')
expect(pathFor('configuration', 'actions')).toBe('/configuration/actions')
expect(pathFor('configuration', 'roles')).toBe('/configuration/roles')
})
it('maps node detail paths', () => {
expect(pathFor('containers', 'overview', 'overview', 'node-1')).toBe(
'/containers/node-1',
)
expect(
pathFor('containers', 'overview', 'overview', 'node-1', 'actions'),
).toBe('/containers/node-1/actions')
expect(pathFor('vms', 'overview', 'overview', 'abc', 'logs')).toBe(
'/vms/abc/logs',
)
})
})
describe('parseLocation', () => {
it('round-trips known paths', () => {
for (const path of [
'/',
'/vms',
'/docker',
'/containers',
'/vms/security',
'/containers/add',
'/docker/overview',
'/profile',
'/logs',
'/setup',
'/login',
'/configuration',
'/configuration/users',
'/configuration/roles',
'/configuration/groups',
'/configuration/actions',
'/configuration/security',
'/configuration/integrations',
'/configuration/network',
'/configuration/advanced',
'/containers/node-1',
'/containers/node-1/actions',
'/vms/node-2/logs',
]) {
const location = parseLocation(path)
expect(
pathFor(
location.section,
location.configTab,
location.resourceTab,
location.nodeId,
location.nodeDetailTab,
),
).toBe(path === '/docker/overview' ? '/docker' : path)
}
})
it('falls back to overview for unknown paths', () => {
expect(parseLocation('/nope')).toEqual({
section: 'overview',
configTab: 'overview',
resourceTab: 'overview',
nodeId: null,
nodeDetailTab: 'overview',
})
expect(parseLocation('/configuration/unknown')).toEqual({
section: 'overview',
configTab: 'overview',
resourceTab: 'overview',
nodeId: null,
nodeDetailTab: 'overview',
})
expect(parseLocation('/vms/extra')).toEqual({
section: 'vms',
configTab: 'overview',
resourceTab: 'overview',
nodeId: 'extra',
nodeDetailTab: 'overview',
})
expect(parseLocation('/docker/extra/nope')).toEqual({
section: 'overview',
configTab: 'overview',
resourceTab: 'overview',
nodeId: null,
nodeDetailTab: 'overview',
})
})
it('treats trailing slashes as the same path', () => {
expect(parseLocation('/configuration/groups/')).toEqual({
section: 'configuration',
configTab: 'groups',
resourceTab: 'overview',
nodeId: null,
nodeDetailTab: 'overview',
})
})
})