- Add markOnboardingCompleted() to set completedAt timestamp when user finishes onboarding - Add isOnboardingCompleted() to check if onboarding was completed (vs dismissed) - Update ModelOnboardingModal to call markOnboardingCompleted on successful completion - Skip onboarding auto-open when already completed locally - Add completion state tracking tests in ModelOnboardingModal.test.tsx - Add model-onboarding-state unit tests - Update useAuthOnboarding to check local completion state before auto-opening - Document localStorage completion state tracking pattern in .fusion/memory.md
61 lines
1.5 KiB
TypeScript
61 lines
1.5 KiB
TypeScript
import { vi } from "vitest";
|
|
|
|
// Extend localStorage mock for multi-project tests
|
|
const localStorageMock: Record<string, string> = {};
|
|
|
|
if (typeof window !== "undefined") {
|
|
Object.defineProperty(window, "localStorage", {
|
|
value: {
|
|
getItem: (key: string) => localStorageMock[key] || null,
|
|
setItem: (key: string, value: string) => {
|
|
localStorageMock[key] = value;
|
|
},
|
|
removeItem: (key: string) => {
|
|
delete localStorageMock[key];
|
|
},
|
|
clear: () => {
|
|
Object.keys(localStorageMock).forEach((key) => delete localStorageMock[key]);
|
|
},
|
|
},
|
|
writable: true,
|
|
});
|
|
}
|
|
|
|
// Mock fetch for project API tests
|
|
const originalFetch = globalThis.fetch;
|
|
|
|
globalThis.fetch = vi.fn(async (url: RequestInfo | URL) => {
|
|
const urlString = url.toString();
|
|
|
|
// Mock project API responses
|
|
if (urlString.includes("/api/projects")) {
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => [],
|
|
text: async () => "[]",
|
|
headers: new Headers({ "content-type": "application/json" }),
|
|
} as Response;
|
|
}
|
|
|
|
// Default: return empty successful response
|
|
return {
|
|
ok: true,
|
|
status: 200,
|
|
json: async () => ({}),
|
|
text: async () => "{}",
|
|
headers: new Headers({ "content-type": "application/json" }),
|
|
} as Response;
|
|
}) as typeof fetch;
|
|
|
|
// Cleanup
|
|
afterEach(() => {
|
|
// Clear localStorage mock
|
|
Object.keys(localStorageMock).forEach((key) => delete localStorageMock[key]);
|
|
|
|
// Reset fetch mock
|
|
vi.mocked(globalThis.fetch).mockClear();
|
|
});
|
|
|
|
export { localStorageMock };
|