story-kit: merge 196_story_render_code_fences_in_user_chat_messages
This commit is contained in:
@@ -1097,9 +1097,13 @@ describe("Remove bubble styling from streaming messages (Story 163)", () => {
|
|||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
// findByText returns the styled div itself for user messages (text is direct child)
|
// findByText finds the text element; traverse up to the styled bubble div
|
||||||
const userStyledDiv = await screen.findByText("I am a user message");
|
const userText = await screen.findByText("I am a user message");
|
||||||
const styleAttr = userStyledDiv.getAttribute("style") ?? "";
|
// User messages are rendered via markdown, so text is inside a <p> inside .user-markdown-body
|
||||||
|
// Walk up to find the styled bubble container
|
||||||
|
const bubbleDiv = userText.closest("[style*='padding: 10px 16px']");
|
||||||
|
expect(bubbleDiv).toBeTruthy();
|
||||||
|
const styleAttr = bubbleDiv?.getAttribute("style") ?? "";
|
||||||
// User messages retain bubble: distinct background, padding, rounded corners
|
// User messages retain bubble: distinct background, padding, rounded corners
|
||||||
expect(styleAttr).toContain("padding: 10px 16px");
|
expect(styleAttr).toContain("padding: 10px 16px");
|
||||||
expect(styleAttr).toContain("border-radius: 20px");
|
expect(styleAttr).toContain("border-radius: 20px");
|
||||||
|
|||||||
@@ -71,3 +71,45 @@ describe("MessageItem component (Story 178 AC3)", () => {
|
|||||||
expect(typeofStr).toContain("memo");
|
expect(typeofStr).toContain("memo");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("MessageItem user message code fence rendering (Story 196)", () => {
|
||||||
|
it("renders code fences in user messages as code blocks", () => {
|
||||||
|
const { container } = render(
|
||||||
|
<MessageItem
|
||||||
|
msg={{
|
||||||
|
role: "user",
|
||||||
|
content: "Here is some code:\n```js\nconsole.log('hi');\n```",
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Syntax highlighter renders a pre > div > code structure
|
||||||
|
const codeEl = container.querySelector("pre code");
|
||||||
|
expect(codeEl).toBeInTheDocument();
|
||||||
|
expect(codeEl?.textContent).toContain("console.log");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders inline code with single backticks in user messages", () => {
|
||||||
|
render(
|
||||||
|
<MessageItem
|
||||||
|
msg={{ role: "user", content: "Use `npm install` to install." }}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
const codeEl = screen.getByText("npm install");
|
||||||
|
expect(codeEl.tagName.toLowerCase()).toBe("code");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("renders user messages with code blocks inside user-markdown-body class", () => {
|
||||||
|
const { container } = render(
|
||||||
|
<MessageItem
|
||||||
|
msg={{
|
||||||
|
role: "user",
|
||||||
|
content: "```js\nconsole.log('hi');\n```",
|
||||||
|
}}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(container.querySelector(".user-markdown-body")).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ function MessageItemInner({ msg }: MessageItemProps) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{msg.role === "user" ? (
|
{msg.role === "user" ? (
|
||||||
msg.content
|
<div className="user-markdown-body">
|
||||||
|
<Markdown components={{ code: CodeBlock }}>{msg.content}</Markdown>
|
||||||
|
</div>
|
||||||
) : msg.role === "tool" ? (
|
) : msg.role === "tool" ? (
|
||||||
<details style={{ cursor: "pointer" }}>
|
<details style={{ cursor: "pointer" }}>
|
||||||
<summary
|
<summary
|
||||||
|
|||||||
Reference in New Issue
Block a user