Files
multica/packages/views/issues/components/comment-trigger-chips.test.tsx
Naiyuan Qing 7c71007e6e refactor(comments): trim trigger preview copy and unify composer buttons (#4174)
Two related cleanups to the issue comment/reply/edit composer:

- Drop the trigger-preview "context" copy added in #4147 (chip prefix
  `trigger_context_*` and per-context popover titles `trigger_preview_title_*`).
  The actual "align context" fix in #4147 was the backend/hook work; the copy
  was redundant decoration. Removes the `context` prop, the dead i18n keys
  across en/zh/ja/ko, and the corresponding test assertions; the popover title
  falls back to the original single `trigger_preview_title`.

- Edit-comment footer: lay the trigger chip on a single row with the action
  cluster (📎 Cancel Save) on the right, attachments on their own full-width
  row above. The 📎 now sits with the action buttons, matching the new-comment
  and reply composers.

- Unify composer buttons on shadcn `Button`: `FileUploadButton` renders a
  ghost icon button instead of a hand-rolled circle, and the reply submit
  button uses `Button` (icon-xs, ghost-when-empty / primary-when-typed) instead
  of a hand-rolled element. Sizes: 📎 and reply submit are both icon-xs (24px).

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 09:44:05 +08:00

124 lines
3.6 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import { fireEvent, screen } from "@testing-library/react";
import type { CommentTriggerPreviewAgent } from "@multica/core/types";
import { renderWithI18n } from "../../test/i18n";
import { CommentTriggerChips } from "./comment-trigger-chips";
vi.mock("@multica/core/agents", () => ({
useAgentPresenceDetail: () => ({ availability: "online", workload: "idle" }),
}));
vi.mock("@multica/core/paths", () => ({
useCurrentWorkspace: () => ({ id: "ws-1" }),
}));
vi.mock("../../common/actor-avatar", () => ({
AgentStatusDot: () => <span data-testid="status-dot" />,
}));
const walt: CommentTriggerPreviewAgent = {
id: "agent-1",
name: "Walt",
source: "issue_assignee",
reason: "",
};
const bob: CommentTriggerPreviewAgent = {
id: "agent-2",
name: "Bob",
source: "mention_agent",
reason: "",
};
describe("CommentTriggerChips", () => {
it("renders nothing without agents", () => {
const { container } = renderWithI18n(
<CommentTriggerChips agents={[]} suppressedAgentIds={new Set()} onToggle={vi.fn()} />,
);
expect(container).toBeEmptyDOMElement();
});
it("renders a single agent as a full sentence and toggles on click", () => {
const onToggle = vi.fn();
renderWithI18n(
<CommentTriggerChips agents={[walt]} suppressedAgentIds={new Set()} onToggle={onToggle} />,
);
const chip = screen.getByRole("button");
expect(chip).toHaveTextContent("Starts working when sent");
expect(chip).toHaveAttribute("aria-pressed", "false");
fireEvent.click(chip);
expect(onToggle).toHaveBeenCalledWith("agent-1");
});
it("dims a suppressed single agent into the skip state", () => {
renderWithI18n(
<CommentTriggerChips
agents={[walt]}
suppressedAgentIds={new Set(["agent-1"])}
onToggle={vi.fn()}
/>,
);
const chip = screen.getByRole("button");
expect(chip).toHaveTextContent("Won't be triggered");
expect(chip).toHaveAttribute("aria-pressed", "true");
});
it("collapses several agents into a stack with an active count", () => {
renderWithI18n(
<CommentTriggerChips
agents={[walt, bob]}
suppressedAgentIds={new Set()}
onToggle={vi.fn()}
/>,
);
expect(screen.getByRole("button")).toHaveTextContent("2 agents start working when sent");
});
it("counts only non-suppressed agents in the sentence", () => {
renderWithI18n(
<CommentTriggerChips
agents={[walt, bob]}
suppressedAgentIds={new Set(["agent-2"])}
onToggle={vi.fn()}
/>,
);
expect(screen.getByRole("button")).toHaveTextContent("1 agent starts working when sent");
});
it("switches to the none-will-trigger state when every agent is suppressed", () => {
renderWithI18n(
<CommentTriggerChips
agents={[walt, bob]}
suppressedAgentIds={new Set(["agent-1", "agent-2"])}
onToggle={vi.fn()}
/>,
);
expect(screen.getByRole("button")).toHaveTextContent("No agents will be triggered");
});
it("opens the popover on click and toggles a row", () => {
const onToggle = vi.fn();
renderWithI18n(
<CommentTriggerChips
agents={[walt, bob]}
suppressedAgentIds={new Set()}
onToggle={onToggle}
/>,
);
fireEvent.click(screen.getByRole("button"));
expect(screen.getByText("This comment will trigger")).toBeInTheDocument();
const row = screen.getByRole("button", { name: /Bob/ });
expect(row).toHaveTextContent("Bob");
fireEvent.click(row);
expect(onToggle).toHaveBeenCalledWith("agent-2");
});
});