返回 DeepSeek-Reasonix
authentication-recovery.tsx
根目录 / desktop / frontend / bench / authentication-recovery.tsx
1 // Isolated browser fixture: real Composer, disposable host and no model calls.
2 import { useState } from "react";
3 import { createRoot } from "react-dom/client";
4 import { Composer } from "../src/components/Composer";
5 import { LocaleProvider } from "../src/lib/i18n";
6 import { ToastProvider } from "../src/lib/toast";
7 import { installDesktopHostStub } from "../src/__tests__/desktopHostStub";
8 import type { TabMeta } from "../src/lib/types";
9 import { modelSettingsAllowSubmission } from "../src/lib/authenticationTypes";
10 import "../src/styles.css";
11
12 let completeRetry: (() => void) | undefined;
13 installDesktopHostStub({
14 Commands: async () => [], Models: async () => [], ModelsForTab: async () => [],
15 RetryAuthenticationForTab: async () => {
16 await new Promise<void>((resolve) => { completeRetry = resolve; });
17 return { status: "ready" };
18 },
19 });
20
21 function Fixture() {
22 const [tabId, setTabId] = useState("first");
23 const [ready, setReady] = useState(true);
24 const [authentication, setAuthentication] = useState<NonNullable<TabMeta["authentication"]>>({ status: "authentication_rejected", providerName: "fixture" });
25 const [sent, setSent] = useState(0);
26 const [modelSettingsPending, setModelSettingsPending] = useState(false);
27 return <main style={{ padding: 24 }}>
28 <h1>Authentication recovery regression</h1>
29 <nav aria-label="Fixture controls">
30 <button onClick={() => setTabId(tabId === "first" ? "second" : "first")}>Switch tab</button>
31 <button onClick={() => { setReady(false); completeRetry?.(); }}>Finish retry while controller unavailable</button>
32 <button onClick={() => { setReady(true); setAuthentication({ status: "missing_credential", providerName: "replacement" }); }}>Replace connection</button>
33 <button onClick={() => { setReady(true); setAuthentication({ status: "ready" }); }}>Publish backend ready</button>
34 <button onClick={() => { setReady(true); setAuthentication({ status: "missing_credential", providerName: "fixture" }); setModelSettingsPending(false); }}>Missing credential</button>
35 <button onClick={() => setModelSettingsPending(true)}>Publish saved settings</button>
36 </nav>
37 <p>Tab: {tabId}; controller ready: {String(ready)}; model submissions: {sent}</p>
38 <div className="chat-pane">
39 <Composer running={false} collaborationMode="normal" toolApprovalMode="ask" goal=""
40 cwd="/fixture" modelLabel="Fixture model" tabId={tabId} sessionKey={`fixture:${tabId}`}
41 ready={ready} authentication={authentication} submitDisabled={!modelSettingsAllowSubmission(ready, { authentication, modelSettingsPending })}
42 onSend={() => setSent(n => n + 1)} onCancel={async () => ({ discardedItemIds: [] })}
43 onCycleMode={() => {}} onSetMode={() => {}} onSetCollaborationMode={() => {}}
44 onSetToolApprovalMode={() => {}} onClearGoal={() => {}} onSwitchModel={() => {}} onSetEffort={() => {}} />
45 </div>
46 </main>;
47 }
48
49 createRoot(document.getElementById("root")!).render(<LocaleProvider><ToastProvider><Fixture /></ToastProvider></LocaleProvider>);
50
50 lines Plain Text