feat(FN-4736): complete Step 1 — linkify mailbox message content

Fusion-Task-Id: FN-4736
Fusion-Task-Lineage: f723ded5-cc07-47f1-ae49-fc7378c8e9f1
This commit is contained in:
Fusion (runfusion.ai)
2026-05-16 09:30:32 -07:00
committed by gsxdsm
parent 1c4088fe14
commit 556db0ba9e
2 changed files with 45 additions and 1 deletions

View File

@@ -2,8 +2,11 @@ import { memo } from "react";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import type { Components } from "react-markdown";
import { linkifyReactChildren } from "../utils/filePathLinkify";
const mailboxMarkdownComponents: Components = {
p: ({ children, ...props }) => <p {...props}>{linkifyReactChildren(children)}</p>,
li: ({ children, ...props }) => <li {...props}>{linkifyReactChildren(children)}</li>,
pre: ({ children, ...props }) => (
<pre {...props} className="mailbox-markdown-pre">
{children}

View File

@@ -1,5 +1,7 @@
import { describe, it, expect, afterEach } from "vitest";
import { describe, it, expect, afterEach, vi } from "vitest";
import { render, cleanup, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import { FileBrowserProvider } from "../../context/FileBrowserContext";
import { MailboxMessageContent } from "../MailboxMessageContent";
afterEach(() => {
@@ -85,4 +87,43 @@ describe("MailboxMessageContent", () => {
render(<MailboxMessageContent content="x" testId="mailbox-message-body" />);
expect(screen.getByTestId("mailbox-message-body")).toBeInTheDocument();
});
describe("file-path linkification", () => {
it("renders prose file paths as clickable file-path-link buttons", () => {
render(
<FileBrowserProvider openFile={vi.fn()}>
<MailboxMessageContent content="See packages/dashboard/app/App.tsx for context." />
</FileBrowserProvider>,
);
expect(
screen.getByRole("button", { name: "packages/dashboard/app/App.tsx" }),
).toHaveClass("file-path-link");
});
it("opens the linked file with parsed line and column", async () => {
const openFile = vi.fn();
render(
<FileBrowserProvider openFile={openFile}>
<MailboxMessageContent content="Review packages/dashboard/app/App.tsx:12:3 before shipping." />
</FileBrowserProvider>,
);
await userEvent.click(
screen.getByRole("button", { name: "packages/dashboard/app/App.tsx:12:3" }),
);
expect(openFile).toHaveBeenCalledWith("packages/dashboard/app/App.tsx", { line: 12, col: 3 });
});
it("does not linkify paths inside fenced code blocks", () => {
render(
<FileBrowserProvider openFile={vi.fn()}>
<MailboxMessageContent content={"```\npackages/dashboard/app/App.tsx:44\n```"} />
</FileBrowserProvider>,
);
expect(screen.queryByRole("button", { name: "packages/dashboard/app/App.tsx:44" })).toBeNull();
});
});
});