File size: 2,723 Bytes
f778c12 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 | import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterEach, describe, expect, it } from "vitest";
import type { OpenClawConfig } from "../../config/types.openclaw.js";
import type { MigrationPlan, MigrationProviderPlugin } from "../../plugins/types.js";
import { planProviderMemoryImport } from "./memory-import.js";
const tempRoots: string[] = [];
async function makeSourceDir(): Promise<string> {
const dir = await fs.realpath(await fs.mkdtemp(path.join(os.tmpdir(), "memory-import-test-")));
tempRoots.push(dir);
return dir;
}
afterEach(async () => {
await Promise.all(tempRoots.splice(0).map((dir) => fs.rm(dir, { force: true, recursive: true })));
});
async function memoryPlan(sourceDir: string, ids: string[]): Promise<MigrationPlan> {
const items = await Promise.all(
ids.map(async (id, index) => {
// Duplicate ids still resolve to distinct real files so the dedupe check,
// not a missing-file error, is what rejects them.
const source = path.join(sourceDir, `${id}-${index}.md`);
await fs.writeFile(source, `# ${id}\n`);
return {
id,
kind: "memory" as const,
action: "copy" as const,
status: "planned" as const,
source,
target: `/target/${id}-${index}.md`,
};
}),
);
return {
providerId: "test",
source: sourceDir,
summary: {
total: items.length,
planned: items.length,
migrated: 0,
skipped: 0,
conflicts: 0,
errors: 0,
sensitive: 0,
},
items,
};
}
function stubProvider(plan: MigrationPlan): MigrationProviderPlugin {
return {
id: "test",
label: "Test",
supportedItemKinds: ["memory"],
detect: () => ({ found: true, source: plan.source }),
plan: () => plan,
apply: () => ({ ...plan, summary: plan.summary }),
};
}
const config = {} as OpenClawConfig;
describe("planProviderMemoryImport memory-only shaping", () => {
it("rejects a plan with duplicate memory item ids", async () => {
const dir = await makeSourceDir();
await expect(
planProviderMemoryImport({
provider: stubProvider(await memoryPlan(dir, ["same-id", "same-id"])),
config,
agentId: "main",
}),
).rejects.toThrow('duplicate memory migration item id "same-id"');
});
it("accepts a plan with unique memory item ids", async () => {
const dir = await makeSourceDir();
const { plan } = await planProviderMemoryImport({
provider: stubProvider(await memoryPlan(dir, ["memory-a", "memory-b"])),
config,
agentId: "main",
});
expect(plan.items.map((item) => item.id)).toEqual(["memory-a", "memory-b"]);
});
});
|