86 lines
3.2 KiB
TypeScript
86 lines
3.2 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import path from "node:path";
|
|
import { readFile } from "node:fs/promises";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
const testsDir = path.dirname(fileURLToPath(import.meta.url));
|
|
const projectChatPagePath = path.join(testsDir, "../src/app/conversations/[projectId]/page.tsx");
|
|
|
|
test("project chat page listens to conversation updates for realtime refresh", async () => {
|
|
const source = await readFile(projectChatPagePath, "utf8");
|
|
const realtimeRefreshConfig = source.match(/<RealtimeRefresh[\s\S]*?events=\{\[([\s\S]*?)\]\}/);
|
|
|
|
assert.ok(realtimeRefreshConfig, "expected project chat page to declare RealtimeRefresh events");
|
|
assert.match(
|
|
realtimeRefreshConfig[1],
|
|
/"conversation\.updated"/,
|
|
"expected project chat page to refresh when conversation.updated is emitted",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/const warningMap = new Map<string, typeof detail\.executionWarnings\[number\]>\(\);/,
|
|
"expected project chat page to build a per-message warning map from executionWarnings",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/detail\.conversationTasks\.find\(\(task\) => task\.requestMessageId === message\.id\)/,
|
|
"expected project chat page to bind lightweight conversation tasks to each message",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/messageTask \? \(/,
|
|
"expected project chat page to render a compact per-message task status strip",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/new Map<string, typeof detail\.executionWarnings\[number\]>\(\)/,
|
|
"expected project chat page to dedupe repeated warnings per message before rendering",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/dedupedWarnings\.map\(\(warning\) => \(/,
|
|
"expected project chat page to render deduped warnings instead of the raw warning list",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/detail\.conversationTasks\.length \?/,
|
|
"expected project chat page to keep a task status summary when lightweight conversation tasks exist",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/resolveDispatchPlanComposerState\(detail\.dispatchPlans\)/,
|
|
"expected project chat page to derive dispatch plan composer state directly from project detail payload",
|
|
);
|
|
assert.doesNotMatch(
|
|
source,
|
|
/listDispatchPlansByProject/,
|
|
"expected project chat page to avoid a separate dispatch plan read outside project detail payload",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/detail\.participantsPayload && detail\.participantsPayload\.repairRequired/,
|
|
"expected project chat page to surface a repair card when group participants are invalid",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/修复群成员/,
|
|
"expected project chat page to show a visible repair members affordance",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/detail\.participantsPayload\.repairReason/,
|
|
"expected project chat page to render the server-provided repair reason copy",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/detail\.participantsPayload\.participants\.filter\(\(participant\) => participant\.status !== "active"\)/,
|
|
"expected project chat page to surface the concrete invalid group members instead of only a generic repair flag",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/participant\.statusLabel \?\? participant\.status/,
|
|
"expected project chat page to show each invalid participant status label",
|
|
);
|
|
});
|