Files
homelable/frontend/src/components/proxmox/__tests__/clusterEdges.test.ts
T
Pouzor 9670d0a86a feat: proxmox import diagnostics, node style fix, and cluster edges
Scan History:
- Proxmox is now a first-class scan kind (badge, filter chip, Server icon,
  completion toast) instead of being mislabeled as an IP scan.
- A done run carrying a non-fatal advisory renders amber (info) with a
  warning toast, distinct from red failures.

Import diagnostics:
- test-connection probes /access/permissions and warns when the API token
  has no ACL (VMs/LXC would be invisible) — points at the PVEAuditor grant.
- import surfaces an advisory when hosts import but no guests are visible
  (privilege-separated token whose rights are the intersection with the user),
  rather than a silent "done".

Node style:
- Proxmox container mode is now opt-in (container_mode === true), matching the
  rest of the codebase (App.tsx nesting logic). Imported proxmox nodes leave
  the flag unset and render like a manually-created node instead of an empty
  group container.

Cluster edges:
- Hosts from one import are chained with 'cluster' edges via left/right handles,
  distinct from the vertical host->guest 'virtual' edges. Wired for both the
  direct "Add to Canvas" path and the pending -> approve path (host<->host
  proxmox_cluster links, resolved to cluster edges on approve; cluster hosts
  get left/right handles).

Tests added on both sides.

ha-relevant: maybe
2026-07-06 10:26:52 +02:00

46 lines
1.6 KiB
TypeScript

import { describe, it, expect } from 'vitest'
import {
buildProxmoxClusterEdges,
isProxmoxCluster,
CLUSTER_SOURCE_HANDLE,
CLUSTER_TARGET_HANDLE,
} from '../clusterEdges'
import type { ProxmoxNode } from '../types'
function host(id: string): ProxmoxNode {
return { id, label: id, type: 'proxmox', ieee_address: id, status: 'online' }
}
function guest(id: string, type: 'vm' | 'lxc' = 'vm'): ProxmoxNode {
return { id, label: id, type, ieee_address: id, status: 'online' }
}
describe('buildProxmoxClusterEdges', () => {
it('chains multiple hosts left→right, ignoring guests', () => {
const nodes = [host('pve-a'), guest('vm-1'), host('pve-b'), host('pve-c'), guest('ct-1', 'lxc')]
const edges = buildProxmoxClusterEdges(nodes)
expect(edges.map((e) => [e.source, e.target])).toEqual([
['pve-a', 'pve-b'],
['pve-b', 'pve-c'],
])
// Endpoints use the left/right handles.
for (const e of edges) {
expect(e.sourceHandle).toBe(CLUSTER_SOURCE_HANDLE)
expect(e.targetHandle).toBe(CLUSTER_TARGET_HANDLE)
}
})
it('returns no edges for a single host', () => {
expect(buildProxmoxClusterEdges([host('pve-a'), guest('vm-1')])).toEqual([])
})
it('returns no edges when there are no hosts', () => {
expect(buildProxmoxClusterEdges([guest('vm-1'), guest('ct-1', 'lxc')])).toEqual([])
})
it('isProxmoxCluster is true only with 2+ hosts', () => {
expect(isProxmoxCluster([host('a')])).toBe(false)
expect(isProxmoxCluster([host('a'), host('b')])).toBe(true)
expect(isProxmoxCluster([host('a'), guest('vm-1')])).toBe(false)
})
})