|
1 | | -import { EnvironmentId, type LocalApi } from "@t3tools/contracts"; |
| 1 | +import { EnvironmentId, type LocalApi, type PersistedSavedEnvironmentRecord } from "@t3tools/contracts"; |
2 | 2 | import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; |
3 | 3 |
|
4 | 4 | import { |
5 | 5 | resetSavedEnvironmentRegistryStoreForTests, |
6 | 6 | resetSavedEnvironmentRuntimeStoreForTests, |
7 | 7 | useSavedEnvironmentRegistryStore, |
8 | 8 | useSavedEnvironmentRuntimeStore, |
| 9 | + waitForSavedEnvironmentRegistryHydration, |
9 | 10 | } from "./catalog"; |
10 | 11 |
|
11 | 12 | describe("environment runtime catalog stores", () => { |
@@ -88,4 +89,49 @@ describe("environment runtime catalog stores", () => { |
88 | 89 |
|
89 | 90 | expect(errorSpy).toHaveBeenCalledWith("[SAVED_ENVIRONMENTS] persist failed", expect.any(Error)); |
90 | 91 | }); |
| 92 | + |
| 93 | + it("does not let stale hydration overwrite records added while hydration is in flight", async () => { |
| 94 | + let resolveRegistryRead: () => void = () => { |
| 95 | + throw new Error("Registry read resolver was not initialized."); |
| 96 | + }; |
| 97 | + |
| 98 | + vi.stubGlobal("window", { |
| 99 | + nativeApi: { |
| 100 | + persistence: { |
| 101 | + getClientSettings: async () => null, |
| 102 | + setClientSettings: async () => undefined, |
| 103 | + getSavedEnvironmentRegistry: () => |
| 104 | + new Promise<readonly PersistedSavedEnvironmentRecord[]>((resolve) => { |
| 105 | + resolveRegistryRead = () => resolve([]); |
| 106 | + }), |
| 107 | + setSavedEnvironmentRegistry: async () => undefined, |
| 108 | + getSavedEnvironmentSecret: async () => null, |
| 109 | + setSavedEnvironmentSecret: async () => true, |
| 110 | + removeSavedEnvironmentSecret: async () => undefined, |
| 111 | + }, |
| 112 | + } satisfies Pick<LocalApi, "persistence">, |
| 113 | + }); |
| 114 | + |
| 115 | + const { __resetLocalApiForTests } = await import("../../localApi"); |
| 116 | + await __resetLocalApiForTests(); |
| 117 | + |
| 118 | + const hydrationPromise = waitForSavedEnvironmentRegistryHydration(); |
| 119 | + |
| 120 | + const environmentId = EnvironmentId.makeUnsafe("environment-1"); |
| 121 | + const record = { |
| 122 | + environmentId, |
| 123 | + label: "Remote environment", |
| 124 | + httpBaseUrl: "https://remote.example.com/", |
| 125 | + wsBaseUrl: "wss://remote.example.com/", |
| 126 | + createdAt: "2026-04-09T00:00:00.000Z", |
| 127 | + lastConnectedAt: null, |
| 128 | + } as const; |
| 129 | + |
| 130 | + useSavedEnvironmentRegistryStore.getState().upsert(record); |
| 131 | + |
| 132 | + resolveRegistryRead(); |
| 133 | + await hydrationPromise; |
| 134 | + |
| 135 | + expect(useSavedEnvironmentRegistryStore.getState().byId[environmentId]).toEqual(record); |
| 136 | + }); |
91 | 137 | }); |
0 commit comments