дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
A mapping's local path may now be an absolute path inside the project (the form IntelliJ writes), and a deployment path of . means the server root; absolute paths outside the project are kept as they are. The project-tree Deployment submenu names the default server (Upload to <server>, Download from <server>, Sync with Deployed to <server>…) and gains Sync with Deployed to Default Server. Remote Host downloads use the backend-resolved mapping, which fixes downloads under symlinked or case-different paths. Fixes #877 Co-authored-by: florentvdry <[email protected]>
77 рядки
3.6 KiB
TypeScript
77 рядки
3.6 KiB
TypeScript
import { beforeEach, expect, it, vi } from "vitest";
|
|
import { DEFAULT_DEPLOYMENT_SERVER } from "@/platform/remoteSettings";
|
|
import { downloadToProject, ensureRoot } from "./remoteHost";
|
|
import { useDeployment } from "./store";
|
|
|
|
const ipc = vi.hoisted(() => ({ root: vi.fn(), list: vi.fn(), download: vi.fn(), notify: vi.fn() }));
|
|
vi.mock("./actions", () => ({ downloadPaths: ipc.download }));
|
|
vi.mock("./ssh", () => ({ withSsh: (_: string, run: () => unknown) => run() }));
|
|
vi.mock("@/ui", () => ({ copyText: vi.fn() }));
|
|
vi.mock("@/workbench/inputDialogs", () => ({ promptInput: vi.fn() }));
|
|
vi.mock("@/workbench/messages", () => ({ confirm: vi.fn() }));
|
|
vi.mock("@/platform/project", () => ({ useProject: { getState: () => ({ project: { root: "/project" } }) } }));
|
|
vi.mock("@/workbench/contributions", () => ({ notifications: () => ({ notify: ipc.notify }) }));
|
|
vi.mock("@/platform/ipc", async (original) => ({
|
|
...(await original<typeof import("@/platform/ipc")>()),
|
|
commands: { deployServerRoot: ipc.root, remoteList: ipc.list },
|
|
}));
|
|
|
|
beforeEach(() => {
|
|
useDeployment.setState({ trees: {} });
|
|
vi.clearAllMocks();
|
|
ipc.root.mockResolvedValue({ status: "ok", data: { root: "/srv", mappings: [] } });
|
|
ipc.list.mockResolvedValue({ status: "ok", data: [] });
|
|
});
|
|
|
|
it("reloads a server's tree when changing its filesystem type or root", async () => {
|
|
const server = { ...DEFAULT_DEPLOYMENT_SERVER, id: "existing", sshConfig: "ssh", rootPath: "/srv" };
|
|
await ensureRoot(server);
|
|
expect(ipc.list).toHaveBeenLastCalledWith({ kind: "sftp", ssh: "ssh" }, "/srv");
|
|
await ensureRoot(server);
|
|
expect(ipc.root).toHaveBeenCalledTimes(1);
|
|
const local = { ...server, kind: "local" as const };
|
|
await ensureRoot(local);
|
|
expect(ipc.list).toHaveBeenLastCalledWith({ kind: "local" }, "/srv");
|
|
ipc.root.mockResolvedValue({ status: "ok", data: { root: "/mounted", mappings: [] } });
|
|
await ensureRoot({ ...local, rootPath: "/mounted" });
|
|
expect(ipc.list).toHaveBeenLastCalledWith({ kind: "local" }, "/mounted");
|
|
expect(useDeployment.getState().trees.existing?.root).toBe("/mounted");
|
|
});
|
|
|
|
it("refreshes resolved mappings when the local mapping changes", async () => {
|
|
const server = { ...DEFAULT_DEPLOYMENT_SERVER, id: "local", kind: "local" as const };
|
|
await ensureRoot(server);
|
|
const mappings = [{ local: "/project/src", deployment: "/srv" }];
|
|
ipc.root.mockResolvedValue({ status: "ok", data: { root: "/srv", mappings } });
|
|
await ensureRoot({ ...server, mappings: [{ local: "/alias", deployment: "/", web: "" }] });
|
|
expect(ipc.root).toHaveBeenCalledTimes(2);
|
|
expect(useDeployment.getState().trees.local?.mappings).toEqual(mappings);
|
|
});
|
|
|
|
it("downloads using backend-resolved folders instead of the configured alias", async () => {
|
|
const server = {
|
|
...DEFAULT_DEPLOYMENT_SERVER,
|
|
id: "local",
|
|
kind: "local" as const,
|
|
mappings: [{ local: "/alias", deployment: ".", web: "" }],
|
|
};
|
|
const mappings = [{ local: "/project/src", deployment: "/srv" }];
|
|
ipc.root.mockResolvedValue({ status: "ok", data: { root: "/srv", mappings } });
|
|
const entry = {
|
|
path: "/srv/a.txt",
|
|
name: "a.txt",
|
|
isDir: false,
|
|
isSymlink: false,
|
|
size: 5,
|
|
mtime: null,
|
|
permissions: "rw-r--r--",
|
|
};
|
|
await downloadToProject(server, [entry]);
|
|
expect(ipc.download).toHaveBeenCalledWith(server, ["/project/src/a.txt"]);
|
|
ipc.download.mockClear();
|
|
ipc.root.mockResolvedValue({ status: "ok", data: { root: "/srv", mappings: [] } });
|
|
await downloadToProject(server, [entry]);
|
|
expect(ipc.download).not.toHaveBeenCalled();
|
|
expect(ipc.notify).toHaveBeenCalledWith(expect.objectContaining({ title: "Not mapped to a project path" }));
|
|
});
|