mirror of
https://github.com/Termix-SSH/Termix.git
synced 2026-10-30 15:15:24 +00:00
chore: lock the plugin boundary and remove 2.9.0 leftovers
This commit is contained in:
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(),
|
||||
}));
|
||||
|
||||
Reference in new issue
Block a user