test(web): cover the App-level listed-resource metadata wiring
The bridge-factory tests inject `getListedResourceMeta` directly, so nothing caught App.tsx ceasing to supply it — the fallback would go unused with every test still green. Add a pass-through spy over the factory in App.test.tsx and assert both factories receive a lookup that resolves a listed resource's `_meta` and misses on an unknown URI. Signed-off-by: cliffhall <cliff@futurescale.com>
This commit is contained in:
parent
0c989a0c34
commit
a1c00e51a8
1 changed files with 70 additions and 0 deletions
|
|
@ -355,6 +355,29 @@ vi.mock("@inspector/core/react/useSettingsDraft.js", () => ({
|
|||
})),
|
||||
}));
|
||||
|
||||
// --- App bridge factory spy (#2055) -----------------------------------------
|
||||
// Passes through to the real factory but records the deps App hands it, so a
|
||||
// test can drive `getListedResourceMeta` — the wiring that carries a
|
||||
// `resources/list` entry's `_meta.ui` into the sandbox CSP. Without this the
|
||||
// bridge-factory unit tests would still pass while App stopped supplying it.
|
||||
const appBridgeFactoryDeps: AppBridgeFactoryDeps[] = [];
|
||||
vi.mock(
|
||||
"./components/elements/AppRenderer/createAppBridgeFactory",
|
||||
async (importOriginal) => {
|
||||
const actual =
|
||||
await importOriginal<
|
||||
typeof import("./components/elements/AppRenderer/createAppBridgeFactory")
|
||||
>();
|
||||
return {
|
||||
...actual,
|
||||
createAppBridgeFactory: (deps: AppBridgeFactoryDeps) => {
|
||||
appBridgeFactoryDeps.push(deps);
|
||||
return actual.createAppBridgeFactory(deps);
|
||||
},
|
||||
};
|
||||
},
|
||||
);
|
||||
|
||||
// --- InspectorView double ---------------------------------------------------
|
||||
// Surfaces each piece of session-scoped state under test and exposes buttons
|
||||
// that invoke the App's connect / call-tool / get-prompt / read-resource /
|
||||
|
|
@ -590,6 +613,8 @@ import type {
|
|||
MessageEntry,
|
||||
ServerEntry,
|
||||
} from "@inspector/core/mcp/types.js";
|
||||
import type { AppBridgeFactoryDeps } from "./components/elements/AppRenderer/createAppBridgeFactory";
|
||||
import { useManagedResources } from "@inspector/core/react/useManagedResources.js";
|
||||
|
||||
// Default useInspectorClient return — capabilities empty (no task tool calls).
|
||||
// Individual tests override via vi.mocked(...).mockReturnValue(...).
|
||||
|
|
@ -3117,3 +3142,48 @@ describe("App background command rejections (#2049)", () => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("App MCP App listed-resource metadata wiring (#2055)", () => {
|
||||
beforeEach(() => {
|
||||
appBridgeFactoryDeps.length = 0;
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// The hook mock is module-level and shared, so put the empty-list default
|
||||
// back rather than leaving a populated list for whatever runs next.
|
||||
vi.mocked(useManagedResources).mockReturnValue({
|
||||
resources: [],
|
||||
refresh: vi.fn(),
|
||||
clearListChanged: vi.fn(),
|
||||
} as unknown as ReturnType<typeof useManagedResources>);
|
||||
});
|
||||
|
||||
it("hands the bridge factory a getListedResourceMeta reading the resources/list entries", async () => {
|
||||
// ext-apps treats a listing entry's `_meta.ui` as the static default for a
|
||||
// UI resource, so the App has to surface the listing to the bridge — the
|
||||
// factory's own tests inject the dep and cannot see this wiring break.
|
||||
const listedMeta = {
|
||||
ui: { csp: { connectDomains: ["https://api.example.com"] } },
|
||||
};
|
||||
vi.mocked(useManagedResources).mockReturnValue({
|
||||
resources: [
|
||||
{ uri: "ui://weather/app.html", name: "app", _meta: listedMeta },
|
||||
],
|
||||
refresh: vi.fn(),
|
||||
clearListChanged: vi.fn(),
|
||||
} as unknown as ReturnType<typeof useManagedResources>);
|
||||
|
||||
renderWithMantine(<App />);
|
||||
await waitFor(() => expect(appBridgeFactoryDeps.length).toBeGreaterThan(0));
|
||||
|
||||
// Every factory App builds gets the wiring, not just the Apps-tab one.
|
||||
for (const deps of appBridgeFactoryDeps) {
|
||||
expect(deps.getListedResourceMeta?.("ui://weather/app.html")).toEqual(
|
||||
listedMeta,
|
||||
);
|
||||
expect(
|
||||
deps.getListedResourceMeta?.("ui://other/app.html"),
|
||||
).toBeUndefined();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue