|
1 | 1 | import { describe, expect, it } from "vitest"; |
2 | 2 | import { CodexAppInventoryCache } from "./app-inventory-cache.js"; |
3 | 3 | import { CODEX_PLUGINS_MARKETPLACE_NAME } from "./config.js"; |
4 | | -import { readCodexPluginInventory } from "./plugin-inventory.js"; |
| 4 | +import { findOpenAiCuratedPluginSummary, readCodexPluginInventory } from "./plugin-inventory.js"; |
5 | 5 | import type { v2 } from "./protocol.js"; |
6 | 6 |
|
7 | 7 | describe("Codex plugin inventory", () => { |
@@ -66,6 +66,70 @@ describe("Codex plugin inventory", () => { |
66 | 66 | expect(calls).toEqual(["plugin/list", "plugin/read"]); |
67 | 67 | }); |
68 | 68 |
|
| 69 | + it("matches namespaced curated plugin ids by normalized path segment", async () => { |
| 70 | + const appCache = new CodexAppInventoryCache(); |
| 71 | + await appCache.refreshNow({ |
| 72 | + key: "runtime", |
| 73 | + nowMs: 0, |
| 74 | + request: async () => ({ |
| 75 | + data: [appInfo("github-app", true)], |
| 76 | + nextCursor: null, |
| 77 | + }), |
| 78 | + }); |
| 79 | + |
| 80 | + const listed = pluginList([ |
| 81 | + pluginSummary("openai-curated/github", { |
| 82 | + name: "GitHub", |
| 83 | + installed: true, |
| 84 | + enabled: true, |
| 85 | + }), |
| 86 | + ]); |
| 87 | + expect(findOpenAiCuratedPluginSummary(listed, "github")?.summary.id).toBe( |
| 88 | + "openai-curated/github", |
| 89 | + ); |
| 90 | + |
| 91 | + const inventory = await readCodexPluginInventory({ |
| 92 | + pluginConfig: { |
| 93 | + codexPlugins: { |
| 94 | + enabled: true, |
| 95 | + plugins: { |
| 96 | + github: { |
| 97 | + marketplaceName: CODEX_PLUGINS_MARKETPLACE_NAME, |
| 98 | + pluginName: "github", |
| 99 | + }, |
| 100 | + }, |
| 101 | + }, |
| 102 | + }, |
| 103 | + appCache, |
| 104 | + appCacheKey: "runtime", |
| 105 | + nowMs: 1, |
| 106 | + request: async (method, params) => { |
| 107 | + if (method === "plugin/list") { |
| 108 | + return listed; |
| 109 | + } |
| 110 | + if (method === "plugin/read") { |
| 111 | + expect(params).toMatchObject({ |
| 112 | + marketplacePath: "/marketplaces/openai-curated", |
| 113 | + pluginName: "github", |
| 114 | + }); |
| 115 | + return pluginDetail("github", [appSummary("github-app")]); |
| 116 | + } |
| 117 | + throw new Error(`unexpected request ${method}`); |
| 118 | + }, |
| 119 | + }); |
| 120 | + |
| 121 | + expect(inventory.records).toHaveLength(1); |
| 122 | + expect(inventory.records[0]).toMatchObject({ |
| 123 | + policy: { pluginName: "github" }, |
| 124 | + summary: { id: "openai-curated/github", installed: true, enabled: true }, |
| 125 | + appOwnership: "proven", |
| 126 | + ownedAppIds: ["github-app"], |
| 127 | + }); |
| 128 | + expect(inventory.diagnostics).not.toContainEqual( |
| 129 | + expect.objectContaining({ code: "plugin_missing" }), |
| 130 | + ); |
| 131 | + }); |
| 132 | + |
69 | 133 | it("fails closed when plugin detail apps are absent from app inventory", async () => { |
70 | 134 | const appCache = new CodexAppInventoryCache(); |
71 | 135 | await appCache.refreshNow({ |
|
0 commit comments