Download __tests__/api/backend-registry/storage.test.ts from SaylorTwift/openhands: direct link, hf CLI and curl.
- Browser
- Download file 11 kB
-
https://huggingface.co/SaylorTwift/openhands/resolve/main/__tests__/api/backend-registry/storage.test.ts
- Command line
-
hf download hf://SaylorTwift/openhands/__tests__/api/backend-registry/storage.test.ts
-
curl -L -o storage.test.ts https://huggingface.co/SaylorTwift/openhands/resolve/main/__tests__/api/backend-registry/storage.test.ts
11 kB
| import { afterEach, describe, expect, it, vi } from "vitest"; | |
| import { | |
| ACTIVE_BACKEND_STORAGE_KEY, | |
| BACKENDS_STORAGE_KEY, | |
| readStoredActiveBackend, | |
| readStoredBackends, | |
| writeStoredActiveBackend, | |
| writeStoredBackends, | |
| } from "#/api/backend-registry/storage"; | |
| import type { Backend } from "#/api/backend-registry/types"; | |
| const ORIGINAL_LOCATION = window.location; | |
| function mockWindowLocation(url: string) { | |
| Object.defineProperty(window, "location", { | |
| configurable: true, | |
| value: new URL(url), | |
| }); | |
| } | |
| afterEach(() => { | |
| window.localStorage.clear(); | |
| window.sessionStorage.clear(); | |
| delete (window as unknown as Record<string, unknown>) | |
| .__AGENT_CANVAS_LOCK_TO_CLOUD__; | |
| Object.defineProperty(window, "location", { | |
| configurable: true, | |
| value: ORIGINAL_LOCATION, | |
| }); | |
| window.history.pushState({}, "", "/"); | |
| vi.unstubAllEnvs(); | |
| }); | |
| describe("backend-registry storage", () => { | |
| it("round-trips a list of backends", () => { | |
| const backends: Backend[] = [ | |
| { | |
| id: "abc", | |
| name: "Local 1", | |
| host: "http://127.0.0.1:9000", | |
| apiKey: "key-1", | |
| kind: "local", | |
| }, | |
| { | |
| id: "xyz", | |
| name: "Production", | |
| host: "https://app.all-hands.dev", | |
| apiKey: "bearer-2", | |
| kind: "cloud", | |
| }, | |
| ]; | |
| writeStoredBackends(backends); | |
| expect(readStoredBackends()).toEqual(backends); | |
| }); | |
| it("returns empty list when storage is malformed", () => { | |
| window.localStorage.setItem(BACKENDS_STORAGE_KEY, "{not-json"); | |
| expect(readStoredBackends()).toEqual([]); | |
| }); | |
| it("does not seed the default Local backend when launcher details are missing", () => { | |
| vi.stubEnv("VITE_SESSION_API_KEY", ""); | |
| expect(window.localStorage.getItem(BACKENDS_STORAGE_KEY)).toBeNull(); | |
| expect(readStoredBackends()).toEqual([]); | |
| expect(window.localStorage.getItem(BACKENDS_STORAGE_KEY)).toBeNull(); | |
| }); | |
| it("seeds the default Local backend when host and API key are available", () => { | |
| vi.stubEnv("VITE_BACKEND_BASE_URL", "http://localhost:9000"); | |
| vi.stubEnv("VITE_SESSION_API_KEY", "fresh-session-key"); | |
| const result = readStoredBackends(); | |
| expect(result).toHaveLength(1); | |
| expect(result[0]).toMatchObject({ | |
| id: "default-local", | |
| host: "http://localhost:9000", | |
| apiKey: "fresh-session-key", | |
| kind: "local", | |
| }); | |
| expect(window.localStorage.getItem(BACKENDS_STORAGE_KEY)).not.toBeNull(); | |
| expect(readStoredBackends()).toEqual(result); | |
| }); | |
| it("seeds a cookie-auth Cloud backend when locked to the current origin", () => { | |
| ( | |
| window as unknown as Record<string, unknown> | |
| ).__AGENT_CANVAS_LOCK_TO_CLOUD__ = window.location.origin; | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([ | |
| { | |
| id: "stale-local", | |
| name: "Stale Local", | |
| host: "http://localhost:18000", | |
| apiKey: "stale-session", | |
| kind: "local", | |
| }, | |
| ]), | |
| ); | |
| const result = readStoredBackends(); | |
| expect(result).toEqual([ | |
| { | |
| id: "locked-cloud", | |
| name: "OpenHands Cloud", | |
| host: window.location.origin, | |
| apiKey: "", | |
| kind: "cloud", | |
| authMode: "cookie", | |
| }, | |
| ]); | |
| expect(readStoredActiveBackend()).toEqual({ | |
| backendId: "locked-cloud", | |
| orgId: null, | |
| }); | |
| }); | |
| it("seeds the cookie-auth Cloud backend on the current origin when the locked host is an equivalent transition domain", () => { | |
| mockWindowLocation("https://pr-254.staging.openhands.dev/canvas"); | |
| ( | |
| window as unknown as Record<string, unknown> | |
| ).__AGENT_CANVAS_LOCK_TO_CLOUD__ = "https://pr-254.staging.all-hands.dev"; | |
| expect(readStoredBackends()).toEqual([ | |
| { | |
| id: "locked-cloud", | |
| name: "OpenHands Cloud", | |
| host: "https://pr-254.staging.openhands.dev", | |
| apiKey: "", | |
| kind: "cloud", | |
| authMode: "cookie", | |
| }, | |
| ]); | |
| }); | |
| it("preserves an existing locked Cloud org selection while reseeding", () => { | |
| ( | |
| window as unknown as Record<string, unknown> | |
| ).__AGENT_CANVAS_LOCK_TO_CLOUD__ = window.location.origin; | |
| writeStoredActiveBackend({ backendId: "locked-cloud", orgId: "org-1" }); | |
| expect(readStoredBackends()[0]).toMatchObject({ id: "locked-cloud" }); | |
| expect(readStoredActiveBackend()).toEqual({ | |
| backendId: "locked-cloud", | |
| orgId: "org-1", | |
| }); | |
| }); | |
| it("does not seed a cookie-auth Cloud backend when locked cross-origin", () => { | |
| ( | |
| window as unknown as Record<string, unknown> | |
| ).__AGENT_CANVAS_LOCK_TO_CLOUD__ = "https://app.all-hands.dev"; | |
| vi.stubEnv("VITE_SESSION_API_KEY", ""); | |
| expect(readStoredBackends()).toEqual([]); | |
| }); | |
| it("re-seeds the default Local backend when storage holds an empty array and launcher details are available", () => { | |
| vi.stubEnv("VITE_BACKEND_BASE_URL", "http://localhost:9000"); | |
| vi.stubEnv("VITE_SESSION_API_KEY", "fresh-session-key"); | |
| window.localStorage.setItem(BACKENDS_STORAGE_KEY, JSON.stringify([])); | |
| const result = readStoredBackends(); | |
| expect(result).toHaveLength(1); | |
| expect(result[0]).toMatchObject({ id: "default-local", kind: "local" }); | |
| }); | |
| it("re-seeds the default Local backend when every stored entry is invalid and launcher details are available", () => { | |
| vi.stubEnv("VITE_BACKEND_BASE_URL", "http://localhost:9000"); | |
| vi.stubEnv("VITE_SESSION_API_KEY", "fresh-session-key"); | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([{ kind: "cloud" }, "not-an-object"]), | |
| ); | |
| const result = readStoredBackends(); | |
| expect(result).toHaveLength(1); | |
| expect(result[0]).toMatchObject({ id: "default-local", kind: "local" }); | |
| }); | |
| it("filters out backends with invalid shape", () => { | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([ | |
| { id: "ok", name: "x", host: "y", apiKey: "z", kind: "local" }, | |
| { id: "missing-kind", name: "x", host: "y", apiKey: "z" }, | |
| { kind: "cloud" }, | |
| "not-an-object", | |
| ]), | |
| ); | |
| expect(readStoredBackends()).toEqual([ | |
| { id: "ok", name: "x", host: "y", apiKey: "z", kind: "local" }, | |
| ]); | |
| }); | |
| it("preserves stored backends without API keys", () => { | |
| vi.stubEnv("VITE_SESSION_API_KEY", ""); | |
| const storedBackend: Backend = { | |
| id: "default-local", | |
| name: "Local", | |
| host: window.location.origin, | |
| apiKey: "", | |
| kind: "local", | |
| }; | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([storedBackend]), | |
| ); | |
| expect(readStoredBackends()).toEqual([storedBackend]); | |
| }); | |
| it("syncs a stale default Local API key from env defaults", () => { | |
| vi.stubEnv("VITE_SESSION_API_KEY", "fresh-session-key"); | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([ | |
| { | |
| id: "default-local", | |
| name: "Local", | |
| host: window.location.origin, | |
| apiKey: "stored-session-key", | |
| kind: "local", | |
| }, | |
| ]), | |
| ); | |
| expect(readStoredBackends()[0]).toMatchObject({ | |
| id: "default-local", | |
| apiKey: "fresh-session-key", | |
| }); | |
| }); | |
| it("syncs a stale default Local API key across localhost and 127.0.0.1", () => { | |
| vi.stubEnv("VITE_BACKEND_BASE_URL", "http://127.0.0.1:8000"); | |
| vi.stubEnv("VITE_SESSION_API_KEY", "fresh-session-key"); | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([ | |
| { | |
| id: "default-local", | |
| name: "Local", | |
| host: "http://localhost:8000", | |
| apiKey: "stored-session-key", | |
| kind: "local", | |
| }, | |
| ]), | |
| ); | |
| expect(readStoredBackends()[0]).toMatchObject({ | |
| id: "default-local", | |
| host: "http://localhost:8000", | |
| apiKey: "fresh-session-key", | |
| }); | |
| }); | |
| it("preserves a custom backend API key instead of syncing from env defaults", () => { | |
| vi.stubEnv("VITE_SESSION_API_KEY", "fresh-session-key"); | |
| const storedBackend: Backend = { | |
| id: "custom-local", | |
| name: "Custom Local", | |
| host: window.location.origin, | |
| apiKey: "stored-session-key", | |
| kind: "local", | |
| }; | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([storedBackend]), | |
| ); | |
| expect(readStoredBackends()[0]).toMatchObject({ | |
| id: "custom-local", | |
| apiKey: "stored-session-key", | |
| }); | |
| }); | |
| it("preserves a user-edited non-loopback default Local backend API key", () => { | |
| vi.stubEnv("VITE_SESSION_API_KEY", "fresh-session-key"); | |
| const storedBackend: Backend = { | |
| id: "default-local", | |
| name: "Edited Local", | |
| host: "https://example.com", | |
| apiKey: "stored-session-key", | |
| kind: "local", | |
| }; | |
| window.localStorage.setItem( | |
| BACKENDS_STORAGE_KEY, | |
| JSON.stringify([storedBackend]), | |
| ); | |
| expect(readStoredBackends()[0]).toMatchObject({ | |
| id: "default-local", | |
| host: "https://example.com", | |
| apiKey: "stored-session-key", | |
| }); | |
| }); | |
| it("round-trips active selection with orgId", () => { | |
| writeStoredActiveBackend({ backendId: "xyz", orgId: "org-1" }); | |
| expect(readStoredActiveBackend()).toEqual({ | |
| backendId: "xyz", | |
| orgId: "org-1", | |
| }); | |
| }); | |
| it("normalizes missing orgId to null", () => { | |
| writeStoredActiveBackend({ backendId: "xyz" }); | |
| expect(readStoredActiveBackend()).toEqual({ | |
| backendId: "xyz", | |
| orgId: null, | |
| }); | |
| }); | |
| it("prefers the tab-scoped active selection over the global fallback", () => { | |
| window.localStorage.setItem( | |
| ACTIVE_BACKEND_STORAGE_KEY, | |
| JSON.stringify({ backendId: "global-backend", orgId: null }), | |
| ); | |
| window.sessionStorage.setItem( | |
| ACTIVE_BACKEND_STORAGE_KEY, | |
| JSON.stringify({ backendId: "tab-backend", orgId: "org-1" }), | |
| ); | |
| expect(readStoredActiveBackend()).toEqual({ | |
| backendId: "tab-backend", | |
| orgId: "org-1", | |
| }); | |
| }); | |
| it("falls back to the global active selection for new tabs", () => { | |
| window.localStorage.setItem( | |
| ACTIVE_BACKEND_STORAGE_KEY, | |
| JSON.stringify({ backendId: "global-backend", orgId: null }), | |
| ); | |
| expect(readStoredActiveBackend()).toEqual({ | |
| backendId: "global-backend", | |
| orgId: null, | |
| }); | |
| }); | |
| it("clears storage when active selection is set to null", () => { | |
| writeStoredActiveBackend({ backendId: "xyz", orgId: "o" }); | |
| writeStoredActiveBackend(null); | |
| expect( | |
| window.sessionStorage.getItem(ACTIVE_BACKEND_STORAGE_KEY), | |
| ).toBeNull(); | |
| expect(window.localStorage.getItem(ACTIVE_BACKEND_STORAGE_KEY)).toBeNull(); | |
| expect(readStoredActiveBackend()).toBeNull(); | |
| }); | |
| it("returns null active selection when storage is malformed", () => { | |
| window.localStorage.setItem(ACTIVE_BACKEND_STORAGE_KEY, "{broken"); | |
| expect(readStoredActiveBackend()).toBeNull(); | |
| }); | |
| }); | |