





















@@ -0,0 +1,230 @@
1+/* @vitest-environment jsdom */
2+3+import { html } from "lit";
4+import { beforeEach, describe, expect, it, vi } from "vitest";
5+import type { AppViewState } from "./app-view-state.ts";
6+import type { QuickSettingsProps } from "./views/config-quick.ts";
7+8+const quickSettingsProps = vi.hoisted(() => ({
9+current: null as QuickSettingsProps | null,
10+}));
11+const localStorageValues = vi.hoisted(() => new Map<string, string>());
12+13+vi.mock("../local-storage.ts", () => ({
14+getSafeLocalStorage: () => ({
15+getItem: (key: string) => localStorageValues.get(key) ?? null,
16+removeItem: (key: string) => localStorageValues.delete(key),
17+setItem: (key: string, value: string) => localStorageValues.set(key, value),
18+}),
19+getSafeSessionStorage: () => null,
20+}));
21+22+vi.mock("./views/config-quick.ts", () => ({
23+renderQuickSettings: (props: QuickSettingsProps) => {
24+quickSettingsProps.current = props;
25+return html`<div data-testid="quick-settings"></div>`;
26+},
27+}));
28+29+vi.mock("./views/chat.ts", () => ({
30+renderChat: () => html`<div data-testid="chat"></div>`,
31+}));
32+33+vi.mock("./icons.ts", () => ({
34+icons: {},
35+}));
36+37+import { renderApp } from "./app-render.ts";
38+import { saveLocalAssistantIdentity } from "./storage.ts";
39+40+function createState(overrides: Partial<AppViewState> = {}): AppViewState {
41+return {
42+settings: {
43+gatewayUrl: "ws://localhost:18789",
44+token: "",
45+locale: "en",
46+sessionKey: "main",
47+lastActiveSessionKey: "main",
48+theme: "claw",
49+themeMode: "dark",
50+splitRatio: 0.6,
51+navWidth: 280,
52+navCollapsed: false,
53+navGroupsCollapsed: {},
54+borderRadius: 50,
55+chatFocusMode: false,
56+chatShowThinking: false,
57+chatShowToolCalls: true,
58+},
59+password: "",
60+loginShowGatewayToken: false,
61+loginShowGatewayPassword: false,
62+tab: "config",
63+onboarding: false,
64+basePath: "",
65+connected: true,
66+theme: "claw",
67+themeMode: "dark",
68+themeResolved: "dark",
69+themeOrder: ["claw", "knot", "dash"],
70+customThemeImportUrl: "",
71+customThemeImportBusy: false,
72+customThemeImportMessage: null,
73+customThemeImportExpanded: false,
74+customThemeImportFocusToken: 0,
75+hello: null,
76+lastError: null,
77+lastErrorCode: null,
78+eventLog: [],
79+assistantName: "Nova",
80+assistantAvatar: "/avatar/main",
81+assistantAvatarSource: "avatars/missing.png",
82+assistantAvatarStatus: "none",
83+assistantAvatarReason: "missing",
84+assistantAvatarUploadBusy: false,
85+assistantAvatarUploadError: null,
86+assistantAgentId: "main",
87+userName: null,
88+userAvatar: null,
89+localMediaPreviewRoots: [],
90+embedSandboxMode: "scripts",
91+allowExternalEmbedUrls: false,
92+sessionKey: "main",
93+chatLoading: false,
94+chatSending: false,
95+chatMessage: "",
96+chatAttachments: [],
97+chatMessages: [],
98+chatToolMessages: [],
99+chatStreamSegments: [],
100+chatStream: null,
101+chatStreamStartedAt: null,
102+chatRunId: null,
103+chatSideResult: null,
104+chatSideResultTerminalRuns: new Set(),
105+compactionStatus: null,
106+fallbackStatus: null,
107+chatAvatarUrl: null,
108+chatAvatarSource: null,
109+chatAvatarStatus: null,
110+chatAvatarReason: null,
111+chatThinkingLevel: null,
112+chatModelOverrides: {},
113+chatModelsLoading: false,
114+chatModelCatalog: [],
115+chatQueue: [],
116+chatQueueBySession: {},
117+chatLocalInputHistoryBySession: {},
118+chatInputHistorySessionKey: null,
119+chatInputHistoryItems: null,
120+chatInputHistoryIndex: -1,
121+chatDraftBeforeHistory: null,
122+realtimeTalkActive: false,
123+realtimeTalkStatus: "idle",
124+realtimeTalkDetail: null,
125+realtimeTalkTranscript: null,
126+chatManualRefreshInFlight: false,
127+nodesLoading: false,
128+nodes: [],
129+chatNewMessagesBelow: false,
130+navDrawerOpen: false,
131+sidebarOpen: false,
132+sidebarContent: null,
133+sidebarError: null,
134+splitRatio: 0.6,
135+scrollToBottom: vi.fn(),
136+presenceEntries: [],
137+sessionsResult: null,
138+cronStatus: null,
139+configSettingsMode: "quick",
140+configForm: {},
141+configSnapshot: { config: {}, hash: "hash" } as AppViewState["configSnapshot"],
142+configFormDirty: false,
143+configSaving: false,
144+configApplying: false,
145+cronJobs: [],
146+skillsReport: {
147+skills: [],
148+workspaceDir: "",
149+managedSkillsDir: "",
150+} as AppViewState["skillsReport"],
151+configActiveSection: null,
152+configActiveSubsection: null,
153+communicationsActiveSection: null,
154+communicationsActiveSubsection: null,
155+appearanceActiveSection: null,
156+appearanceActiveSubsection: null,
157+appearanceFormMode: "form",
158+appearanceSearchQuery: "",
159+automationActiveSection: null,
160+automationActiveSubsection: null,
161+infrastructureActiveSection: null,
162+infrastructureActiveSubsection: null,
163+aiAgentsActiveSection: null,
164+aiAgentsActiveSubsection: null,
165+configReady: true,
166+configRaw: "",
167+configRawOriginal: "",
168+configValid: true,
169+configIssues: [],
170+configLoading: false,
171+configSchema: null,
172+configSchemaLoading: false,
173+configUiHints: null,
174+configFormOriginal: {},
175+updateRunning: false,
176+agentsList: null,
177+agentsSelectedId: null,
178+cronModelSuggestions: [],
179+cronForm: { deliveryChannel: "", deliveryMode: "last" },
180+cronFieldErrors: {},
181+cronError: null,
182+cronQuickCreateOpen: false,
183+cronQuickCreateStep: "what",
184+cronQuickCreateDraft: null,
185+cronEditingJobId: null,
186+channelsSnapshot: null,
187+execApprovalQueue: [],
188+dreamingRestartConfirmOpen: false,
189+dreamingRestartConfirmLoading: false,
190+dreamingStatusError: null,
191+client: null,
192+refreshSessionsAfterChat: new Set(),
193+connect: vi.fn(),
194+setTab: vi.fn(),
195+setTheme: vi.fn(),
196+setThemeMode: vi.fn(),
197+setCustomThemeImportUrl: vi.fn(),
198+openCustomThemeImport: vi.fn(),
199+importCustomTheme: vi.fn(),
200+clearCustomTheme: vi.fn(),
201+setBorderRadius: vi.fn(),
202+applySettings: vi.fn(),
203+applyLocalUserIdentity: vi.fn(),
204+loadOverview: vi.fn(),
205+loadAssistantIdentity: vi.fn(),
206+loadCron: vi.fn(),
207+ ...overrides,
208+} as unknown as AppViewState;
209+}
210+211+beforeEach(() => {
212+localStorageValues.clear();
213+quickSettingsProps.current = null;
214+});
215+216+describe("renderApp assistant avatar routing", () => {
217+it("passes the browser-local assistant override to Quick Settings ahead of stale identity metadata", () => {
218+const dataUrl = "data:image/png;base64,bG9jYWwtYXNzaXN0YW50";
219+saveLocalAssistantIdentity({ avatar: dataUrl });
220+221+renderApp(createState());
222+223+expect(quickSettingsProps.current?.assistantAvatar).toBe(dataUrl);
224+expect(quickSettingsProps.current?.assistantAvatarUrl).toBe(dataUrl);
225+expect(quickSettingsProps.current?.assistantAvatarSource).toBe(dataUrl);
226+expect(quickSettingsProps.current?.assistantAvatarStatus).toBe("data");
227+expect(quickSettingsProps.current?.assistantAvatarReason).toBeNull();
228+expect(quickSettingsProps.current?.assistantAvatarOverride).toBe(dataUrl);
229+});
230+});
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。