clarify desktop ai bridge recovery in settings
This commit is contained in:
parent
7b87f976a2
commit
17b030f01f
5 changed files with 1237 additions and 151 deletions
|
|
@ -3,14 +3,22 @@ import { describe, expect, it } from "bun:test";
|
|||
import {
|
||||
createUnavailableState,
|
||||
detectDesktopShell,
|
||||
resolveDesktopAiRuntime
|
||||
resolveDesktopAiRuntime,
|
||||
} from "./desktop-ai";
|
||||
import { requireDesktopActionCopy } from "./desktop-ai-panels";
|
||||
import {
|
||||
getDesktopAiModelListEmptyCopy,
|
||||
getDesktopAiModelSelectLabel,
|
||||
getDesktopAiProfileBadgeLabel,
|
||||
getDesktopAiSettingsBridgeNotice,
|
||||
requireDesktopActionCopy,
|
||||
} from "./desktop-ai-panels";
|
||||
|
||||
describe("desktop ai runtime detection", () => {
|
||||
it("recognizes Electron user agents before the bridge is available", () => {
|
||||
const runtime = resolveDesktopAiRuntime({
|
||||
navigator: { userAgent: "Mozilla/5.0 Islandflow Electron/39.0.0 Safari/537.36" }
|
||||
navigator: {
|
||||
userAgent: "Mozilla/5.0 Islandflow Electron/39.0.0 Safari/537.36",
|
||||
},
|
||||
});
|
||||
|
||||
expect(runtime.shellAvailable).toBe(true);
|
||||
|
|
@ -22,17 +30,21 @@ describe("desktop ai runtime detection", () => {
|
|||
const runtime = resolveDesktopAiRuntime({
|
||||
islandflowDesktop: {
|
||||
ai: {
|
||||
getState: async () => createUnavailableState({ shellAvailable: true, bridgeAvailable: true }),
|
||||
getState: async () =>
|
||||
createUnavailableState({
|
||||
shellAvailable: true,
|
||||
bridgeAvailable: true,
|
||||
}),
|
||||
loginWithBrowser: async () => {},
|
||||
loginWithDeviceCode: async () => {},
|
||||
cancelLogin: async () => {},
|
||||
logout: async () => {},
|
||||
updatePreferences: async () => {},
|
||||
runTask: async () => ({ taskId: "task-1" }),
|
||||
subscribe: () => () => {}
|
||||
}
|
||||
subscribe: () => () => {},
|
||||
},
|
||||
},
|
||||
navigator: { userAgent: "Mozilla/5.0" }
|
||||
navigator: { userAgent: "Mozilla/5.0" },
|
||||
});
|
||||
|
||||
expect(runtime.shellAvailable).toBe(true);
|
||||
|
|
@ -62,15 +74,21 @@ describe("desktop ai unavailable state", () => {
|
|||
|
||||
describe("desktop action copy", () => {
|
||||
it("asks for the desktop app only when the shell is genuinely absent", () => {
|
||||
expect(requireDesktopActionCopy(false, false, false)).toContain("Open Islandflow Desktop");
|
||||
expect(requireDesktopActionCopy(false, false, false)).toContain(
|
||||
"Open Islandflow Desktop",
|
||||
);
|
||||
});
|
||||
|
||||
it("surfaces bridge recovery guidance inside the desktop shell", () => {
|
||||
expect(requireDesktopActionCopy(true, false, false)).toContain("missing the native AI bridge");
|
||||
expect(requireDesktopActionCopy(true, false, false)).toContain(
|
||||
"missing the native AI bridge",
|
||||
);
|
||||
});
|
||||
|
||||
it("asks for login once the bridge is present", () => {
|
||||
expect(requireDesktopActionCopy(true, true, false)).toContain("Connect a ChatGPT or Codex account");
|
||||
expect(requireDesktopActionCopy(true, true, false)).toContain(
|
||||
"Connect a ChatGPT or Codex account",
|
||||
);
|
||||
});
|
||||
|
||||
it("clears helper copy when the action is ready", () => {
|
||||
|
|
@ -81,6 +99,50 @@ describe("desktop action copy", () => {
|
|||
describe("desktop shell detection", () => {
|
||||
it("matches Electron signatures", () => {
|
||||
expect(detectDesktopShell("Mozilla/5.0 Electron/39.0.0")).toBe(true);
|
||||
expect(detectDesktopShell("Mozilla/5.0 Chrome/136.0.0.0 Safari/537.36")).toBe(false);
|
||||
expect(
|
||||
detectDesktopShell("Mozilla/5.0 Chrome/136.0.0.0 Safari/537.36"),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("desktop ai settings copy", () => {
|
||||
it("explains when the desktop app itself is required", () => {
|
||||
expect(getDesktopAiSettingsBridgeNotice(false, false)).toEqual({
|
||||
title: "Desktop app required",
|
||||
body: "Open Islandflow Desktop to connect ChatGPT, load managed models, and use native Copilot controls.",
|
||||
});
|
||||
});
|
||||
|
||||
it("explains when the native bridge is missing from the desktop window", () => {
|
||||
expect(getDesktopAiSettingsBridgeNotice(true, false)?.title).toBe(
|
||||
"Bridge unavailable in this window",
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps the model selector explicit before login", () => {
|
||||
expect(getDesktopAiModelSelectLabel(true, true, false, 0)).toBe(
|
||||
"Connect ChatGPT to load models",
|
||||
);
|
||||
expect(getDesktopAiModelListEmptyCopy(true, true, false)).toContain(
|
||||
"Connect a ChatGPT or Codex account",
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps the model selector explicit while the bridge is disconnected", () => {
|
||||
expect(getDesktopAiModelSelectLabel(true, false, false, 0)).toBe(
|
||||
"Bridge unavailable",
|
||||
);
|
||||
expect(getDesktopAiModelListEmptyCopy(true, false, false)).toContain(
|
||||
"native AI bridge reconnects",
|
||||
);
|
||||
});
|
||||
|
||||
it("shows the real status label when a selected profile is unusable", () => {
|
||||
expect(
|
||||
getDesktopAiProfileBadgeLabel(true, "Bridge unavailable", false),
|
||||
).toBe("Bridge unavailable");
|
||||
expect(
|
||||
getDesktopAiProfileBadgeLabel(true, "Bridge unavailable", true),
|
||||
).toBe("Selected");
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue