fix electron desktop ai runtime fallback detection
This commit is contained in:
parent
a54e847c8e
commit
d15f96d7be
4 changed files with 390 additions and 47 deletions
|
|
@ -19,6 +19,20 @@ import {
|
|||
} from "./desktop-ai-panels";
|
||||
|
||||
describe("desktop ai runtime detection", () => {
|
||||
const createBridge = (getState: () => Promise<ReturnType<typeof createUnavailableState>>) => ({
|
||||
ai: {
|
||||
getState,
|
||||
loginWithBrowser: async () => {},
|
||||
loginWithDeviceCode: async () => {},
|
||||
cancelLogin: async () => {},
|
||||
logout: async () => {},
|
||||
updatePreferences: async () => {},
|
||||
runTask: async () => ({ taskId: "task-1" }),
|
||||
cancelTask: async () => {},
|
||||
subscribe: () => () => {},
|
||||
},
|
||||
});
|
||||
|
||||
it("recognizes the explicit desktop preload marker before the bridge is available", () => {
|
||||
const runtime = resolveDesktopAiRuntime({
|
||||
islandflowDesktopRuntime: {
|
||||
|
|
@ -73,6 +87,88 @@ describe("desktop ai runtime detection", () => {
|
|||
expect(runtime.bridgeAvailable).toBe(true);
|
||||
expect(runtime.bridge).not.toBeNull();
|
||||
});
|
||||
|
||||
it("keeps desktop runtime when the bridge exists before ai state resolves", () => {
|
||||
let resolveState: ((value: ReturnType<typeof createUnavailableState>) => void) | null = null;
|
||||
const pending = new Promise<ReturnType<typeof createUnavailableState>>((resolve) => {
|
||||
resolveState = resolve;
|
||||
});
|
||||
|
||||
const runtime = resolveDesktopAiRuntime({
|
||||
islandflowDesktopRuntime: {
|
||||
app: "islandflow",
|
||||
shell: "electron",
|
||||
},
|
||||
islandflowDesktop: createBridge(() => pending),
|
||||
navigator: { userAgent: "Mozilla/5.0 Safari/537.36" },
|
||||
});
|
||||
|
||||
expect(runtime.shellAvailable).toBe(true);
|
||||
expect(runtime.bridgeAvailable).toBe(true);
|
||||
expect(runtime.bridge).not.toBeNull();
|
||||
expect(
|
||||
requireDesktopActionCopy(
|
||||
runtime.shellAvailable,
|
||||
runtime.bridgeAvailable,
|
||||
false,
|
||||
),
|
||||
).toContain("Connect a ChatGPT or Codex account");
|
||||
|
||||
resolveState?.(
|
||||
createUnavailableState({
|
||||
shellAvailable: true,
|
||||
bridgeAvailable: true,
|
||||
}),
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps bridge-specific recovery copy when bridge state loading fails", async () => {
|
||||
const runtime = resolveDesktopAiRuntime({
|
||||
islandflowDesktopRuntime: {
|
||||
app: "islandflow",
|
||||
shell: "electron",
|
||||
},
|
||||
islandflowDesktop: createBridge(async () => {
|
||||
throw new Error("state failed");
|
||||
}),
|
||||
navigator: { userAgent: "Mozilla/5.0 Safari/537.36" },
|
||||
});
|
||||
|
||||
expect(runtime.shellAvailable).toBe(true);
|
||||
expect(runtime.bridgeAvailable).toBe(true);
|
||||
expect(createUnavailableState(runtime).transportError).toContain(
|
||||
"initial state could not be read",
|
||||
);
|
||||
expect(
|
||||
requireDesktopActionCopy(
|
||||
runtime.shellAvailable,
|
||||
runtime.bridgeAvailable,
|
||||
false,
|
||||
),
|
||||
).not.toContain("Open Islandflow Desktop");
|
||||
});
|
||||
|
||||
it("flips from browser runtime to desktop runtime when the marker appears later", () => {
|
||||
const host: {
|
||||
islandflowDesktopRuntime?: { app?: string | null; shell?: string | null };
|
||||
navigator: { userAgent: string };
|
||||
} = {
|
||||
navigator: { userAgent: "Mozilla/5.0 Safari/537.36" },
|
||||
};
|
||||
|
||||
const initialRuntime = resolveDesktopAiRuntime(host);
|
||||
expect(initialRuntime.shellAvailable).toBe(false);
|
||||
expect(initialRuntime.bridgeAvailable).toBe(false);
|
||||
|
||||
host.islandflowDesktopRuntime = {
|
||||
app: "islandflow",
|
||||
shell: "electron",
|
||||
};
|
||||
|
||||
const nextRuntime = resolveDesktopAiRuntime(host);
|
||||
expect(nextRuntime.shellAvailable).toBe(true);
|
||||
expect(nextRuntime.bridgeAvailable).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("desktop ai unavailable state", () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue