返回 DeepSeek-Reasonix
remoteSubmissionLifecycle.ts
根目录 / desktop / frontend / src / __tests__ / helpers / remoteSubmissionLifecycle.ts
1 import { act } from "react";
2 import type { RemoteSessionApi } from "../../lib/useRemoteSession";
3 type Check = (value: boolean, label: string) => void;
4
5 export async function verifyRemoteSubmissionLifecycle(getProbe: () => RemoteSessionApi | undefined, setError: (error: Error | undefined) => void, tape: string[], flush: () => Promise<unknown>, ok: Check) {
6 ok(Object.values(getProbe()?.transcript.localSubmissions ?? {}).find(submission => submission.text === "run tests")?.status === "accepted",
7 "remote RPC success accepts the echo without removing it");
8 const realNow = Date.now;
9 try {
10 Date.now = () => 123456789;
11 await act(async () => { await Promise.all([getProbe()?.submit("same millisecond A"), getProbe()?.submit("same millisecond B")]); await flush(); });
12 } finally { Date.now = realNow; }
13 const sameTick = Object.values(getProbe()?.transcript.localSubmissions ?? {}).filter(submission => submission.text.startsWith("same millisecond"));
14 ok(sameTick.length === 2 && new Set(sameTick.map(submission => submission.submissionId)).size === 2,
15 "remote submissions within the same millisecond retain distinct identities");
16 const duplicateBefore = tape.filter(entry => entry === "submit:tab-remote-2:duplicate remote").length;
17 await act(async () => { await Promise.all([getProbe()?.submit("duplicate remote"), getProbe()?.submit("duplicate remote")]); await flush(); });
18 ok(tape.filter(entry => entry === "submit:tab-remote-2:duplicate remote").length === duplicateBefore + 1,
19 "a repeated in-flight remote submission dispatches once");
20 setError(new Error("explicit rejection"));
21 await act(async () => { await getProbe()?.submit("rejected remote").catch(() => {}); await flush(); });
22 ok(Object.values(getProbe()?.transcript.localSubmissions ?? {}).find(submission => submission.text === "rejected remote")?.status === "failed",
23 "remote explicit rejection preserves a failed echo");
24 setError(new Error("network timeout"));
25 await act(async () => { await getProbe()?.submit("unknown remote").catch(() => {}); await flush(); });
26 ok(Object.values(getProbe()?.transcript.localSubmissions ?? {}).find(submission => submission.text === "unknown remote")?.status === "unknown",
27 "remote transport timeout preserves an unknown echo");
28 ok(tape.filter(entry => entry === "submit:tab-remote-2:unknown remote").length === 1,
29 "unknown remote result is not automatically resubmitted");
30 await act(async () => { await getProbe()?.submit("new remote while unknown").catch(() => {}); await flush(); });
31 ok(!tape.includes("submit:tab-remote-2:new remote while unknown"),
32 "a different remote message cannot bypass an unknown submission receipt");
33 setError(undefined);
34 }
35
36 export async function verifyRemoteSubmissionTabIsolation(getProbe: () => RemoteSessionApi | undefined, render: (tabId: string) => void, flush: () => Promise<unknown>, ok: Check) {
37 const retainedSubmissionIds = Object.keys(getProbe()?.transcript.localSubmissions ?? {});
38 await act(async () => {
39 render("tab-other-submissions");
40 await flush();
41 });
42 ok(getProbe()?.transcript.localSubmissionOrder.length === 0, "remote tab hydration cannot copy another tab's pending echoes");
43 await act(async () => {
44 render("tab-remote-2");
45 await flush();
46 });
47 ok(retainedSubmissionIds.length > 0 && retainedSubmissionIds.every(id => Boolean(getProbe()?.transcript.localSubmissions[id])),
48 "switching back retains unresolved echoes in their original remote session");
49 }
50
50 lines TYPESCRIPT