150 lines
4.8 KiB
TypeScript
150 lines
4.8 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
|
||
const {
|
||
DEFAULT_TERMINAL_RESUME_MINUTES,
|
||
MAX_TERMINAL_RESUME_MINUTES,
|
||
buildTerminalSessionSnapshot,
|
||
isTerminalSessionAiHighlighted,
|
||
isTerminalSessionConnecting,
|
||
isTerminalSessionHighlighted,
|
||
normalizeCodexSandboxMode,
|
||
normalizeTerminalResumeMinutes,
|
||
normalizeTerminalSessionSnapshot,
|
||
resolveTerminalResumeGraceMs
|
||
} = require("./terminalSessionState");
|
||
|
||
describe("terminalSessionState", () => {
|
||
it("收敛后台保活分钟数到合法区间", () => {
|
||
expect(normalizeTerminalResumeMinutes(undefined)).toBe(DEFAULT_TERMINAL_RESUME_MINUTES);
|
||
expect(normalizeTerminalResumeMinutes(0)).toBe(1);
|
||
expect(normalizeTerminalResumeMinutes(MAX_TERMINAL_RESUME_MINUTES + 10)).toBe(
|
||
MAX_TERMINAL_RESUME_MINUTES
|
||
);
|
||
});
|
||
|
||
it("根据设置生成毫秒级续接窗口", () => {
|
||
expect(resolveTerminalResumeGraceMs({ backgroundSessionKeepAliveMinutes: 15 })).toBe(15 * 60 * 1000);
|
||
});
|
||
|
||
it("保留未过期的可续接快照", () => {
|
||
const now = 1_700_000_000_000;
|
||
const snapshot = buildTerminalSessionSnapshot(
|
||
{
|
||
serverId: "srv-1",
|
||
serverLabel: "server-1",
|
||
sessionId: "mini-1",
|
||
sessionKey: "mini-key-1",
|
||
status: "resumable",
|
||
activeAiProvider: "codex",
|
||
codexSandboxMode: "danger-full-access",
|
||
resumeGraceMs: 15 * 60 * 1000
|
||
},
|
||
now
|
||
);
|
||
|
||
expect(snapshot).toBeTruthy();
|
||
expect(snapshot && snapshot.codexSandboxMode).toBe("danger-full-access");
|
||
expect(normalizeTerminalSessionSnapshot(snapshot, now + 1000)).toEqual(snapshot);
|
||
expect(normalizeTerminalSessionSnapshot(snapshot, now + 15 * 60 * 1000 + 1)).toBeNull();
|
||
});
|
||
|
||
it("仅在 Codex 前台态下保留 sandbox,并收敛脏值", () => {
|
||
const now = 1_700_000_000_000;
|
||
|
||
expect(normalizeCodexSandboxMode("danger-full-access")).toBe("danger-full-access");
|
||
expect(normalizeCodexSandboxMode("invalid")).toBe("workspace-write");
|
||
expect(normalizeCodexSandboxMode("")).toBe("");
|
||
|
||
const codexSnapshot = buildTerminalSessionSnapshot(
|
||
{
|
||
serverId: "srv-codex",
|
||
sessionId: "mini-codex",
|
||
sessionKey: "mini-key-codex",
|
||
status: "connected",
|
||
activeAiProvider: "codex",
|
||
codexSandboxMode: "invalid",
|
||
resumeGraceMs: 15 * 60 * 1000
|
||
},
|
||
now
|
||
);
|
||
const copilotSnapshot = buildTerminalSessionSnapshot(
|
||
{
|
||
serverId: "srv-copilot",
|
||
sessionId: "mini-copilot",
|
||
sessionKey: "mini-key-copilot",
|
||
status: "connected",
|
||
activeAiProvider: "copilot",
|
||
codexSandboxMode: "danger-full-access",
|
||
resumeGraceMs: 15 * 60 * 1000
|
||
},
|
||
now
|
||
);
|
||
|
||
expect(codexSnapshot && codexSnapshot.codexSandboxMode).toBe("workspace-write");
|
||
expect(copilotSnapshot && copilotSnapshot.codexSandboxMode).toBe("");
|
||
});
|
||
|
||
it("区分高亮态与连接中态", () => {
|
||
const now = 1_700_000_000_000;
|
||
const resumable = buildTerminalSessionSnapshot(
|
||
{
|
||
serverId: "srv-2",
|
||
sessionId: "mini-2",
|
||
sessionKey: "mini-key-2",
|
||
status: "resumable",
|
||
activeAiProvider: "copilot",
|
||
resumeGraceMs: 15 * 60 * 1000
|
||
},
|
||
now
|
||
);
|
||
const connecting = buildTerminalSessionSnapshot(
|
||
{
|
||
serverId: "srv-3",
|
||
sessionId: "mini-3",
|
||
sessionKey: "mini-key-3",
|
||
status: "connecting",
|
||
activeAiProvider: "invalid",
|
||
resumeGraceMs: 15 * 60 * 1000
|
||
},
|
||
now
|
||
);
|
||
|
||
expect(isTerminalSessionHighlighted(resumable, "srv-2", now)).toBe(true);
|
||
expect(isTerminalSessionConnecting(resumable, "srv-2", now)).toBe(false);
|
||
expect(isTerminalSessionConnecting(connecting, "srv-3", now)).toBe(true);
|
||
expect(isTerminalSessionHighlighted(connecting, "srv-3", now)).toBe(false);
|
||
expect(connecting && connecting.activeAiProvider).toBe("");
|
||
});
|
||
|
||
it("仅在目标服务器存在 AI 前台态时点亮 AI 按钮", () => {
|
||
const now = 1_700_000_000_000;
|
||
const aiResumable = buildTerminalSessionSnapshot(
|
||
{
|
||
serverId: "srv-ai",
|
||
sessionId: "mini-ai",
|
||
sessionKey: "mini-key-ai",
|
||
status: "resumable",
|
||
activeAiProvider: "copilot",
|
||
resumeGraceMs: 15 * 60 * 1000
|
||
},
|
||
now
|
||
);
|
||
const plainConnected = buildTerminalSessionSnapshot(
|
||
{
|
||
serverId: "srv-shell",
|
||
sessionId: "mini-shell",
|
||
sessionKey: "mini-key-shell",
|
||
status: "connected",
|
||
activeAiProvider: "",
|
||
resumeGraceMs: 15 * 60 * 1000
|
||
},
|
||
now
|
||
);
|
||
|
||
expect(isTerminalSessionAiHighlighted(aiResumable, "srv-ai", now)).toBe(true);
|
||
expect(isTerminalSessionAiHighlighted(aiResumable, "srv-other", now)).toBe(false);
|
||
expect(isTerminalSessionAiHighlighted(plainConnected, "srv-shell", now)).toBe(false);
|
||
expect(isTerminalSessionAiHighlighted(null, "srv-ai", now)).toBe(false);
|
||
});
|
||
});
|