Files
openclaw/extensions/memory-wiki/src/source-sync.test.ts
2026-04-07 05:59:30 +01:00

140 lines
4.1 KiB
TypeScript

import { beforeEach, describe, expect, it, vi } from "vitest";
import { syncMemoryWikiImportedSources } from "./source-sync.js";
const { syncBridgeMock, syncUnsafeLocalMock, refreshIndexesMock } = vi.hoisted(() => ({
syncBridgeMock: vi.fn(),
syncUnsafeLocalMock: vi.fn(),
refreshIndexesMock: vi.fn(),
}));
vi.mock("./bridge.js", () => ({
syncMemoryWikiBridgeSources: syncBridgeMock,
}));
vi.mock("./unsafe-local.js", () => ({
syncMemoryWikiUnsafeLocalSources: syncUnsafeLocalMock,
}));
vi.mock("./compile.js", () => ({
refreshMemoryWikiIndexesAfterImport: refreshIndexesMock,
}));
const bridgeResult = {
importedCount: 1,
updatedCount: 2,
skippedCount: 3,
removedCount: 4,
artifactCount: 10,
workspaces: 2,
pagePaths: ["sources/alpha.md"],
};
describe("syncMemoryWikiImportedSources", () => {
beforeEach(() => {
syncBridgeMock.mockReset();
syncUnsafeLocalMock.mockReset();
refreshIndexesMock.mockReset();
syncBridgeMock.mockResolvedValue(bridgeResult);
syncUnsafeLocalMock.mockResolvedValue({
...bridgeResult,
workspaces: 0,
});
refreshIndexesMock.mockResolvedValue({
refreshed: true,
reason: "import-changed",
compile: { updatedFiles: ["index.md", "sources/index.md"] },
});
});
it("routes bridge mode through bridge sync and merges refresh results", async () => {
const config = { vaultMode: "bridge" } as Parameters<
typeof syncMemoryWikiImportedSources
>[0]["config"];
const appConfig = { agents: { list: [{ id: "main", default: true }] } } as Parameters<
typeof syncMemoryWikiImportedSources
>[0]["appConfig"];
const result = await syncMemoryWikiImportedSources({ config, appConfig });
expect(syncBridgeMock).toHaveBeenCalledWith({ config, appConfig });
expect(syncUnsafeLocalMock).not.toHaveBeenCalled();
expect(refreshIndexesMock).toHaveBeenCalledWith({
config,
syncResult: bridgeResult,
});
expect(result).toEqual({
...bridgeResult,
indexesRefreshed: true,
indexRefreshReason: "import-changed",
indexUpdatedFiles: ["index.md", "sources/index.md"],
});
});
it("routes unsafe-local mode through unsafe-local sync", async () => {
const unsafeLocalResult = {
...bridgeResult,
importedCount: 2,
workspaces: 0,
pagePaths: ["sources/private.md"],
};
syncUnsafeLocalMock.mockResolvedValueOnce(unsafeLocalResult);
refreshIndexesMock.mockResolvedValueOnce({
refreshed: false,
reason: "auto-compile-disabled",
});
const config = { vaultMode: "unsafe-local" } as Parameters<
typeof syncMemoryWikiImportedSources
>[0]["config"];
const result = await syncMemoryWikiImportedSources({ config });
expect(syncUnsafeLocalMock).toHaveBeenCalledWith(config);
expect(syncBridgeMock).not.toHaveBeenCalled();
expect(refreshIndexesMock).toHaveBeenCalledWith({
config,
syncResult: unsafeLocalResult,
});
expect(result).toEqual({
...unsafeLocalResult,
indexesRefreshed: false,
indexRefreshReason: "auto-compile-disabled",
indexUpdatedFiles: [],
});
});
it("returns a no-op sync result outside imported-source modes", async () => {
const config = { vaultMode: "isolated" } as Parameters<
typeof syncMemoryWikiImportedSources
>[0]["config"];
const result = await syncMemoryWikiImportedSources({ config });
expect(syncBridgeMock).not.toHaveBeenCalled();
expect(syncUnsafeLocalMock).not.toHaveBeenCalled();
expect(refreshIndexesMock).toHaveBeenCalledWith({
config,
syncResult: {
importedCount: 0,
updatedCount: 0,
skippedCount: 0,
removedCount: 0,
artifactCount: 0,
workspaces: 0,
pagePaths: [],
},
});
expect(result).toEqual({
importedCount: 0,
updatedCount: 0,
skippedCount: 0,
removedCount: 0,
artifactCount: 0,
workspaces: 0,
pagePaths: [],
indexesRefreshed: true,
indexRefreshReason: "import-changed",
indexUpdatedFiles: ["index.md", "sources/index.md"],
});
});
});