95 lines
3.6 KiB
TypeScript
95 lines
3.6 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 repairClientPath = path.join(testsDir, "../src/components/group-participants-repair-client.tsx");
|
|
const participantsPagePath = path.join(testsDir, "../src/app/conversations/[projectId]/participants/page.tsx");
|
|
|
|
test("web group participants repair client handles empty candidates and disables invalid submissions", async () => {
|
|
const source = await readFile(repairClientPath, "utf8");
|
|
|
|
assert.match(
|
|
source,
|
|
/const canSubmit = !loading && availableThreads\.length >= 2 && selectedProjectIds\.size >= 2;/,
|
|
"expected repair client to derive a submit-ready state from loading, candidates, and selections",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/if \(availableThreads\.length < 2\) \{\s*setMessage\("当前没有足够的真实线程可用于修复群成员。"\);/s,
|
|
"expected repair client to show a specific empty-candidates message before attempting submit",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/disabled=\{!canSubmit\}/,
|
|
"expected repair submit button to stay disabled until the request is actually valid",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/availableThreads\.length \? \(/,
|
|
"expected repair client to branch between candidate list and empty-state copy",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/try \{/,
|
|
"expected repair client to guard network submission with try/finally handling",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/catch \(error\) \{/,
|
|
"expected repair client to surface a user-facing message when submit fetch rejects",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/finally \{\s*setLoading\(false\);/s,
|
|
"expected repair client to always clear loading even after a network failure",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/router\.replace\(`\/conversations\/\$\{projectId\}\/participants\?repaired=1`\);/,
|
|
"expected repair client to persist repair success via URL state before refreshing away",
|
|
);
|
|
});
|
|
|
|
test("web group participants page hides repair form when fewer than two real thread candidates remain", async () => {
|
|
const source = await readFile(participantsPagePath, "utf8");
|
|
|
|
assert.match(
|
|
source,
|
|
/const canRepairGroupMembers = availableThreads\.length >= 2;/,
|
|
"expected participants page to compute whether repair is currently possible",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/participantsPayload\?\.repairRequired && canRepairGroupMembers \? \(/,
|
|
"expected participants page to only mount the repair client when at least two real thread candidates exist",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/participantsPayload\?\.repairRequired && !canRepairGroupMembers \? \(/,
|
|
"expected participants page to render a fallback guidance card when repair is required but impossible",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/当前设备里暂时没有足够的真实线程可用于修复群成员。/,
|
|
"expected participants page to explain why direct repair is currently unavailable",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/searchParams: Promise<\{ repaired\?: string \| string\[\] \| undefined \}>;/,
|
|
"expected participants page to read repaired search params under the current Next page contract",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/const repaired = \(await searchParams\)\.repaired;/,
|
|
"expected participants page to resolve repaired status from search params",
|
|
);
|
|
assert.match(
|
|
source,
|
|
/repaired === \"1\" \? \(/,
|
|
"expected participants page to show a durable success acknowledgement after repair refresh",
|
|
);
|
|
});
|