import test from "node:test"; import assert from "node:assert/strict"; import fs from "node:fs"; import path from "node:path"; import { fileURLToPath } from "node:url"; const source = fs.readFileSync( path.join(path.dirname(fileURLToPath(import.meta.url)), "SftpHostPicker.tsx"), "utf8", ); test("sftp host picker rows reuse quick switcher selection classes", () => { assert.match(source, /getQuickSwitcherRowStateClass/); assert.match(source, /shouldUseQuickSwitcherPointerNavigation/); assert.match(source, /isKeyboardNavigating/); assert.match(source, /onMouseMove=\{\(event\) => handlePointerHover\(event\.movementX, event\.movementY\)\}/); assert.match( source, /const handlePointerHover = useCallback\(\(movementX: number, movementY: number\) => \{[\s\S]*if \(!isKeyboardNavigatingRef\.current\) return;[\s\S]*setIsKeyboardNavigating\(false\);[\s\S]*\}, \[\]\);/, ); assert.doesNotMatch( source, /const handlePointerHover = useCallback\(\(itemIndex: number, movementX: number, movementY: number\) => \{[\s\S]*setSelectedIndex\(itemIndex\);/, ); }); test("sftp host picker uses single-line quick switcher row layout", () => { assert.match( source, /className=\{`flex items-center justify-between px-4 py-2\.5 cursor-pointer transition-colors \$\{getQuickSwitcherRowStateClass/, ); assert.match( source, /className="h-6 w-6 rounded flex items-center justify-center text-muted-foreground"/, ); assert.match( source, /\{t\('sftp\.picker\.local\.title'\)\}<\/span>/, ); assert.match( source, /\{host\.label\}<\/span>/, ); assert.match( source, /className="ml-3 shrink-0 text-\[11px\] text-muted-foreground truncate max-w-\[12rem\]"/, ); assert.match(source, /formatHostMeta\(host\)/); assert.doesNotMatch(source, /bg-primary\/10 border border-primary\/30/); assert.doesNotMatch(source, /text-xs text-muted-foreground truncate/); }); test("sftp host picker passes sourceSessionId for sudo connected hosts", () => { assert.match(source, /sftpSourceSessionIdForHost/); assert.match( source, /const sourceSessionId = sftpSourceSessionIdForHost\(\s*item\.entry\.host,\s*item\.entry\.sessionId,\s*\);/, ); assert.match( source, /onSelectHost\(\s*item\.entry\.host,\s*sourceSessionId \? \{ sourceSessionId \} : undefined,\s*\)/, ); }); test("sftp host picker virtualizes the host list", () => { assert.match(source, /VariableSizeVirtualList/); assert.match(source, /data-host-picker-virtual="sftp"/); assert.match(source, /itemIndexToVisualIndex/); assert.doesNotMatch(source, /filteredHosts\.map\(\(host\) =>/); // Connected-only results must not leave a dangling empty Hosts header. assert.match(source, /if \(filteredHosts\.length > 0\) \{\s*pushHeader\('header:hosts'/); assert.match( source, /else if \(filteredConnectedHosts\.length === 0\) \{\s*pushHeader\('header:hosts'/, ); // Short lists shrink; long lists cap at 360px (not a forced blank 360px dialog). assert.match(source, /Math\.min\(360, Math\.max\(total, 1\)\)/); assert.match(source, /listViewportHeight/); assert.doesNotMatch(source, /className="h-\[360px\]"/); });