// @vitest-environment jsdom import { cleanup, render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { afterEach, describe, expect, it, vi } from 'vitest'; import { InstanceSettingsPage, sanitizeFleetSnapshot, type FleetDataSource, type FleetSnapshot, } from './instance-settings-page.js'; afterEach(cleanup); function deferredSource() { let resolve!: (value: FleetSnapshot) => void; let reject!: (reason: unknown) => void; const load = vi.fn( () => new Promise((done, fail) => { resolve = done; reject = fail; }), ); return { source: { load }, load, resolve: (value: FleetSnapshot) => resolve(value), reject: (reason: unknown) => reject(reason), }; } const snapshot: FleetSnapshot = { instances: [ { id: 'west/one', name: 'West modem', url: 'https://operator:secret@west.example:8443/admin?token=secret', description: 'must not appear', tags: ['private-tag'], }, { id: 'offline', url: 'javascript:alert(1)' }, ], statuses: new Map([ [ 'west/one', { reachable: true, authenticated: true, latencyMs: 12, summary: { capabilities: ['messages', 'calls', 7], freshness: 'fresh', password: 'never-render', credentialConfigured: true, version: 'also-not-part-of-this-page', }, }, ], ['offline', { reachable: false }], ]), }; describe('Settings instances page', () => { it('rejects identity values instead of trimming, truncating, or admitting controls', () => { const longId = 'x'.repeat(257); const source = (id: string, name?: string) => ({ instances: [{ id, url: 'https://example.test', ...(name === undefined ? {} : { name }) }], statuses: new Map(), }); for (const id of [' padded', 'padded ', longId, 'line\nbreak', 'null\0byte']) { expect(sanitizeFleetSnapshot(source(id))).toEqual({ instances: [], statuses: new Map() }); } expect(sanitizeFleetSnapshot(source('stable-id', ` ${'n'.repeat(300)} `))?.instances).toEqual( [{ id: 'stable-id', url: 'https://example.test', name: 'n'.repeat(256) }], ); }); it('is explicitly unavailable without an injected fleet source', () => { render(); expect(screen.getByRole('heading', { name: 'Instances' })).toBeTruthy(); expect(screen.getByRole('status', { name: 'Instances unavailable' }).textContent).toMatch( /no fleet data source/i, ); expect(screen.getByRole('link', { name: 'Add instance' }).getAttribute('href')).toBe( '/instances/new', ); }); it('loads and renders an accessible, safe settings list using only fleet fields', async () => { const pending = deferredSource(); render(); expect(screen.getByRole('status', { name: 'Instances loading status' })).toBeTruthy(); expect(pending.load).toHaveBeenCalledWith(expect.any(AbortSignal)); pending.resolve(snapshot); const list = await screen.findByRole('list', { name: 'Configured instances' }); const west = within(list).getByRole('listitem', { name: 'West modem' }); expect(within(west).getByRole('link', { name: 'West modem' }).getAttribute('href')).toBe( '/settings/instances/west%2Fone', ); const origin = within(west).getByRole('link', { name: 'Open West modem origin' }); expect(origin.getAttribute('href')).toBe('https://west.example:8443'); expect(origin.getAttribute('rel')).toBe('noopener noreferrer'); for (const value of ['Online', 'Authenticated', 'Fresh', 'messages, calls']) expect(within(west).getByText(value)).toBeTruthy(); const offline = within(list).getByRole('listitem', { name: 'offline' }); expect(within(offline).getByText('Invalid origin')).toBeTruthy(); expect(within(offline).getByText('Offline')).toBeTruthy(); expect(within(offline).queryByText(/authentication|freshness|capabilities/i)).toBeNull(); expect(document.body.textContent).not.toMatch( /secret|must not appear|private-tag|never-render|credentialConfigured|also-not-part/, ); }); it('shows a fixed error, retries, and never exposes rejection details', async () => { const user = userEvent.setup(); const load = vi .fn() .mockRejectedValueOnce(new Error('password=top-secret')) .mockResolvedValueOnce({ instances: [], statuses: new Map() }); render(); const alert = await screen.findByRole('alert'); expect(alert.textContent).toBe('Instances could not be loaded.Retry loading instances'); expect(document.body.textContent).not.toContain('top-secret'); await user.click(screen.getByRole('button', { name: 'Retry loading instances' })); expect(await screen.findByText('No instances are configured.')).toBeTruthy(); expect(load).toHaveBeenCalledTimes(2); }); it('aborts superseded loads and fences late results', async () => { const first = deferredSource(); const second = deferredSource(); let calls = 0; const load = vi.fn((signal) => (calls++ === 0 ? first : second).source.load(signal), ); const source = { load }; const { rerender } = render(); const oldSignal = load.mock.calls[0]?.[0]; rerender(); expect(oldSignal?.aborted).toBe(true); first.resolve({ instances: [{ id: 'stale', url: 'https://stale.example' }], statuses: new Map(), }); second.resolve({ instances: [{ id: 'current', url: 'https://current.example' }], statuses: new Map(), }); expect(await screen.findByRole('link', { name: 'current' })).toBeTruthy(); expect(screen.queryByRole('link', { name: 'stale' })).toBeNull(); }); });