diff --git a/clients/web/src/components/elements/ContentViewer/ContentViewer.test.tsx b/clients/web/src/components/elements/ContentViewer/ContentViewer.test.tsx index bfd65add..66d5ace3 100644 --- a/clients/web/src/components/elements/ContentViewer/ContentViewer.test.tsx +++ b/clients/web/src/components/elements/ContentViewer/ContentViewer.test.tsx @@ -263,6 +263,39 @@ describe("ContentViewer", () => { expect(screen.getByRole("button", { name: "Copy" })).toBeInTheDocument(); }); + // The `resource` block branch used to render every embedded resource in a + // plain code block, so a prompt message carrying JSON did not inherit this + // migration even though the text-block branch did. + it("renders an embedded JSON resource in the JSON editor", () => { + const block: ContentBlock = { + type: "resource", + resource: { + uri: "file:///a.json", + mimeType: "application/json", + text: '{"a":1}', + }, + }; + renderWithMantine(); + expect(getAceText()).toBe('{\n "a": 1\n}'); + }); + + // Narrowed to JSON on purpose: routing every declared type through would put + // an embedded `text/html` resource into the sandboxed frame, which is a + // change to what a tool result is. + it("leaves a non-JSON embedded resource on the plain renderer", () => { + const block: ContentBlock = { + type: "resource", + resource: { + uri: "file:///a.html", + mimeType: "text/html", + text: "

hi

", + }, + }; + renderWithMantine(); + expect(screen.getByText("

hi

")).toBeInTheDocument(); + expect(document.querySelector("iframe")).toBeNull(); + }); + it("renders nothing when neither block nor contents is provided", () => { const { container } = renderWithMantine(); // MantineProvider injects a