Files
openwork/apps/app/tests/gateway-runtime.test.ts

767 lines
29 KiB
TypeScript

import { afterEach, beforeEach, describe, expect, test } from "bun:test";
import {
buildDenAuthUrl,
createDenClient,
getDenMcpUrl,
initializeDenBootstrapConfig,
readDenBootstrapConfig,
readDenSettings,
resolveDenBaseUrls,
} from "../src/app/lib/den";
import {
hydrateOpenworkServerSettingsFromEnv,
readOpenworkServerSettings,
} from "../src/app/lib/openwork-server";
import { createOpenworkServerStore } from "../src/react-app/domains/connections/openwork-server-store";
import { buildOpenworkHealthHeaders } from "../src/react-app/kernel/server-provider";
import {
isStaleStoredDesktopConnection,
resolveOpenworkConnection,
} from "../src/react-app/shell/openwork-connection";
const originalWindow = globalThis.window;
const originalFetch = globalThis.fetch;
const originalDeployment = process.env.VITE_OPENWORK_DEPLOYMENT;
function restoreEnv(key: string, value: string | undefined) {
if (value === undefined) delete process.env[key];
else process.env[key] = value;
}
function memoryStorage(): Storage {
const map = new Map<string, string>();
return {
get length() {
return map.size;
},
clear() {
map.clear();
},
getItem(key: string) {
return map.get(key) ?? null;
},
key(index: number) {
return Array.from(map.keys())[index] ?? null;
},
removeItem(key: string) {
map.delete(key);
},
setItem(key: string, value: string) {
map.set(key, value);
},
};
}
function getRequestUrl(input: RequestInfo | URL): string {
if (input instanceof URL) return input.toString();
if (typeof input === "string") return input;
return input.url;
}
function createTestOpenworkServerStore(startupPreference: "local" | "server" = "server") {
return createOpenworkServerStore({
startupPreference: () => startupPreference,
documentVisible: () => true,
developerMode: () => false,
runtimeWorkspaceId: () => "workspace_test",
activeClient: () => null,
selectedWorkspaceDisplay: () => ({
id: "workspace_test",
name: "Test workspace",
path: "/tmp/workspace_test",
preset: "default",
workspaceType: "local",
}),
restartLocalServer: async () => false,
createRemoteWorkspaceFlow: async () => false,
});
}
function installWindow(options: {
origin: string;
gateway?: boolean;
bootstrapToken?: string;
electronInfo?: {
baseUrl: string;
ownerToken: string;
clientToken?: string;
hostToken?: string;
};
/** Raw openworkServerInfo response for non-ready/restarting server states. */
electronServerInfoRaw?: Record<string, unknown>;
/** Simulate a desktop bridge whose openworkServerInfo call fails outright. */
electronServerInfoError?: boolean;
}) {
const localStorage = memoryStorage();
const electronBridgeInstalled =
options.electronInfo || options.electronServerInfoRaw || options.electronServerInfoError;
Object.defineProperty(globalThis, "window", {
configurable: true,
value: {
localStorage,
dispatchEvent: () => true,
setTimeout: () => 1,
clearTimeout: () => undefined,
location: { origin: options.origin },
__OPENWORK_GATEWAY__: options.gateway ? { version: 1 } : undefined,
__OPENWORK_BOOTSTRAP__: options.bootstrapToken ? { token: options.bootstrapToken } : undefined,
__OPENWORK_ELECTRON__: electronBridgeInstalled
? {
invokeDesktop: async (command: string) => {
if (command !== "openworkServerInfo") {
throw new Error(`Unexpected desktop command: ${command}`);
}
if (options.electronServerInfoError) {
throw new Error("desktop bridge unavailable");
}
if (options.electronServerInfoRaw) {
return options.electronServerInfoRaw;
}
return {
running: true,
baseUrl: options.electronInfo?.baseUrl,
ownerToken: options.electronInfo?.ownerToken,
clientToken: options.electronInfo?.clientToken,
hostToken: options.electronInfo?.hostToken,
};
},
}
: undefined,
},
});
return localStorage;
}
describe("gateway runtime mode", () => {
beforeEach(() => {
process.env.VITE_OPENWORK_DEPLOYMENT = "web";
});
afterEach(() => {
Object.defineProperty(globalThis, "window", {
configurable: true,
value: originalWindow,
});
Object.defineProperty(globalThis, "fetch", {
configurable: true,
value: originalFetch,
});
if (originalDeployment === undefined) {
delete process.env.VITE_OPENWORK_DEPLOYMENT;
} else {
process.env.VITE_OPENWORK_DEPLOYMENT = originalDeployment;
}
});
test("resolves OpenWork server traffic through the gateway origin with the Den session token", async () => {
const storage = installWindow({ origin: "https://web.openworklabs.com", gateway: true });
storage.setItem("openwork.den.authToken", "den-session-token");
storage.setItem("openwork.server.urlOverride", "https://direct-instance.example.com");
storage.setItem("openwork.server.token", "stale-instance-token");
const connection = await resolveOpenworkConnection();
expect(connection).toEqual({
normalizedBaseUrl: "https://web.openworklabs.com",
resolvedToken: "den-session-token",
resolvedHostToken: "",
hostInfo: null,
source: "gateway",
});
});
test("keeps the OpenWork server snapshot stable when options have not changed", () => {
installWindow({ origin: "https://web.openworklabs.com", gateway: true });
const store = createTestOpenworkServerStore();
const initialSnapshot = store.getSnapshot();
let notifications = 0;
const unsubscribe = store.subscribe(() => {
notifications += 1;
});
store.syncFromOptions();
expect(store.getSnapshot()).toBe(initialSnapshot);
expect(notifications).toBe(0);
store.updateOpenworkServerSettings({
urlOverride: "https://instance.example.com",
token: "instance-token",
});
expect(store.getSnapshot()).not.toBe(initialSnapshot);
expect(notifications).toBe(1);
unsubscribe();
});
test("keeps Den web on the configured origin and Den API calls on the gateway origin", () => {
const storage = installWindow({ origin: "https://gw.example", gateway: true });
storage.setItem("openwork.den.baseUrl", "https://app.openworklabs.com");
storage.setItem("openwork.den.authToken", "den-session-token");
expect(resolveDenBaseUrls("https://gw.example")).toEqual({
baseUrl: "https://app.openworklabs.com",
apiBaseUrl: "https://gw.example/api/den",
});
expect(readDenSettings().baseUrl).toBe("https://app.openworklabs.com");
expect(readDenSettings().apiBaseUrl).toBe("https://gw.example/api/den");
expect(readDenSettings().authToken).toBe("den-session-token");
});
test("builds web auth URLs on the Den web origin with the gateway return origin", () => {
installWindow({ origin: "https://gw.example", gateway: true });
const authUrl = new URL(buildDenAuthUrl(readDenSettings().baseUrl, "sign-up"));
expect(authUrl.origin).toBe("https://app.openworklabs.com");
expect(authUrl.searchParams.get("mode")).toBe("sign-up");
expect(authUrl.searchParams.get("webAuth")).toBe("1");
expect(authUrl.searchParams.get("webAuthReturn")).toBe("https://gw.example");
});
test("routes Den auth API paths to Den web and v1 paths through the gateway API", async () => {
installWindow({ origin: "https://gw.example", gateway: true });
const requestedUrls: string[] = [];
Object.defineProperty(globalThis, "fetch", {
configurable: true,
value: async (input: RequestInfo | URL) => {
requestedUrls.push(getRequestUrl(input));
return new Response(JSON.stringify({
user: { id: "user_test", email: "user@example.com" },
token: "tok_test",
}), {
status: 200,
headers: { "content-type": "application/json" },
});
},
});
const client = createDenClient({ baseUrl: readDenSettings().baseUrl, token: "tok_test" });
await client.signInEmail("user@example.com", "password");
await client.getSession();
expect(requestedUrls).toEqual([
"https://app.openworklabs.com/api/auth/sign-in/email",
"https://gw.example/api/den/v1/me",
]);
});
test("reads Den-authored Web access through the gateway for the selected organization", async () => {
installWindow({ origin: "https://gw.example", gateway: true });
const requests: Array<{
url: string;
authorization: string | null;
organizationId: string | null;
}> = [];
Object.defineProperty(globalThis, "fetch", {
configurable: true,
value: async (input: RequestInfo | URL, init?: RequestInit) => {
const url = getRequestUrl(input);
const headers = new Headers(init?.headers);
requests.push({
url,
authorization: headers.get("authorization"),
organizationId: headers.get("x-openwork-org-id"),
});
if (new URL(url).pathname === "/api/den/v1/org") {
return Response.json({ capabilities: { openworkWeb: true } });
}
return Response.json({
billing: {
stripe: {
web: {
hasAccess: true,
accessSource: "complimentary",
hasEligibleSubscription: false,
complimentaryAccess: true,
},
},
},
});
},
});
const access = await createDenClient({
baseUrl: readDenSettings().baseUrl,
token: "tok_test",
}).getOpenWorkWebAccess("org_test");
expect(access).toEqual({ hasAccess: true, accessSource: "complimentary" });
expect(requests).toEqual([
{
url: "https://gw.example/api/den/v1/org",
authorization: "Bearer tok_test",
organizationId: "org_test",
},
{
url: "https://gw.example/api/den/v1/billing/web",
authorization: "Bearer tok_test",
organizationId: "org_test",
},
]);
});
test("keeps Web locked without calling billing when an older Den omits the capability", async () => {
installWindow({ origin: "https://gw.example", gateway: true });
const requestedUrls: string[] = [];
Object.defineProperty(globalThis, "fetch", {
configurable: true,
value: async (input: RequestInfo | URL) => {
requestedUrls.push(getRequestUrl(input));
return Response.json({ capabilities: {} });
},
});
const access = await createDenClient({
baseUrl: readDenSettings().baseUrl,
token: "tok_test",
}).getOpenWorkWebAccess("org_test");
expect(access).toEqual({ hasAccess: false, accessSource: null });
expect(requestedUrls).toEqual(["https://gw.example/api/den/v1/org"]);
});
test("uses the gateway Den API proxy for MCP", () => {
installWindow({ origin: "https://gw.example", gateway: true });
expect(getDenMcpUrl()).toBe("https://gw.example/api/den/mcp");
});
test("returns a stable gateway bootstrap snapshot for React external stores", () => {
installWindow({ origin: "https://web.openworklabs.com", gateway: true });
const first = readDenBootstrapConfig();
const second = readDenBootstrapConfig();
expect(second).toBe(first);
expect(first.baseUrl).toBe("https://app.openworklabs.com");
expect(first.apiBaseUrl).toBe("https://web.openworklabs.com/api/den");
});
test("does not hydrate an instance bootstrap token into server storage behind the gateway", () => {
const storage = installWindow({
origin: "https://web.openworklabs.com",
gateway: true,
bootstrapToken: "instance-token-must-not-store",
});
hydrateOpenworkServerSettingsFromEnv();
expect(storage.getItem("openwork.server.token")).toBeNull();
expect(readOpenworkServerSettings().token).toBeUndefined();
});
test("uses same-origin and the Den bearer for OpenWork server store env calls behind the gateway", async () => {
const storage = installWindow({ origin: "https://gw.example", gateway: true });
storage.setItem("openwork.den.authToken", "den-session-token");
storage.setItem("openwork.server.urlOverride", "https://direct-instance.example.com");
storage.setItem("openwork.server.token", "stale-instance-token");
storage.setItem("openwork.server.hostToken", "stale-host-token");
const requests: Array<{ url: string; authorization: string | null; hostToken: string | null }> = [];
Object.defineProperty(globalThis, "fetch", {
configurable: true,
value: async (input: RequestInfo | URL, init?: RequestInit) => {
const headers = new Headers(init?.headers);
requests.push({
url: getRequestUrl(input),
authorization: headers.get("authorization"),
hostToken: headers.get("x-openwork-host-token"),
});
return new Response(JSON.stringify({ runtimeKey: "runtime-a", pendingChanges: false, ok: true, count: 1 }), {
status: 200,
headers: { "content-type": "application/json" },
});
},
});
const store = createTestOpenworkServerStore();
const snapshot = store.getSnapshot();
const client = snapshot.openworkServerClient;
if (!client) throw new Error("Expected a gateway OpenWork server client");
expect(snapshot.openworkServerBaseUrl).toBe("https://gw.example");
expect(snapshot.openworkServerAuth.token).toBe("den-session-token");
expect(snapshot.openworkServerAuth.hostToken).toBeUndefined();
expect(client.baseUrl).toBe("https://gw.example");
expect(client.token).toBe("den-session-token");
await client.getUserEnvStatus("runtime-a");
await client.upsertUserEnv([{ key: "OPENAI_API_KEY", value: "sk-test" }]);
expect(requests).toEqual([
{
url: "https://gw.example/env/status?runtimeKey=runtime-a",
authorization: "Bearer den-session-token",
hostToken: null,
},
{
url: "https://gw.example/env",
authorization: "Bearer den-session-token",
hostToken: null,
},
]);
});
test("uses the Den bearer for same-origin OpenCode health polling behind the gateway", () => {
const storage = installWindow({ origin: "https://gw.example", gateway: true });
storage.setItem("openwork.den.authToken", "den-session-token");
storage.setItem("openwork.server.token", "stale-instance-token");
expect(buildOpenworkHealthHeaders("https://gw.example/opencode")).toEqual({
Authorization: "Bearer den-session-token",
});
});
});
describe("non-gateway connection modes", () => {
beforeEach(() => {
process.env.VITE_OPENWORK_DEPLOYMENT = "web";
});
afterEach(() => {
Object.defineProperty(globalThis, "window", {
configurable: true,
value: originalWindow,
});
Object.defineProperty(globalThis, "fetch", {
configurable: true,
value: originalFetch,
});
if (originalDeployment === undefined) {
delete process.env.VITE_OPENWORK_DEPLOYMENT;
} else {
process.env.VITE_OPENWORK_DEPLOYMENT = originalDeployment;
}
});
test("direct instance bootstrap hydration and same-origin resolution are unchanged without the marker", async () => {
installWindow({ origin: "https://instance.example.com", bootstrapToken: "instance-token" });
hydrateOpenworkServerSettingsFromEnv();
const connection = await resolveOpenworkConnection();
expect(readOpenworkServerSettings().token).toBe("instance-token");
expect(connection.normalizedBaseUrl).toBe("https://instance.example.com");
expect(connection.resolvedToken).toBe("instance-token");
expect(connection.source).toBe("same-origin");
});
test("force-env settings overwrite stale localStorage openwork-server credentials", () => {
const previous = {
url: process.env.VITE_OPENWORK_URL,
port: process.env.VITE_OPENWORK_PORT,
token: process.env.VITE_OPENWORK_TOKEN,
hostToken: process.env.VITE_OPENWORK_HOST_TOKEN,
force: process.env.VITE_OPENWORK_FORCE_ENV_SETTINGS,
};
process.env.VITE_OPENWORK_URL = "http://127.0.0.1:8787";
process.env.VITE_OPENWORK_PORT = "8787";
process.env.VITE_OPENWORK_TOKEN = "fresh-token";
process.env.VITE_OPENWORK_HOST_TOKEN = "fresh-host-token";
process.env.VITE_OPENWORK_FORCE_ENV_SETTINGS = "1";
const storage = installWindow({ origin: "http://127.0.0.1:5173" });
storage.setItem("openwork.server.urlOverride", "http://127.0.0.1:9999");
storage.setItem("openwork.server.token", "stale-token");
storage.setItem("openwork.server.hostToken", "stale-host-token");
try {
hydrateOpenworkServerSettingsFromEnv();
expect(readOpenworkServerSettings()).toEqual({
urlOverride: "http://127.0.0.1:8787",
portOverride: 8787,
token: "fresh-token",
hostToken: "fresh-host-token",
remoteAccessEnabled: false,
});
} finally {
restoreEnv("VITE_OPENWORK_URL", previous.url);
restoreEnv("VITE_OPENWORK_PORT", previous.port);
restoreEnv("VITE_OPENWORK_TOKEN", previous.token);
restoreEnv("VITE_OPENWORK_HOST_TOKEN", previous.hostToken);
restoreEnv("VITE_OPENWORK_FORCE_ENV_SETTINGS", previous.force);
}
});
test("force-env without a VITE host token clears a leftover browser host token", () => {
const previous = {
url: process.env.VITE_OPENWORK_URL,
port: process.env.VITE_OPENWORK_PORT,
token: process.env.VITE_OPENWORK_TOKEN,
hostToken: process.env.VITE_OPENWORK_HOST_TOKEN,
force: process.env.VITE_OPENWORK_FORCE_ENV_SETTINGS,
};
process.env.VITE_OPENWORK_URL = "http://127.0.0.1:8787";
process.env.VITE_OPENWORK_PORT = "8787";
process.env.VITE_OPENWORK_TOKEN = "fresh-token";
delete process.env.VITE_OPENWORK_HOST_TOKEN;
process.env.VITE_OPENWORK_FORCE_ENV_SETTINGS = "1";
const storage = installWindow({ origin: "http://127.0.0.1:5178" });
storage.setItem("openwork.server.hostToken", "leaked-host-token");
try {
hydrateOpenworkServerSettingsFromEnv();
expect(readOpenworkServerSettings().hostToken).toBeUndefined();
expect(storage.getItem("openwork.server.hostToken")).toBeNull();
} finally {
restoreEnv("VITE_OPENWORK_URL", previous.url);
restoreEnv("VITE_OPENWORK_PORT", previous.port);
restoreEnv("VITE_OPENWORK_TOKEN", previous.token);
restoreEnv("VITE_OPENWORK_HOST_TOKEN", previous.hostToken);
restoreEnv("VITE_OPENWORK_FORCE_ENV_SETTINGS", previous.force);
}
});
test("stored server settings still win without the marker", async () => {
const storage = installWindow({ origin: "https://instance.example.com" });
storage.setItem("openwork.server.urlOverride", "https://manual.example.com");
storage.setItem("openwork.server.token", "manual-token");
storage.setItem("openwork.server.hostToken", "host-token");
const connection = await resolveOpenworkConnection();
expect(connection.normalizedBaseUrl).toBe("https://manual.example.com");
expect(connection.resolvedToken).toBe("manual-token");
expect(connection.resolvedHostToken).toBe("");
expect(connection.source).toBe("stored-settings");
const store = createTestOpenworkServerStore();
const snapshot = store.getSnapshot();
expect(snapshot.openworkServerBaseUrl).toBe("https://manual.example.com");
expect(snapshot.openworkServerAuth.token).toBe("manual-token");
expect(snapshot.openworkServerAuth.hostToken).toBeUndefined();
expect(snapshot.openworkServerClient?.baseUrl).toBe("https://manual.example.com");
expect(snapshot.openworkServerClient?.token).toBe("manual-token");
});
test("OpenCode health polling still uses the stored instance token without the gateway marker", () => {
const storage = installWindow({ origin: "https://instance.example.com" });
storage.setItem("openwork.server.token", "instance-token");
expect(buildOpenworkHealthHeaders("https://instance.example.com/opencode")).toEqual({
Authorization: "Bearer instance-token",
});
});
test("plain web Den settings still use a stored custom base URL without the marker", () => {
const storage = installWindow({ origin: "https://instance.example.com" });
storage.setItem("openwork.den.baseUrl", "https://den.self-hosted.example.com");
expect(readDenSettings().baseUrl).toBe("https://den.self-hosted.example.com");
expect(readDenSettings().apiBaseUrl).toBe("https://den.self-hosted.example.com/api/den");
});
test("VITE_DEN_API_BASE_URL pins Den API calls to the proxy while sign-in stays on the web base", () => {
const previous = process.env.VITE_DEN_API_BASE_URL;
process.env.VITE_DEN_API_BASE_URL = "http://127.0.0.1:5178/api/den";
installWindow({ origin: "http://127.0.0.1:5178" });
try {
const settings = readDenSettings();
expect(settings.baseUrl).toBe("https://app.openworklabs.com");
expect(settings.apiBaseUrl).toBe("http://127.0.0.1:5178/api/den");
// Every Den client derives its API base the same way, so requests go
// through the same-origin proxy even when created from the web base.
const client = createDenClient({ baseUrl: settings.baseUrl, token: "den-token" });
expect(client.baseUrls.apiBaseUrl).toBe("http://127.0.0.1:5178/api/den");
expect(client.baseUrls.baseUrl).toBe("https://app.openworklabs.com");
// Sign-in still opens the real Den web app, not the proxy origin.
// Loopback cannot use webAuth return URLs against hosted Den, so the
// URL uses desktopAuth (copy link / paste grant) instead.
const authUrl = new URL(buildDenAuthUrl(settings.baseUrl, "sign-in"));
expect(authUrl.origin).toBe("https://app.openworklabs.com");
expect(authUrl.searchParams.get("desktopAuth")).toBe("1");
expect(authUrl.searchParams.get("webAuth")).toBeNull();
} finally {
restoreEnv("VITE_DEN_API_BASE_URL", previous);
}
});
test("loopback web auth uses desktop handoff instead of an unapprovable webAuth return URL", () => {
installWindow({ origin: "http://127.0.0.1:5178" });
const authUrl = new URL(buildDenAuthUrl(readDenSettings().baseUrl, "sign-in"));
expect(authUrl.origin).toBe("https://app.openworklabs.com");
expect(authUrl.searchParams.get("desktopAuth")).toBe("1");
expect(authUrl.searchParams.get("desktopScheme")).toBe("openwork");
expect(authUrl.searchParams.get("webAuth")).toBeNull();
expect(authUrl.searchParams.get("webAuthReturn")).toBeNull();
});
test("force-env clears a stale stored Den base URL on web bootstrap init", async () => {
const previous = process.env.VITE_OPENWORK_FORCE_ENV_SETTINGS;
process.env.VITE_OPENWORK_FORCE_ENV_SETTINGS = "1";
const storage = installWindow({ origin: "http://127.0.0.1:5178" });
storage.setItem("openwork.den.baseUrl", "http://127.0.0.1:8779");
try {
await initializeDenBootstrapConfig();
expect(storage.getItem("openwork.den.baseUrl")).toBeNull();
expect(readDenSettings().baseUrl).toBe("https://app.openworklabs.com");
} finally {
restoreEnv("VITE_OPENWORK_FORCE_ENV_SETTINGS", previous);
}
});
test("desktop runtime still uses live desktop server info without the marker", async () => {
installWindow({
origin: "https://instance.example.com",
electronInfo: {
baseUrl: "http://127.0.0.1:8787",
ownerToken: "owner-token",
hostToken: "host-token",
},
});
const connection = await resolveOpenworkConnection();
expect(connection.normalizedBaseUrl).toBe("http://127.0.0.1:8787");
expect(connection.resolvedToken).toBe("owner-token");
expect(connection.resolvedHostToken).toBe("host-token");
expect(connection.source).toBe("desktop-runtime");
});
test("desktop reconnect persists the complete live server credential bundle", async () => {
const storage = installWindow({
origin: "https://instance.example.com",
electronInfo: {
baseUrl: "http://127.0.0.1:8787",
ownerToken: "owner-token",
clientToken: "live-client-token",
hostToken: "live-host-token",
},
});
storage.setItem("openwork.server.token", "stale-client-token");
storage.setItem("openwork.server.hostToken", "stale-host-token");
Object.defineProperty(globalThis, "fetch", {
configurable: true,
value: async () => new Response(JSON.stringify({ ok: true }), {
status: 200,
headers: { "content-type": "application/json" },
}),
});
const store = createTestOpenworkServerStore("local");
expect(await store.reconnectOpenworkServer()).toBe(true);
expect(readOpenworkServerSettings().token).toBe("live-client-token");
expect(readOpenworkServerSettings().hostToken).toBe("live-host-token");
expect(store.getSnapshot().openworkServerAuth).toEqual({
token: "live-client-token",
hostToken: "live-host-token",
});
});
test("a restarting desktop server invalidates stored loopback settings instead of resolving a dead port", async () => {
// App update / slow restart: the live runtime answers definitively, but
// the server has not republished its base URL and tokens yet. The stored
// loopback settings are from the previous server lifetime.
const storage = installWindow({
origin: "https://instance.example.com",
electronServerInfoRaw: { running: false, baseUrl: null, ownerToken: null, clientToken: null },
});
storage.setItem("openwork.server.urlOverride", "http://127.0.0.1:4100");
storage.setItem("openwork.server.token", "tok_previous_lifetime");
const connection = await resolveOpenworkConnection();
expect(connection.source).toBe("empty");
expect(connection.normalizedBaseUrl).toBe("");
expect(connection.resolvedToken).toBe("");
});
test("a restarting desktop server keeps stored remote/manual servers as the fallback", async () => {
const storage = installWindow({
origin: "https://instance.example.com",
electronServerInfoRaw: { running: false, baseUrl: null, ownerToken: null, clientToken: null },
});
storage.setItem("openwork.server.urlOverride", "https://manual.example.com");
storage.setItem("openwork.server.token", "manual-token");
const connection = await resolveOpenworkConnection();
expect(connection.source).toBe("stored-settings");
expect(connection.normalizedBaseUrl).toBe("https://manual.example.com");
expect(connection.resolvedToken).toBe("manual-token");
});
test("a failing desktop bridge still falls back to stored settings", async () => {
// No definitive live answer: keep the pre-existing fallback so broken
// bridges do not strand configured connections.
const storage = installWindow({
origin: "https://instance.example.com",
electronServerInfoError: true,
});
storage.setItem("openwork.server.urlOverride", "http://127.0.0.1:4100");
storage.setItem("openwork.server.token", "tok_stored");
const connection = await resolveOpenworkConnection();
expect(connection.source).toBe("stored-settings");
expect(connection.normalizedBaseUrl).toBe("http://127.0.0.1:4100");
expect(connection.resolvedToken).toBe("tok_stored");
});
});
describe("isStaleStoredDesktopConnection", () => {
test("marks stored loopback connections stale only on a definitive not-ready answer", () => {
expect(
isStaleStoredDesktopConnection({
desktopRuntime: true,
desktopServerReportedNotReady: true,
storedBaseUrl: "http://127.0.0.1:4100",
runtimeReportedBaseUrl: "",
}),
).toBe(true);
expect(
isStaleStoredDesktopConnection({
desktopRuntime: true,
desktopServerReportedNotReady: false,
storedBaseUrl: "http://127.0.0.1:4100",
runtimeReportedBaseUrl: "",
}),
).toBe(false);
expect(
isStaleStoredDesktopConnection({
desktopRuntime: false,
desktopServerReportedNotReady: true,
storedBaseUrl: "http://127.0.0.1:4100",
runtimeReportedBaseUrl: "",
}),
).toBe(false);
});
test("keeps remote URLs unless they match the runtime-reported base URL", () => {
expect(
isStaleStoredDesktopConnection({
desktopRuntime: true,
desktopServerReportedNotReady: true,
storedBaseUrl: "https://manual.example.com",
runtimeReportedBaseUrl: "",
}),
).toBe(false);
expect(
isStaleStoredDesktopConnection({
desktopRuntime: true,
desktopServerReportedNotReady: true,
storedBaseUrl: "https://manual.example.com",
runtimeReportedBaseUrl: "https://manual.example.com",
}),
).toBe(true);
expect(
isStaleStoredDesktopConnection({
desktopRuntime: true,
desktopServerReportedNotReady: true,
storedBaseUrl: "",
runtimeReportedBaseUrl: "",
}),
).toBe(false);
});
});