import { EnvironmentId, type LocalApi, type PersistedSavedEnvironmentRecord, } from "@t3tools/contracts"; import { afterEach, beforeEach, describe, expect, it, vi } from "vite-plus/test"; import { readSavedEnvironmentCredential, resetSavedEnvironmentRegistryStoreForTests, resetSavedEnvironmentRuntimeStoreForTests, useSavedEnvironmentRegistryStore, useSavedEnvironmentRuntimeStore, waitForSavedEnvironmentRegistryHydration, writeSavedEnvironmentCredential, } from "./catalog"; describe("environment runtime catalog stores", () => { beforeEach(async () => { vi.stubGlobal("window", { nativeApi: { persistence: { getClientSettings: async () => null, setClientSettings: async () => undefined, getSavedEnvironmentRegistry: async () => [], setSavedEnvironmentRegistry: async () => undefined, getSavedEnvironmentSecret: async () => null, setSavedEnvironmentSecret: async () => true, removeSavedEnvironmentSecret: async () => undefined, }, } satisfies Pick, }); const { __resetLocalApiForTests } = await import("../../localApi"); await __resetLocalApiForTests(); }); afterEach(async () => { resetSavedEnvironmentRegistryStoreForTests(); resetSavedEnvironmentRuntimeStoreForTests(); const { __resetLocalApiForTests } = await import("../../localApi"); await __resetLocalApiForTests(); vi.unstubAllGlobals(); }); it("resets the saved environment registry store state", () => { const environmentId = EnvironmentId.make("environment-1"); useSavedEnvironmentRegistryStore.getState().upsert({ environmentId, label: "Remote environment", httpBaseUrl: "https://remote.example.com/", wsBaseUrl: "wss://remote.example.com/", createdAt: "2026-04-09T00:00:00.000Z", lastConnectedAt: null, }); expect(useSavedEnvironmentRegistryStore.getState().byId[environmentId]).toBeDefined(); resetSavedEnvironmentRegistryStoreForTests(); expect(useSavedEnvironmentRegistryStore.getState().byId).toEqual({}); }); it("resets the saved environment runtime store state", () => { const environmentId = EnvironmentId.make("environment-1"); useSavedEnvironmentRuntimeStore.getState().patch(environmentId, { connectionState: "connected", connectedAt: "2026-04-09T00:00:00.000Z", }); expect(useSavedEnvironmentRuntimeStore.getState().byId[environmentId]).toBeDefined(); resetSavedEnvironmentRuntimeStoreForTests(); expect(useSavedEnvironmentRuntimeStore.getState().byId).toEqual({}); }); it("decodes legacy bearer secrets and writes versioned DPoP credentials", async () => { let storedSecret: string | null = "legacy-bearer-token"; vi.stubGlobal("window", { nativeApi: { persistence: { getClientSettings: async () => null, setClientSettings: async () => undefined, getSavedEnvironmentRegistry: async () => [], setSavedEnvironmentRegistry: async () => undefined, getSavedEnvironmentSecret: async () => storedSecret, setSavedEnvironmentSecret: async (_environmentId, secret) => { storedSecret = secret; return true; }, removeSavedEnvironmentSecret: async () => undefined, }, } satisfies Pick, }); const { __resetLocalApiForTests } = await import("../../localApi"); await __resetLocalApiForTests(); const environmentId = EnvironmentId.make("environment-1"); await expect(readSavedEnvironmentCredential(environmentId)).resolves.toEqual({ version: 1, method: "bearer", token: "legacy-bearer-token", }); await expect( writeSavedEnvironmentCredential(environmentId, { version: 1, method: "dpop", accessToken: "managed-dpop-access-token", }), ).resolves.toBe(true); await expect(readSavedEnvironmentCredential(environmentId)).resolves.toEqual({ version: 1, method: "dpop", accessToken: "managed-dpop-access-token", }); }); it("does not throw when local api lookup fails during registry persistence", async () => { vi.unstubAllGlobals(); const errorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); const { __resetLocalApiForTests } = await import("../../localApi"); await __resetLocalApiForTests(); expect(() => useSavedEnvironmentRegistryStore.getState().upsert({ environmentId: EnvironmentId.make("environment-1"), label: "Remote environment", httpBaseUrl: "https://remote.example.com/", wsBaseUrl: "wss://remote.example.com/", createdAt: "2026-04-09T00:00:00.000Z", lastConnectedAt: null, }), ).not.toThrow(); expect(errorSpy).toHaveBeenCalledWith("[SAVED_ENVIRONMENTS] persist failed", expect.any(Error)); }); it("does not let stale hydration overwrite records added while hydration is in flight", async () => { let resolveRegistryRead: () => void = () => { throw new Error("Registry read resolver was not initialized."); }; vi.stubGlobal("window", { nativeApi: { persistence: { getClientSettings: async () => null, setClientSettings: async () => undefined, getSavedEnvironmentRegistry: () => new Promise((resolve) => { resolveRegistryRead = () => resolve([]); }), setSavedEnvironmentRegistry: async () => undefined, getSavedEnvironmentSecret: async () => null, setSavedEnvironmentSecret: async () => true, removeSavedEnvironmentSecret: async () => undefined, }, } satisfies Pick, }); const { __resetLocalApiForTests } = await import("../../localApi"); await __resetLocalApiForTests(); const hydrationPromise = waitForSavedEnvironmentRegistryHydration(); const environmentId = EnvironmentId.make("environment-1"); const record = { environmentId, label: "Remote environment", httpBaseUrl: "https://remote.example.com/", wsBaseUrl: "wss://remote.example.com/", createdAt: "2026-04-09T00:00:00.000Z", lastConnectedAt: null, } as const; useSavedEnvironmentRegistryStore.getState().upsert(record); resolveRegistryRead(); await hydrationPromise; expect(useSavedEnvironmentRegistryStore.getState().byId[environmentId]).toEqual(record); }); });