test: tighten installed plugin index assertions

This commit is contained in:
Peter Steinberger
2026-05-11 00:09:33 +01:00
parent 8b45a7e145
commit e530a174d2

View File

@@ -45,6 +45,15 @@ function createPluginCandidate(stateDir: string, pluginId: string): PluginCandid
};
}
function expectRecordFields(record: unknown, expected: Record<string, unknown>) {
expect(record).toBeDefined();
const actual = record as Record<string, unknown>;
for (const [key, value] of Object.entries(expected)) {
expect(actual[key]).toEqual(value);
}
return actual;
}
afterEach(() => {
for (const dir of tempDirs.splice(0)) {
fs.rmSync(dir, { recursive: true, force: true });
@@ -73,23 +82,22 @@ describe("plugin index install records store", () => {
const indexPath = resolveInstalledPluginIndexRecordsStorePath({ stateDir });
expect(indexPath).toBe(path.join(stateDir, "plugins", "installs.json"));
expect(JSON.parse(fs.readFileSync(indexPath, "utf8"))).toMatchObject({
version: 1,
generatedAtMs: 1777118400000,
installRecords: {
twitch: {
source: "npm",
spec: "@openclaw/plugin-twitch@1.0.0",
installPath: "plugins/npm/@openclaw/plugin-twitch",
},
},
plugins: [
{
pluginId: "twitch",
installRecordHash: expect.stringMatching(/^[a-f0-9]{64}$/u),
},
],
const persisted = JSON.parse(fs.readFileSync(indexPath, "utf8")) as {
version?: number;
generatedAtMs?: number;
installRecords?: Record<string, unknown>;
plugins?: Array<{ pluginId?: string; installRecordHash?: string }>;
};
expect(persisted.version).toBe(1);
expect(persisted.generatedAtMs).toBe(1777118400000);
expectRecordFields(persisted.installRecords?.twitch, {
source: "npm",
spec: "@openclaw/plugin-twitch@1.0.0",
installPath: "plugins/npm/@openclaw/plugin-twitch",
});
expect(persisted.plugins).toHaveLength(1);
expect(persisted.plugins?.[0]?.pluginId).toBe("twitch");
expect(persisted.plugins?.[0]?.installRecordHash).toMatch(/^[a-f0-9]{64}$/u);
await expect(readPersistedInstalledPluginIndexInstallRecords({ stateDir })).resolves.toEqual({
twitch: {
source: "npm",
@@ -117,20 +125,15 @@ describe("plugin index install records store", () => {
},
);
expect(
JSON.parse(
fs.readFileSync(resolveInstalledPluginIndexRecordsStorePath({ stateDir }), "utf8"),
),
).toMatchObject({
installRecords: {
missing: {
source: "npm",
spec: "missing-plugin@1.0.0",
installPath: path.join(stateDir, "plugins", "missing"),
},
},
plugins: [],
const persisted = JSON.parse(
fs.readFileSync(resolveInstalledPluginIndexRecordsStorePath({ stateDir }), "utf8"),
) as { installRecords?: Record<string, unknown>; plugins?: unknown[] };
expectRecordFields(persisted.installRecords?.missing, {
source: "npm",
spec: "missing-plugin@1.0.0",
installPath: path.join(stateDir, "plugins", "missing"),
});
expect(persisted.plugins).toEqual([]);
await expect(loadInstalledPluginIndexInstallRecords({ stateDir })).resolves.toEqual({
missing: {
source: "npm",
@@ -210,36 +213,28 @@ describe("plugin index install records store", () => {
fs.mkdirSync(path.dirname(indexPath), { recursive: true });
fs.writeFileSync(indexPath, JSON.stringify({ installRecords: {}, plugins: [] }), "utf8");
await expect(loadInstalledPluginIndexInstallRecords({ stateDir })).resolves.toMatchObject({
codex: {
source: "npm",
spec: "@openclaw/codex@2026.5.2",
installPath: codexDir,
version: "2026.5.2",
resolvedName: "@openclaw/codex",
resolvedVersion: "2026.5.2",
resolvedSpec: "@openclaw/codex@2026.5.2",
},
discord: {
source: "npm",
spec: "@openclaw/discord@2026.5.2",
installPath: discordDir,
version: "2026.5.2",
resolvedName: "@openclaw/discord",
resolvedVersion: "2026.5.2",
resolvedSpec: "@openclaw/discord@2026.5.2",
},
const loaded = await loadInstalledPluginIndexInstallRecords({ stateDir });
expectRecordFields(loaded.codex, {
source: "npm",
spec: "@openclaw/codex@2026.5.2",
installPath: codexDir,
version: "2026.5.2",
resolvedName: "@openclaw/codex",
resolvedVersion: "2026.5.2",
resolvedSpec: "@openclaw/codex@2026.5.2",
});
expect(loadInstalledPluginIndexInstallRecordsSync({ stateDir })).toMatchObject({
codex: {
source: "npm",
installPath: codexDir,
},
discord: {
source: "npm",
installPath: discordDir,
},
expectRecordFields(loaded.discord, {
source: "npm",
spec: "@openclaw/discord@2026.5.2",
installPath: discordDir,
version: "2026.5.2",
resolvedName: "@openclaw/discord",
resolvedVersion: "2026.5.2",
resolvedSpec: "@openclaw/discord@2026.5.2",
});
const loadedSync = loadInstalledPluginIndexInstallRecordsSync({ stateDir });
expectRecordFields(loadedSync.codex, { source: "npm", installPath: codexDir });
expectRecordFields(loadedSync.discord, { source: "npm", installPath: discordDir });
});
it("keeps persisted install record metadata over recovered npm records", async () => {
@@ -263,13 +258,12 @@ describe("plugin index install records store", () => {
{ stateDir, candidates: [candidate] },
);
await expect(loadInstalledPluginIndexInstallRecords({ stateDir })).resolves.toMatchObject({
discord: {
source: "npm",
spec: "@openclaw/discord@beta",
installPath: path.join(stateDir, "custom", "discord"),
integrity: "sha512-persisted",
},
const loaded = await loadInstalledPluginIndexInstallRecords({ stateDir });
expectRecordFields(loaded.discord, {
source: "npm",
spec: "@openclaw/discord@beta",
installPath: path.join(stateDir, "custom", "discord"),
integrity: "sha512-persisted",
});
});
@@ -290,14 +284,13 @@ describe("plugin index install records store", () => {
{ stateDir, candidates: [candidate] },
);
await expect(loadInstalledPluginIndexInstallRecords({ stateDir })).resolves.toMatchObject({
"git-demo": {
source: "git",
spec: "git:file:///tmp/git-demo@abc123",
gitUrl: "file:///tmp/git-demo",
gitRef: "abc123",
gitCommit: "abc123",
},
const loaded = await loadInstalledPluginIndexInstallRecords({ stateDir });
expectRecordFields(loaded["git-demo"], {
source: "git",
spec: "git:file:///tmp/git-demo@abc123",
gitUrl: "file:///tmp/git-demo",
gitRef: "abc123",
gitCommit: "abc123",
});
});
@@ -329,20 +322,19 @@ describe("plugin index install records store", () => {
{ stateDir, candidates: [candidate] },
);
await expect(loadInstalledPluginIndexInstallRecords({ stateDir })).resolves.toMatchObject({
"clawpack-demo": {
source: "clawhub",
spec: "clawhub:clawpack-demo",
artifactKind: "npm-pack",
artifactFormat: "tgz",
npmIntegrity: "sha512-clawpack",
npmShasum: "1".repeat(40),
npmTarballName: "clawpack-demo-2026.5.1-beta.2.tgz",
clawpackSha256: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
clawpackSpecVersion: 1,
clawpackManifestSha256: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
clawpackSize: 4096,
},
const loaded = await loadInstalledPluginIndexInstallRecords({ stateDir });
expectRecordFields(loaded["clawpack-demo"], {
source: "clawhub",
spec: "clawhub:clawpack-demo",
artifactKind: "npm-pack",
artifactFormat: "tgz",
npmIntegrity: "sha512-clawpack",
npmShasum: "1".repeat(40),
npmTarballName: "clawpack-demo-2026.5.1-beta.2.tgz",
clawpackSha256: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
clawpackSpecVersion: 1,
clawpackManifestSha256: "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
clawpackSize: 4096,
});
});
@@ -376,7 +368,7 @@ describe("plugin index install records store", () => {
spec: "keep@1.0.0",
},
});
expect(withInstall.demo).toMatchObject({
expectRecordFields(withInstall.demo, {
source: "npm",
spec: "demo@latest",
installedAt: "2026-04-25T00:00:00.000Z",