@@ -289,4 +289,70 @@ describe("loadPluginLookUpTable", () => {
|
289 | 289 | }), |
290 | 290 | ); |
291 | 291 | }); |
| 292 | + |
| 293 | +it("rebuilds when a provided metadata snapshot has stale plugin inventory", async () => { |
| 294 | +const snapshotPlugins = [ |
| 295 | +createManifestRecord({ |
| 296 | +id: "telegram", |
| 297 | +origin: "bundled", |
| 298 | +channels: ["telegram"], |
| 299 | +}), |
| 300 | +]; |
| 301 | +const requestedPlugins = [ |
| 302 | +createManifestRecord({ |
| 303 | +id: "telegram", |
| 304 | +origin: "bundled", |
| 305 | +channels: ["telegram"], |
| 306 | +}), |
| 307 | +createManifestRecord({ |
| 308 | +id: "discord", |
| 309 | +origin: "bundled", |
| 310 | +channels: ["discord"], |
| 311 | +}), |
| 312 | +]; |
| 313 | +const config = { |
| 314 | +channels: { |
| 315 | +telegram: { token: "configured" }, |
| 316 | +}, |
| 317 | +} as OpenClawConfig; |
| 318 | +const policyHash = resolveInstalledPluginIndexPolicyHash(config); |
| 319 | +const snapshotIndex = createIndex(snapshotPlugins, { policyHash }); |
| 320 | +const requestedIndex = createIndex(requestedPlugins, { policyHash }); |
| 321 | +const snapshotRegistry: PluginManifestRegistry = { |
| 322 | +plugins: snapshotPlugins, |
| 323 | +diagnostics: [], |
| 324 | +}; |
| 325 | +const requestedRegistry: PluginManifestRegistry = { |
| 326 | +plugins: requestedPlugins, |
| 327 | +diagnostics: [], |
| 328 | +}; |
| 329 | +loadPluginManifestRegistryForInstalledIndex |
| 330 | +.mockReturnValueOnce(snapshotRegistry) |
| 331 | +.mockReturnValueOnce(requestedRegistry); |
| 332 | +const { loadPluginMetadataSnapshot } = await import("./plugin-metadata-snapshot.js"); |
| 333 | +const { loadPluginLookUpTable } = await import("./plugin-lookup-table.js"); |
| 334 | + |
| 335 | +const metadataSnapshot = loadPluginMetadataSnapshot({ |
| 336 | + config, |
| 337 | +env: {}, |
| 338 | +index: snapshotIndex, |
| 339 | +}); |
| 340 | +loadPluginManifestRegistryForInstalledIndex.mockClear(); |
| 341 | + |
| 342 | +const table = loadPluginLookUpTable({ |
| 343 | + config, |
| 344 | +env: {}, |
| 345 | +index: requestedIndex, |
| 346 | + metadataSnapshot, |
| 347 | +}); |
| 348 | + |
| 349 | +expect(loadPluginManifestRegistryForInstalledIndex).toHaveBeenCalledOnce(); |
| 350 | +expect(loadPluginManifestRegistryForInstalledIndex).toHaveBeenCalledWith( |
| 351 | +expect.objectContaining({ |
| 352 | +index: requestedIndex, |
| 353 | + config, |
| 354 | +}), |
| 355 | +); |
| 356 | +expect(table.manifestRegistry).toBe(requestedRegistry); |
| 357 | +}); |
292 | 358 | }); |