1import { renderToStaticMarkup } from "react-dom/server";
2import { describe, expect, it, vi } from "vite-plus/test";
3
4import { DiffCommentAnnotation } from "./DiffCommentAnnotation";
5
6const callbacks = {
7 onTextChange: vi.fn(),
8 onCancel: vi.fn(),
9 onComment: vi.fn(),
10 onDelete: vi.fn(),
11};
12
13describe("DiffCommentAnnotation", () => {
14 it("renders the shared draft composer directly in the selected diff", () => {
15 const markup = renderToStaticMarkup(
16 <DiffCommentAnnotation kind="draft" rangeLabel="+78" text="" {...callbacks} />,
17 );
18
19 expect(markup).toContain("font-sans");
20 expect(markup).not.toContain("chat-composer-glass");
21 expect(markup).not.toContain("font-mono");
22 expect(markup).not.toContain("Local comment");
23 expect(markup).not.toContain("on +78");
24 expect(markup).toContain("⌘/Ctrl Enter to send");
25 expect(markup).toContain("Add a comment…");
26 expect(markup).toContain(">Comment</button>");
27 expect(markup).toContain("autofocus");
28 // The comment box is the standard small Textarea, not a bespoke surface.
29 expect(markup).toMatch(/<span[^>]*data-size="sm"[^>]*data-slot="textarea-control"/);
30 });
31
32 it("lets a pull-request diff configure actions without replacing the composer", () => {
33 const markup = renderToStaticMarkup(
34 <DiffCommentAnnotation
35 kind="draft"
36 rangeLabel="src/app.ts:4"
37 text=""
38 {...callbacks}
39 submitLabel="Add to review"
40 secondaryAction={{
41 label: "Add to agent",
42 onAction: vi.fn(),
43 }}
44 />,
45 );
46
47 expect(markup).toContain("Add a comment…");
48 expect(markup).toContain(">Add to review</button>");
49 expect(markup.match(/<button[^>]*disabled[^>]*>Add to review<\/button>/)).not.toBeNull();
50 expect(markup.match(/<button[^>]*disabled[^>]*>Add to agent<\/button>/)).not.toBeNull();
51 });
52
53 it("renders a saved comment without a nested card or redundant range label", () => {
54 const markup = renderToStaticMarkup(
55 <DiffCommentAnnotation
56 kind="comment"
57 rangeLabel="+78"
58 text="Please keep this branch explicit."
59 {...callbacks}
60 />,
61 );
62
63 expect(markup).toContain("font-sans");
64 expect(markup).not.toContain("chat-composer-glass");
65 expect(markup).not.toContain("on +78");
66 expect(markup).toContain("Please keep this branch explicit.");
67 expect(markup).toContain('aria-label="Delete comment"');
68 expect(markup).toContain("border-s-2");
69 expect(markup).toContain("bg-primary/[0.045]");
70 expect(markup).toContain("lucide-message-circle");
71 });
72
73 it("renders draft text owned by the annotation wrapper", () => {
74 const markup = renderToStaticMarkup(
75 <DiffCommentAnnotation
76 kind="draft"
77 rangeLabel="+78"
78 text="Keep this unsaved draft"
79 {...callbacks}
80 />,
81 );
82
83 expect(markup).toContain("Keep this unsaved draft");
84 });
85});