chore: lock the plugin boundary and remove 2.9.0 leftovers

This commit is contained in:
LukeGus committed 2026-09-25 07:24:46 -05:00
1 parent 6489b62ece
commit 2961297989
399 files changed
+3964 -5627

No files matched your search

@@ -6,7 +6,7 @@ import {
LOCAL_FILES_DRAG_MIME,
REMOTE_FILES_DRAG_MIME,
} from "../../src/frontend/local-transfer-utils";
import type { LocalFileEntry } from "@/types/electron";
import type { LocalFileEntry } from "@termix/plugin-sdk/ui";
// jsdom has no layout, so render every row instead of a virtual window.
vi.mock("@tanstack/react-virtual", () => ({
@@ -19,13 +19,16 @@ const api = vi.hoisted(() => ({
beginTransferProgressMonitoring: vi.fn(),
}));
vi.mock("@/main-axios", () => ({
vi.mock("../../src/frontend/api/transfer-api", () => ({
addTransferRecent: api.addTransferRecent,
getSSHHosts: api.getSSHHosts,
getTransferProgressPercent: api.getTransferProgressPercent,
transferToHost: api.transferToHost,
}));
vi.mock("../../src/frontend/api/hosts", () => ({
getSSHHosts: api.getSSHHosts,
}));
vi.mock("../../src/frontend/api/ssh-file-operations-api", () => ({
browseSSHDirectory: api.browseSSHDirectory,
changeSSHPermissions: api.changeSSHPermissions,
@@ -57,11 +57,12 @@ describe(`${manifest.id} activate`, () => {
expect(rendered.registered.hostEditorSections()).toEqual([]);
});
it("registers files.openHost and files.openEditor actions", async () => {
it("registers its open actions, including the shell's host.openFiles", async () => {
rendered = await renderWithApp(plugin, { manifest, locales });
expect(rendered.registered.actions().sort()).toEqual([
"files.openEditor",
"files.openHost",
"host.openFiles",
]);
});
@@ -4,9 +4,8 @@ const fileManagerApiMock = vi.hoisted(() => ({
post: vi.fn(async () => ({ data: { complete: false } })),
}));
vi.mock("@/main-axios", () => ({
authApi: { defaults: {} },
fileManagerApi: { defaults: {} },
vi.mock("../../../src/frontend/api/client", () => ({
fileManagerApi: () => ({ defaults: {} }),
getFileManagerApiForSession: () => fileManagerApiMock,
handleApiError: (error: unknown) => {
throw error;
@@ -14,19 +13,20 @@ vi.mock("@/main-axios", () => ({
setSessionOrigin: vi.fn(),
clearSessionOrigin: vi.fn(),
}));
vi.mock("@/lib/connection-origin", () => ({
vi.mock("@termix/plugin-sdk/ui", async (importOriginal) => ({
...(await importOriginal<object>()),
resolveConnectionOrigin: vi.fn(),
}));
vi.mock("@/lib/frontend-logger", () => ({
fileLogger: {
createFrontendLogger: () => ({
info: vi.fn(),
success: vi.fn(),
},
warn: vi.fn(),
error: vi.fn(),
}),
}));
vi.mock("@/lib/file-list-request-cache", () => ({
vi.mock("../../../src/frontend/lib/file-list-request-cache", () => ({
getCachedFileList: vi.fn(),
}));
vi.mock("@/lib/file-content-request-cache", () => ({
vi.mock("../../../src/frontend/lib/file-content-request-cache", () => ({
getCachedFileContent: vi.fn(),
invalidateCachedFileContent: vi.fn(),
}));
@@ -0,0 +1,84 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { createKeyedRequestCache } from "../../../src/frontend/lib/keyed-request-cache";
afterEach(() => vi.useRealTimers());
describe("createKeyedRequestCache", () => {
it("coalesces requests per key without mixing keys", async () => {
let resolve!: (value: string) => void;
const loader = vi.fn(() => new Promise<string>((done) => (resolve = done)));
const cache = createKeyedRequestCache<string>(5_000);
const first = cache.get("host:1", loader);
const duplicate = cache.get("host:1", loader);
const other = cache.get("host:2", async () => "other");
resolve("shared");
await expect(Promise.all([first, duplicate, other])).resolves.toEqual([
"shared",
"shared",
"other",
]);
expect(loader).toHaveBeenCalledOnce();
});
it("can show stale data immediately while forcing one refresh", async () => {
vi.useFakeTimers();
const cache = createKeyedRequestCache<string>(1_000);
await cache.get("directory", async () => "old");
await vi.advanceTimersByTimeAsync(2_000);
expect(cache.peek("directory", 30_000)).toBe("old");
const loader = vi.fn(async () => "fresh");
const [a, b] = await Promise.all([
cache.get("directory", loader, { force: true }),
cache.get("directory", loader, { force: true }),
]);
expect([a, b]).toEqual(["fresh", "fresh"]);
expect(loader).toHaveBeenCalledOnce();
});
it("evicts the least recently used entry when bounded", async () => {
const cache = createKeyedRequestCache<number>(10_000, 2);
await cache.get("a", async () => 1);
await cache.get("b", async () => 2);
expect(cache.peek("a")).toBe(1);
await cache.get("c", async () => 3);
expect(cache.peek("a")).toBe(1);
expect(cache.peek("b")).toBeNull();
expect(cache.peek("c")).toBe(3);
});
it("keeps stale data when a refresh fails", async () => {
const cache = createKeyedRequestCache<string>(1_000);
await cache.get("key", async () => "safe");
await expect(
cache.get(
"key",
async () => {
throw new Error("offline");
},
{ force: true },
),
).rejects.toThrow("offline");
expect(cache.peek("key")).toBe("safe");
});
it("does not let an invalidated request overwrite newer data", async () => {
let resolveOld!: (value: string) => void;
const cache = createKeyedRequestCache<string>(10_000);
const oldRequest = cache.get(
"key",
() => new Promise<string>((resolve) => (resolveOld = resolve)),
);
cache.set("key", "optimistic");
resolveOld("old");
await oldRequest;
expect(cache.peek("key")).toBe("optimistic");
});
});
@@ -26,7 +26,7 @@ import {
serializeLocalFilesDragPayload,
sortLocalEntries,
} from "../../src/frontend/local-transfer-utils";
import type { LocalFileEntry } from "@/types/electron";
import type { LocalFileEntry } from "@termix/plugin-sdk/ui";
describe("drag payloads", () => {
it("round-trips local file payloads", () => {
@@ -1,5 +1,5 @@
import { describe, expect, it } from "vitest";
import type { FileItem } from "@/types/index";
import type { FileItem } from "../../src/frontend/host-types";
import {
addOptimisticItem,
childPath,
@@ -7,7 +7,7 @@ vi.mock("sonner", () => ({
},
}));
vi.mock("@/main-axios.ts", () => ({}));
vi.mock("../../src/frontend/api/transfer-api", () => ({}));
vi.mock("../../src/frontend/transferNotificationStore.ts", () => ({
markTransferNotified: vi.fn(),
}));