86 lines
3.1 KiB
TypeScript
86 lines
3.1 KiB
TypeScript
import { describe, expect, it } from "bun:test";
|
|
|
|
import {
|
|
createUnavailableState,
|
|
detectDesktopShell,
|
|
resolveDesktopAiRuntime
|
|
} from "./desktop-ai";
|
|
import { 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" }
|
|
});
|
|
|
|
expect(runtime.shellAvailable).toBe(true);
|
|
expect(runtime.bridgeAvailable).toBe(false);
|
|
expect(runtime.bridge).toBeNull();
|
|
});
|
|
|
|
it("treats a bridged window as desktop even without an Electron user agent", () => {
|
|
const runtime = resolveDesktopAiRuntime({
|
|
islandflowDesktop: {
|
|
ai: {
|
|
getState: async () => createUnavailableState({ shellAvailable: true, bridgeAvailable: true }),
|
|
loginWithBrowser: async () => {},
|
|
loginWithDeviceCode: async () => {},
|
|
cancelLogin: async () => {},
|
|
logout: async () => {},
|
|
updatePreferences: async () => {},
|
|
runTask: async () => ({ taskId: "task-1" }),
|
|
subscribe: () => () => {}
|
|
}
|
|
},
|
|
navigator: { userAgent: "Mozilla/5.0" }
|
|
});
|
|
|
|
expect(runtime.shellAvailable).toBe(true);
|
|
expect(runtime.bridgeAvailable).toBe(true);
|
|
expect(runtime.bridge).not.toBeNull();
|
|
});
|
|
});
|
|
|
|
describe("desktop ai unavailable state", () => {
|
|
it("keeps desktopAvailable false for real browser fallbacks", () => {
|
|
const state = createUnavailableState();
|
|
|
|
expect(state.desktopAvailable).toBe(false);
|
|
expect(state.transportStatus).toBe("stopped");
|
|
expect(state.transportError).toContain("Electron app");
|
|
});
|
|
|
|
it("reports desktop-shell bridge failures without pretending the app is a browser", () => {
|
|
const state = createUnavailableState({ shellAvailable: true });
|
|
|
|
expect(state.desktopAvailable).toBe(true);
|
|
expect(state.transportStatus).toBe("error");
|
|
expect(state.transportError).toContain("native AI bridge");
|
|
expect(state.account.login.message).toContain("Reload the window");
|
|
});
|
|
});
|
|
|
|
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");
|
|
});
|
|
|
|
it("surfaces bridge recovery guidance inside the desktop shell", () => {
|
|
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");
|
|
});
|
|
|
|
it("clears helper copy when the action is ready", () => {
|
|
expect(requireDesktopActionCopy(true, true, true)).toBe("");
|
|
});
|
|
});
|
|
|
|
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);
|
|
});
|
|
});
|