Files
NetMesh/domain/sftpFollowTerminalCwd.test.ts
zhaolei 3c72efcb7f
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
[Init] Initial commit - NetMesh terminal manager
2026-09-13 18:24:01 +08:00

552 lines
16 KiB
TypeScript

import test from "node:test";
import assert from "node:assert/strict";
import {
isFollowOriginStillCurrent,
mergeLatestFollowTerminalCwdHostSetting,
resolveHostFollowTerminalCwd,
resolveSftpFollowTerminalCwdTargetHost,
shouldApplyFollowTerminalCwdSyncResult,
shouldClearBlockedFollowOnReach,
shouldFollowTerminalCwdNavigate,
shouldInvalidateFollowBookkeepingOnCwdChange,
shouldLatchInitialFollowInterruption,
shouldReleaseInitialFollowSyncAttempt,
shouldResetInitialFollowTerminalCwdSync,
} from "./sftpFollowTerminalCwd";
const base = {
followEnabled: true,
isVisible: true,
terminalCwd: "/home/user/project",
currentPath: "/home/user",
connectionId: "conn-1",
hasActiveWork: false,
isConnected: true,
};
test("shouldFollowTerminalCwdNavigate returns true when follow is on and paths differ", () => {
assert.equal(shouldFollowTerminalCwdNavigate(base), true);
});
test("shouldFollowTerminalCwdNavigate returns false when paths already match", () => {
assert.equal(
shouldFollowTerminalCwdNavigate({ ...base, currentPath: "/home/user/project" }),
false,
);
});
test("shouldFollowTerminalCwdNavigate returns false when follow is disabled", () => {
assert.equal(shouldFollowTerminalCwdNavigate({ ...base, followEnabled: false }), false);
});
test("shouldFollowTerminalCwdNavigate returns false while interactive work is active", () => {
assert.equal(shouldFollowTerminalCwdNavigate({ ...base, hasActiveWork: true }), false);
});
test("shouldFollowTerminalCwdNavigate returns false without a known terminal cwd", () => {
assert.equal(shouldFollowTerminalCwdNavigate({ ...base, terminalCwd: null }), false);
});
test("shouldFollowTerminalCwdNavigate returns false when cwd is blocked after a failed follow", () => {
assert.equal(
shouldFollowTerminalCwdNavigate({
...base,
blockedFollow: { connectionId: "conn-1", terminalCwd: "/home/user/project" },
}),
false,
);
});
test("shouldFollowTerminalCwdNavigate ignores blocked cwd for a different connection", () => {
assert.equal(
shouldFollowTerminalCwdNavigate({
...base,
connectionId: "conn-2",
blockedFollow: { connectionId: "conn-1", terminalCwd: "/home/user/project" },
}),
true,
);
});
test("shouldFollowTerminalCwdNavigate ignores blocked cwd when terminal cwd changed", () => {
assert.equal(
shouldFollowTerminalCwdNavigate({
...base,
terminalCwd: "/home/user/other",
blockedFollow: { connectionId: "conn-1", terminalCwd: "/home/user/project" },
}),
true,
);
});
test("shouldFollowTerminalCwdNavigate does not recapture manual navigation after the cwd was handled", () => {
assert.equal(
shouldFollowTerminalCwdNavigate({
...base,
currentPath: "/srv/bookmark",
handledFollow: { connectionId: "conn-1", terminalCwd: "/home/user/project" },
}),
false,
);
});
test("shouldFollowTerminalCwdNavigate resumes when the terminal cwd changes", () => {
assert.equal(
shouldFollowTerminalCwdNavigate({
...base,
terminalCwd: "/home/user/other",
currentPath: "/srv/bookmark",
handledFollow: { connectionId: "conn-1", terminalCwd: "/home/user/project" },
}),
true,
);
});
test("resolveHostFollowTerminalCwd inherits the global setting until the host overrides it", () => {
assert.equal(resolveHostFollowTerminalCwd(undefined, true), true);
assert.equal(resolveHostFollowTerminalCwd(undefined, false), false);
assert.equal(resolveHostFollowTerminalCwd(true, false), true);
assert.equal(resolveHostFollowTerminalCwd(false, true), false);
});
test("resolveSftpFollowTerminalCwdTargetHost prefers the visible SFTP host", () => {
const terminalHost = { id: "terminal-host" };
const visibleHost = { id: "visible-sftp-host" };
assert.equal(
resolveSftpFollowTerminalCwdTargetHost(visibleHost, terminalHost),
visibleHost,
);
assert.equal(
resolveSftpFollowTerminalCwdTargetHost(null, terminalHost),
terminalHost,
);
});
test("visible SFTP host override can enable follow when terminal host inherits global off", () => {
const terminalHost = { id: "terminal-host", sftpFollowTerminalCwd: undefined };
const visibleHost = { id: "visible-sftp-host", sftpFollowTerminalCwd: true };
const followHost = resolveSftpFollowTerminalCwdTargetHost(visibleHost, terminalHost);
assert.equal(resolveHostFollowTerminalCwd(followHost?.sftpFollowTerminalCwd, false), true);
});
test("mergeLatestFollowTerminalCwdHostSetting refreshes the follow flag without losing display overrides", () => {
const connectedHost = {
id: "host-1",
hostname: "session.example.com",
sftpFollowTerminalCwd: false,
};
const latestHost = {
id: "host-1",
hostname: "vault.example.com",
sftpFollowTerminalCwd: true,
};
assert.deepEqual(
mergeLatestFollowTerminalCwdHostSetting(connectedHost, latestHost),
{
id: "host-1",
hostname: "session.example.com",
sftpFollowTerminalCwd: true,
},
);
});
test("mergeLatestFollowTerminalCwdHostSetting keeps optimistic session override until vault updates", () => {
const connectedHost = {
id: "host-1",
hostname: "session.example.com",
sftpFollowTerminalCwd: false,
};
const latestHost = {
id: "host-1",
hostname: "vault.example.com",
};
assert.deepEqual(
mergeLatestFollowTerminalCwdHostSetting(connectedHost, latestHost, false),
{
id: "host-1",
hostname: "session.example.com",
sftpFollowTerminalCwd: false,
},
);
});
test("mergeLatestFollowTerminalCwdHostSetting drops stale session override when vault clears the follow flag", () => {
const connectedHost = {
id: "host-1",
hostname: "session.example.com",
sftpFollowTerminalCwd: true,
};
const latestHost = {
id: "host-1",
hostname: "vault.example.com",
};
assert.deepEqual(
mergeLatestFollowTerminalCwdHostSetting(connectedHost, latestHost),
{
id: "host-1",
hostname: "session.example.com",
sftpFollowTerminalCwd: undefined,
},
);
});
test("shouldClearBlockedFollowOnReach clears when the active connection reaches the blocked cwd", () => {
assert.equal(
shouldClearBlockedFollowOnReach(
{ connectionId: "conn-1", terminalCwd: "/home/user/project" },
"conn-1",
"/home/user/project",
false,
),
true,
);
});
test("shouldClearBlockedFollowOnReach keeps block while navigation is still loading", () => {
assert.equal(
shouldClearBlockedFollowOnReach(
{ connectionId: "conn-1", terminalCwd: "/home/user/project" },
"conn-1",
"/home/user/project",
true,
),
false,
);
});
test("shouldApplyFollowTerminalCwdSyncResult rejects stale follow results after cwd changes", () => {
let generation = 0;
const followA = generation;
generation += 1;
const followB = generation;
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: followB,
currentGeneration: generation,
followEnabled: true,
canFollow: true,
}),
true,
);
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: followA,
currentGeneration: generation,
followEnabled: true,
canFollow: true,
}),
false,
);
});
test("shouldApplyFollowTerminalCwdSyncResult rejects results after follow is unavailable", () => {
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: false,
canFollow: true,
}),
false,
);
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: false,
}),
false,
);
});
test("isFollowOriginStillCurrent treats a missing origin as bound to the live focused terminal", () => {
assert.equal(isFollowOriginStillCurrent({
expectedOriginId: null,
liveOriginId: null,
}), true);
assert.equal(isFollowOriginStillCurrent({
expectedOriginId: null,
liveOriginId: "mosh-b",
}), false);
assert.equal(isFollowOriginStillCurrent({
expectedOriginId: "mosh-a",
liveOriginId: "mosh-b",
}), false);
assert.equal(isFollowOriginStillCurrent({
expectedOriginId: "mosh-a",
liveOriginId: "mosh-a",
}), true);
});
test("shouldApplyFollowTerminalCwdSyncResult rejects a null origin after focus appears", () => {
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedSessionId: null,
liveSessionId: null,
}),
true,
);
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedSessionId: null,
liveSessionId: "mosh-b",
}),
false,
);
});
test("shouldApplyFollowTerminalCwdSyncResult rejects results after the focused session changes", () => {
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedSessionId: "session-a",
liveSessionId: "session-b",
}),
false,
);
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedSessionId: "session-a",
liveSessionId: "session-a",
}),
true,
);
});
test("shouldApplyFollowTerminalCwdSyncResult rejects results for an old connection", () => {
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedConnectionId: "conn-1",
liveConnectionId: "conn-2",
paneConnectionId: "conn-2",
}),
false,
);
});
test("shouldApplyFollowTerminalCwdSyncResult rejects results for an old terminal cwd", () => {
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedConnectionId: "conn-1",
liveConnectionId: "conn-1",
paneConnectionId: "conn-1",
expectedTerminalCwd: "/srv/old",
liveTerminalCwd: "/srv/new",
}),
false,
);
});
test("shouldApplyFollowTerminalCwdSyncResult rejects missing live cwd when required", () => {
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedConnectionId: "conn-1",
liveConnectionId: "conn-1",
paneConnectionId: "conn-1",
expectedTerminalCwd: "/srv/project",
liveTerminalCwd: null,
requireLiveTerminalCwd: true,
}),
false,
);
});
test("shouldApplyFollowTerminalCwdSyncResult allows missing live cwd when target was fetched fresh", () => {
assert.equal(
shouldApplyFollowTerminalCwdSyncResult({
syncGeneration: 2,
currentGeneration: 2,
followEnabled: true,
canFollow: true,
expectedConnectionId: "conn-1",
liveConnectionId: "conn-1",
paneConnectionId: "conn-1",
expectedTerminalCwd: "/srv/project",
liveTerminalCwd: null,
}),
true,
);
});
test("follow bookkeeping keeps handled state across hidden-panel null cwd transitions", () => {
// Hidden panels receive activeTerminalCwd={null} and get the last live value
// back on reshow: the visibility transitions may not drop handled follow
// bookkeeping when the cwd did not actually change.
assert.equal(
shouldInvalidateFollowBookkeepingOnCwdChange({
nextCwd: null,
lastCwd: "/home/user/project",
isVisible: false,
}),
false,
);
assert.equal(
shouldInvalidateFollowBookkeepingOnCwdChange({
nextCwd: "/home/user/project",
lastCwd: "/home/user/project",
isVisible: false,
}),
false,
);
assert.equal(
shouldInvalidateFollowBookkeepingOnCwdChange({
nextCwd: "/home/user/project",
lastCwd: "/home/user/project",
isVisible: true,
}),
false,
);
assert.equal(
shouldInvalidateFollowBookkeepingOnCwdChange({
nextCwd: null,
lastCwd: null,
isVisible: false,
}),
false,
);
});
test("follow bookkeeping invalidates on a real terminal cwd change", () => {
assert.equal(
shouldInvalidateFollowBookkeepingOnCwdChange({
nextCwd: "/home/user/other",
lastCwd: "/home/user/project",
isVisible: true,
}),
true,
);
// A cwd that changed while the panel was hidden still invalidates on reshow.
assert.equal(
shouldInvalidateFollowBookkeepingOnCwdChange({
nextCwd: "/home/user/other",
lastCwd: null,
isVisible: true,
}),
true,
);
// A `null` while the surface is visible means the linked terminal session
// changed (or closed) and its cwd cache is empty: in-flight follow results
// of the previous session must be invalidated.
assert.equal(
shouldInvalidateFollowBookkeepingOnCwdChange({
nextCwd: null,
lastCwd: "/home/user/project",
isVisible: true,
}),
true,
);
});
test("first-open sync reset re-arms on a replaced connection", () => {
assert.equal(
shouldResetInitialFollowTerminalCwdSync({
isVisible: true,
ownerPanelOpen: true,
connectionId: "conn-2",
trackedConnectionId: "conn-1",
}),
true,
);
});
test("first-open sync reset re-arms after a fresh open on the same connection", () => {
assert.equal(
shouldResetInitialFollowTerminalCwdSync({
isVisible: false,
ownerPanelOpen: false,
connectionId: "conn-1",
trackedConnectionId: "conn-1",
}),
true,
);
});
test("first-open sync reset survives hiding the surface while the owner panel stays open", () => {
// Terminal tab switches / side-panel tool switches keep the panel mounted
// and open: the user's browsed directory and filename filter must survive.
assert.equal(
shouldResetInitialFollowTerminalCwdSync({
isVisible: false,
ownerPanelOpen: true,
connectionId: "conn-1",
trackedConnectionId: "conn-1",
}),
false,
);
assert.equal(
shouldResetInitialFollowTerminalCwdSync({
isVisible: true,
ownerPanelOpen: true,
connectionId: "conn-1",
trackedConnectionId: "conn-1",
}),
false,
);
});
test("first-open sync attempt is released while visible or after the owner panel closed", () => {
assert.equal(shouldReleaseInitialFollowSyncAttempt({ isVisible: true, ownerPanelOpen: true }), true);
assert.equal(shouldReleaseInitialFollowSyncAttempt({ isVisible: true, ownerPanelOpen: false }), true);
assert.equal(shouldReleaseInitialFollowSyncAttempt({ isVisible: false, ownerPanelOpen: false }), true);
});
test("first-open sync attempt stays consumed while hidden with the owner panel open", () => {
// Terminal tab switch while the fresh-CWD probe is still pending: the
// interrupted attempt must not re-arm, or returning to the tab re-runs the
// first-open sync and navigates away from the browsed directory.
assert.equal(shouldReleaseInitialFollowSyncAttempt({ isVisible: false, ownerPanelOpen: true }), false);
});
test("first-open probe is latched as interrupted on a hide with the owner panel open", () => {
// Terminal-tab switch while the fresh-CWD probe is pending: the probe must be
// latched as interrupted so it cannot navigate once the tab is reshown.
assert.equal(
shouldLatchInitialFollowInterruption({ isVisible: false, ownerPanelOpen: true }),
true,
);
assert.equal(
shouldLatchInitialFollowInterruption({ isVisible: true, ownerPanelOpen: true }),
false,
);
// A panel close is not an interruption latch: the reset guard re-arms there.
assert.equal(
shouldLatchInitialFollowInterruption({ isVisible: false, ownerPanelOpen: false }),
false,
);
});