From 6f3547bc5fbb10ddf313a8cd2f184b6359173a59 Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Tue, 8 Sep 2026 23:02:25 +0100 Subject: [PATCH] test(web): trace agent-only NAS through Proxmox table projection The new #1930 payload has agent and Docker sources without cluster metadata. Retain a sanitised API-to-table boundary test alongside a real PVE-shaped neighbour to distinguish that evidence from the earlier screenshot; this is diagnostic coverage, not a reproduced reporter fix. Change-source: pulse-maintainer --- .../__tests__/useUnifiedResources.test.ts | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/frontend-modern/src/hooks/__tests__/useUnifiedResources.test.ts b/frontend-modern/src/hooks/__tests__/useUnifiedResources.test.ts index 45ea92111..761ed090b 100644 --- a/frontend-modern/src/hooks/__tests__/useUnifiedResources.test.ts +++ b/frontend-modern/src/hooks/__tests__/useUnifiedResources.test.ts @@ -1,6 +1,7 @@ import { batch, createRoot, createSignal } from 'solid-js'; import { createStore, reconcile, type SetStoreFunction } from 'solid-js/store'; import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'; +import { buildProxmoxPageModel } from '@/features/proxmox/proxmoxPageModel'; import type { State } from '@/types/api'; import type { Resource } from '@/types/resource'; import useUnifiedResourcesSource from '../useUnifiedResources.ts?raw'; @@ -1339,6 +1340,54 @@ describe('useUnifiedResources', () => { dispose(); }); + it('keeps an agent-plus-docker NAS out of the Proxmox table after API projection', async () => { + // #1930's supplied field shape, with entirely synthetic identities and no + // addresses or token metadata. This does not reproduce the earlier screenshot. + apiFetchMock.mockResolvedValueOnce({ + ok: true, + json: async () => ({ + data: [ + { + ...v2Resource, + id: 'synthetic-nas', + name: 'synthetic-nas', + technology: 'linux', + sources: ['agent', 'docker'], + platformScopes: ['agent', 'docker'], + canonicalIdentity: { displayName: 'synthetic-nas', platformId: 'synthetic-nas' }, + identity: { hostnames: ['synthetic-nas'] }, + agent: { platform: 'linux', osName: 'Synology DSM' }, + }, + { + ...v2Resource, + id: 'synthetic-pve', + sources: ['proxmox'], + proxmox: { nodeName: 'synthetic-pve', clusterName: 'synthetic-cluster' }, + }, + ], + }), + }); + let dispose = () => {}; + let result: ReturnType | undefined; + createRoot((d) => { + dispose = d; + result = useUnifiedResources({ query: 'type=agent', cacheKey: 'nas-boundary' }); + }); + try { + await result!.refetch(); + const resources = result!.resources(); + const nas = resources.find((resource) => resource.id === 'synthetic-nas'); + expect(nas).toBeDefined(); + expect(nas?.clusterId).toBeUndefined(); + expect(nas?.proxmox).toBeUndefined(); + expect(buildProxmoxPageModel(resources).pveNodes.map((node) => node.id)).toEqual([ + 'synthetic-pve', + ]); + } finally { + dispose(); + } + }); + it('projects proxmox clusterId from the shared cluster helper', async () => { apiFetchMock.mockResolvedValueOnce({ ok: true,