|
1 | 1 | import { describe, expect, it } from "vitest"; |
| 2 | +import officialExternalPluginCatalog from "../../scripts/lib/official-external-plugin-catalog.json" with { type: "json" }; |
2 | 3 | import { |
3 | 4 | type OfficialExternalPluginCatalogEntry, |
4 | 5 | getOfficialExternalPluginCatalogEntry, |
| 6 | +isOfficialExternalPluginCatalogFeed, |
5 | 7 | listOfficialExternalPluginCatalogEntries, |
| 8 | +parseOfficialExternalPluginCatalogEntries, |
6 | 9 | resolveOfficialExternalProviderContractPluginIds, |
7 | 10 | resolveOfficialExternalProviderPluginIds, |
8 | 11 | resolveOfficialExternalProviderPluginIdsForEnv, |
@@ -20,6 +23,54 @@ function expectCatalogEntry(id: string): OfficialExternalPluginCatalogEntry {
|
20 | 23 | } |
21 | 24 | |
22 | 25 | describe("official external plugin catalog", () => { |
| 26 | +it("ships the official plugin catalog as a feed-shaped bundled fallback", () => { |
| 27 | +expect(isOfficialExternalPluginCatalogFeed(officialExternalPluginCatalog)).toBe(true); |
| 28 | +expect(officialExternalPluginCatalog).toMatchObject({ |
| 29 | +schemaVersion: 1, |
| 30 | +id: "openclaw-official-external-plugins", |
| 31 | +sequence: 1, |
| 32 | +}); |
| 33 | +expect(officialExternalPluginCatalog.entries.length).toBeGreaterThan(0); |
| 34 | +}); |
| 35 | + |
| 36 | +it("does not allow malformed feed wrappers to count as feed documents", () => { |
| 37 | +expect( |
| 38 | +isOfficialExternalPluginCatalogFeed({ |
| 39 | +schemaVersion: 1, |
| 40 | +id: " ", |
| 41 | +generatedAt: "2026-06-22T00:00:00.000Z", |
| 42 | +sequence: 1, |
| 43 | +entries: [], |
| 44 | +}), |
| 45 | +).toBe(false); |
| 46 | +expect( |
| 47 | +isOfficialExternalPluginCatalogFeed({ |
| 48 | +schemaVersion: 2, |
| 49 | +id: "openclaw-official-external-plugins", |
| 50 | +generatedAt: "2026-06-22T00:00:00.000Z", |
| 51 | +sequence: 1, |
| 52 | +entries: [], |
| 53 | +}), |
| 54 | +).toBe(false); |
| 55 | +}); |
| 56 | + |
| 57 | +it("keeps unsupported versioned feed wrappers out of legacy catalog parsing", () => { |
| 58 | +expect( |
| 59 | +parseOfficialExternalPluginCatalogEntries({ |
| 60 | +schemaVersion: 2, |
| 61 | +id: "future-feed", |
| 62 | +generatedAt: "2026-06-22T00:00:00.000Z", |
| 63 | +sequence: 1, |
| 64 | +entries: [{ name: "should-not-load" }], |
| 65 | +}), |
| 66 | +).toEqual([]); |
| 67 | +expect( |
| 68 | +parseOfficialExternalPluginCatalogEntries({ |
| 69 | +entries: [{ name: "legacy-catalog-entry" }], |
| 70 | +}), |
| 71 | +).toEqual([{ name: "legacy-catalog-entry" }]); |
| 72 | +}); |
| 73 | + |
23 | 74 | it("lists the externalized provider and capability plugins with install metadata", () => { |
24 | 75 | const providers = [ |
25 | 76 | ["arcee", "@openclaw/arcee-provider"], |
|