Files
NetMesh/components/sftp/SftpHostPicker.test.ts

81 lines
3.2 KiB
TypeScript
Raw Normal View History

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,
/<span className="text-sm font-medium truncate">\{t\('sftp\.picker\.local\.title'\)\}<\/span>/,
);
assert.match(
source,
/<span className="text-sm font-medium truncate">\{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\]"/);
});