Files
openidea/src/workbench/projectWindow.test.ts
T
l0ng-ai 2c9a6470ff feat(project): add project trust and restricted execution mode (#517)
Projects now open with a user-owned trust decision. The prompt offers Preview in Restricted Mode, Don't Open and Trust Project, with an optional trusted parent folder; preview is the default focus so Enter never grants trust.

Restricted projects keep browsing, editing, saving, search and highlighting. Project-controlled execution is denied by default in the backend: run, debug, build, tools, language servers, plugins and Git commands that could honour repository configuration. Trusting a project enables those paths without reopening it, and decisions can be revoked in Settings.

Terminals stay available when the user opens one, without project shell settings, environment or virtualenv activation. A shell prompt that runs git in the folder can still honour the repository's core.fsmonitor.

Fixes #462
2026-10-31 20:58:45 +08:00

47 lines
1.9 KiB
TypeScript

import { beforeEach, expect, it, vi } from "vitest";
import { useProject } from "@/platform/project";
import { chooseProjectWindow, openPolicy } from "./projectWindow";
import { ask } from "./messages";
import { commands } from "@/platform/ipc";
vi.mock("./messages", () => ({ ask: vi.fn() }));
vi.mock("@/platform/remote", () => ({
isRemoteWindow: () => false,
connectRemote: vi.fn(),
}));
vi.mock("@/platform/ipc", () => ({
call: (p: unknown) => p,
commands: {
settingsSet: vi.fn(async () => ({ general: { openProjectIn: "attach" } })),
},
}));
beforeEach(() => {
vi.clearAllMocks();
useProject.setState({
project: { root: "/a", name: "A", settings: {}, trusted: true, isGit: false },
settings: {},
lightEdit: false,
});
});
it("offers IDEA's four choices with This Window primary and remembers Attach", async () => {
vi.mocked(ask).mockResolvedValue({ button: "attach", checked: true });
expect(await chooseProjectWindow("B")).toBe("attach");
const prompt = vi.mocked(ask).mock.calls[0]![0];
expect(prompt.buttons.map((b) => b.id)).toEqual(["cancel", "attach", "new", "same"]);
expect(prompt.buttons.filter((b) => b.primary).map((b) => b.id)).toEqual(["same"]);
expect(commands.settingsSet).toHaveBeenCalledWith("global", "general.openProjectIn", '"attach"');
expect(openPolicy()).toBe("attach");
expect(await chooseProjectWindow("C")).toBe("attach");
expect(ask).toHaveBeenCalledTimes(1);
});
it("does not attach without a project or when opening a remote project", async () => {
useProject.setState({
settings: { general: { openProjectIn: "attach" } } as never,
});
vi.mocked(ask).mockResolvedValue({ button: "cancel", checked: false });
expect(await chooseProjectWindow("remote", false)).toBeNull();
expect(vi.mocked(ask).mock.calls[0]![0].buttons.map((b) => b.id)).not.toContain("attach");
useProject.setState({ project: null });
expect(await chooseProjectWindow("B")).toBe("same");
});