Files
fusion/packages/dashboard/app/components/__tests__/SelectionCommentPopover.test.tsx
gsxdsm 4bfb6b46ad FN-6528: add selection comments for new tasks
Adds a text-selection comment flow that opens New Task with source context.

- Add a reusable selection comment hook and popover for editor/document text selections.
- Thread selected-file and line-range context into the New Task modal.
- Enable comment-on-selection entry points in file editor, browser, documents, and memory surfaces.
- Cover the selection flow with focused component and hook tests, plus docs and copy updates.

Files changed:
 docs/dashboard-guide.md                            |   6 +-
 packages/dashboard/app/App.tsx                     |   7 +-
 packages/dashboard/app/components/AppModals.tsx    |   2 +
 .../dashboard/app/components/DocumentsView.tsx     |  25 ++-
 .../dashboard/app/components/FileBrowserModal.tsx  |   3 +
 packages/dashboard/app/components/FileEditor.tsx   |  35 +++-
 packages/dashboard/app/components/MemoryView.tsx   |   5 +-
 packages/dashboard/app/components/NewTaskModal.tsx |  15 +-
 .../app/components/SelectionCommentPopover.css     |  73 +++++++++
 .../app/components/SelectionCommentPopover.tsx     | 181 +++++++++++++++++++++
 .../components/__tests__/DocumentsView.test.tsx    |  59 +++++++
 .../components/__tests__/FileBrowserModal.test.tsx |  79 +++++++++
 .../app/components/__tests__/FileEditor.test.tsx   |  60 +++++++
 .../app/components/__tests__/MemoryView.test.tsx   |  48 +++++-
 .../app/components/__tests__/NewTaskModal.test.tsx |  17 ++
 .../__tests__/SelectionCommentPopover.test.tsx     |  75 +++++++++
 .../app/hooks/__tests__/useModalManager.test.ts    |  29 ++++
 .../hooks/__tests__/useSelectionComment.test.ts    | 140 ++++++++++++++++
 packages/dashboard/app/hooks/useModalManager.ts    |  19 ++-
 .../dashboard/app/hooks/useSelectionComment.ts     |  95 +++++++++++
 packages/i18n/locales/en/app.json                  |  11 ++
 21 files changed, 973 insertions(+), 11 deletions(-)

Fusion-Task-Id: FN-6528

Fusion-Task-Lineage: ef79e450-e69f-497b-97cd-f82d3c832fdf
2026-06-17 03:29:39 -07:00

76 lines
2.5 KiB
TypeScript

import { fireEvent, render, screen } from "@testing-library/react";
import { describe, expect, it, vi } from "vitest";
import { SelectionCommentPopover, composeSelectionCommentDescription } from "../SelectionCommentPopover";
vi.mock("lucide-react", () => ({
MessageSquarePlus: () => null,
}));
describe("SelectionCommentPopover", () => {
it("renders a trigger for a selection and submits a composed task description", () => {
const onSubmit = vi.fn();
render(
<SelectionCommentPopover
selectedText="const answer = 42;"
anchorRect={new DOMRect(20, 30, 100, 16)}
filePath="src/example.ts"
lineRange={{ start: 4, end: 4 }}
onSubmit={onSubmit}
/>,
);
fireEvent.click(screen.getByRole("button", { name: /add a comment/i }));
fireEvent.change(screen.getByLabelText(/comment for the new task/i), {
target: { value: "Turn this into a configurable value." },
});
fireEvent.click(screen.getByRole("button", { name: /send to new task/i }));
expect(onSubmit).toHaveBeenCalledWith([
"File: src/example.ts",
"Lines: 4",
"",
"Selected snippet:",
"```text",
"const answer = 42;",
"```",
"",
"Comment:",
"Turn this into a configurable value.",
].join("\n"));
});
it("cancels cleanly without submitting", () => {
const onSubmit = vi.fn();
const onCancel = vi.fn();
const onOpenChange = vi.fn();
render(
<SelectionCommentPopover
selectedText="snippet"
anchorRect={new DOMRect(20, 30, 100, 16)}
filePath="README.md"
onSubmit={onSubmit}
onCancel={onCancel}
onOpenChange={onOpenChange}
/>,
);
fireEvent.click(screen.getByRole("button", { name: /add a comment/i }));
fireEvent.change(screen.getByLabelText(/comment for the new task/i), { target: { value: "A note" } });
fireEvent.click(screen.getByRole("button", { name: /cancel/i }));
expect(onSubmit).not.toHaveBeenCalled();
expect(onCancel).toHaveBeenCalledTimes(1);
expect(onOpenChange).toHaveBeenCalledWith(true);
expect(onOpenChange).toHaveBeenLastCalledWith(false);
expect(screen.getByRole("button", { name: /add a comment/i })).toBeInTheDocument();
});
it("uses a longer markdown fence when the snippet contains backticks", () => {
expect(composeSelectionCommentDescription({
filePath: "README.md",
selectedText: "```js\ncode\n```",
comment: "Move this example.",
})).toContain("````text\n```js\ncode\n```\n````");
});
});