Fix overlay warning

This commit is contained in:
Konstantin Wohlwend 2026-06-24 11:25:57 -07:00
parent d57bba3a06
commit 6883d83ad1
2 changed files with 76 additions and 1 deletions

View File

@ -0,0 +1,72 @@
import { afterEach, describe, expect, it, vi } from "vitest";
import { envVars } from "../generated/env";
import { StackClientApp } from "../lib/hexclave-app";
import { mountPushedConfigErrorOverlay } from ".";
function createMockElement() {
return {
style: {},
appendChild: () => {},
addEventListener: () => {},
setAttribute: () => {},
replaceChildren: () => {},
remove: () => {},
};
}
describe("pushed config error overlay", () => {
afterEach(() => {
vi.unstubAllEnvs();
vi.unstubAllGlobals();
});
it("defers the first project refresh until after construction-time callers finish", async () => {
const app = new StackClientApp({
baseUrl: "http://localhost:12345",
projectId: "00000000-0000-4000-8000-000000000000",
publishableClientKey: "stack-pk-test",
tokenStore: "memory",
redirectMethod: "none",
devTool: false,
});
const getProject = vi.fn(async () => ({
pushedConfigError: null,
configWarnings: [],
}));
Reflect.set(app, "getProject", getProject);
const appendChild = vi.fn();
vi.stubEnv("NODE_ENV", "development");
expect(Reflect.get(envVars, "NODE_ENV")).toBe("development");
vi.stubGlobal("window", {
"__hexclave-pushed-config-error-overlay": null,
location: {
href: "http://localhost:3000",
},
});
vi.stubGlobal("document", {
body: {
appendChild,
},
createElement: () => createMockElement(),
createTextNode: () => createMockElement(),
});
vi.stubGlobal("localStorage", {
getItem: () => null,
setItem: () => {},
removeItem: () => {},
});
const cleanup = mountPushedConfigErrorOverlay(app);
try {
expect(appendChild).toHaveBeenCalledOnce();
expect(getProject).not.toHaveBeenCalled();
await Promise.resolve();
expect(getProject).toHaveBeenCalledOnce();
} finally {
cleanup();
}
});
});

View File

@ -528,7 +528,10 @@ export function mountPushedConfigErrorOverlay(app: StackClientApp<true>): () =>
});
};
refresh();
// This is mounted from the base client-app constructor, which also runs
// before subclass field initializers. Defer the first app call so overridden
// methods like adminApp.getProject() can safely touch subclass caches.
queueMicrotask(refresh);
const interval = setInterval(refresh, REFRESH_INTERVAL_MS);
const cleanup = () => {