test comment deletion cleanup regressions

This commit is contained in:
Dotta
2026-06-03 17:39:42 +00:00
parent 1afc8b1a60
commit d87b14ff4f
2 changed files with 40 additions and 5 deletions
+14 -5
View File
@@ -1,6 +1,7 @@
// @vitest-environment jsdom
import { act, createRef, forwardRef, useImperativeHandle, useState } from "react";
import { flushSync } from "react-dom";
import type { ReactNode } from "react";
import { createRoot } from "react-dom/client";
import { MemoryRouter } from "react-router-dom";
@@ -33,6 +34,14 @@ import type {
IssueChatTranscriptEntry,
} from "../lib/issue-chat-messages";
function flushAct<T>(callback: () => T): T {
let result: T | undefined;
flushSync(() => {
result = callback();
});
return result as T;
}
function hasSmoothScrollBehavior(arg: unknown) {
return typeof arg === "object"
&& arg !== null
@@ -1327,7 +1336,7 @@ describe("IssueChatThread", () => {
it("renders deleted comments as tombstones without the original body", () => {
const root = createRoot(container);
act(() => {
flushAct(() => {
root.render(
<MemoryRouter>
<IssueChatThread
@@ -1360,12 +1369,12 @@ describe("IssueChatThread", () => {
);
});
expect(container.textContent).toContain("Comment deleted");
expect(container.textContent).toContain("You deleted this comment");
expect(container.textContent).not.toContain("Sensitive deleted body");
expect(container.querySelector("button[aria-label='Delete comment']")).toBeNull();
expect(container.querySelector("button[aria-label='Copy message']")).toBeNull();
act(() => {
flushAct(() => {
root.unmount();
});
});
@@ -1374,7 +1383,7 @@ describe("IssueChatThread", () => {
const root = createRoot(container);
const replaceStateSpy = vi.spyOn(window.history, "replaceState").mockImplementation(() => {});
act(() => {
flushAct(() => {
root.render(
<MemoryRouter initialEntries={["/issues/PAP-1#comment-comment-deleted"]}>
<IssueChatThread
@@ -1409,7 +1418,7 @@ describe("IssueChatThread", () => {
expect(replaceStateSpy).toHaveBeenCalledWith(null, "", "/issues/PAP-1");
replaceStateSpy.mockRestore();
act(() => {
flushAct(() => {
root.unmount();
});
});
+26
View File
@@ -324,6 +324,32 @@ describe("buildIssueChatMessages", () => {
});
});
it("redacts deleted comment bodies while preserving tombstone metadata", () => {
const messages = buildIssueChatMessages({
comments: [
createComment({
body: "Sensitive deleted body",
deletedAt: new Date("2026-04-06T12:05:00.000Z"),
deletedByType: "user",
deletedByUserId: "user-1",
}),
],
timelineEvents: [],
linkedRuns: [],
liveRuns: [],
currentUserId: "user-1",
userLabelMap: new Map([["user-1", "Dotta"]]),
});
expect(messages[0]?.content).toEqual([{ type: "text", text: "" }]);
expect(messages[0]?.metadata.custom).toMatchObject({
deletedAt: "2026-04-06T12:05:00.000Z",
deletedByType: "user",
deletedByUserId: "user-1",
});
expect(JSON.stringify(messages[0])).not.toContain("Sensitive deleted body");
});
it("prefers derived agent attribution when a board-authored comment is proven to come from a run", () => {
const agentMap = new Map<string, Agent>([["agent-1", createAgent("agent-1", "Claude")]]);
const messages = buildIssueChatMessages({