|
|
@ -0,0 +1,77 @@ |
|
|
|
|
|
import { render, waitFor } from "@testing-library/react"; |
|
|
|
|
|
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; |
|
|
|
|
|
import { describe, expect, it, vi, beforeEach } from "vitest"; |
|
|
|
|
|
import AuthDataBoundary from "./auth-data-boundary"; |
|
|
|
|
|
import { marriageQueryKeys } from "@/hooks/marriage/query-keys"; |
|
|
|
|
|
import { HABIB_AUTH_TOKEN_CHANGED_EVENT } from "@/lib/auth-bridge"; |
|
|
|
|
|
|
|
|
|
|
|
describe("AuthDataBoundary", () => { |
|
|
|
|
|
let queryClient: QueryClient; |
|
|
|
|
|
|
|
|
|
|
|
beforeEach(() => { |
|
|
|
|
|
window.localStorage.clear(); |
|
|
|
|
|
queryClient = new QueryClient({ |
|
|
|
|
|
defaultOptions: { |
|
|
|
|
|
queries: { retry: false }, |
|
|
|
|
|
}, |
|
|
|
|
|
}); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("purges user-specific caches on habib:auth-token-changed while preserving config", async () => { |
|
|
|
|
|
// Populate query cache with user data + config
|
|
|
|
|
|
queryClient.setQueryData(marriageQueryKeys.profile(), { id: 100, can_edit_profile: true }); |
|
|
|
|
|
queryClient.setQueryData(marriageQueryKeys.formOverview("profile", "en"), { form_id: "profile", sections: [] }); |
|
|
|
|
|
queryClient.setQueryData(marriageQueryKeys.formSection("profile", "job", "en"), { form_id: "profile", section: { id: "job" } }); |
|
|
|
|
|
queryClient.setQueryData(marriageQueryKeys.cattellQuestions("en"), { questions: [] }); |
|
|
|
|
|
queryClient.setQueryData(marriageQueryKeys.glasserQuestions("en"), { questions: [] }); |
|
|
|
|
|
queryClient.setQueryData(marriageQueryKeys.config(), { min_age: 18 }); |
|
|
|
|
|
|
|
|
|
|
|
render( |
|
|
|
|
|
<QueryClientProvider client={queryClient}> |
|
|
|
|
|
<AuthDataBoundary> |
|
|
|
|
|
<div data-testid="child">Child Content</div> |
|
|
|
|
|
</AuthDataBoundary> |
|
|
|
|
|
</QueryClientProvider>, |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
// Verify initial cached data is present
|
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.profile())).toBeDefined(); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.formOverview("profile", "en"))).toBeDefined(); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.formSection("profile", "job", "en"))).toBeDefined(); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.cattellQuestions("en"))).toBeDefined(); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.config())).toBeDefined(); |
|
|
|
|
|
|
|
|
|
|
|
// Fire auth identity change (e.g. Account A logs out or switches to Account B)
|
|
|
|
|
|
window.dispatchEvent(new CustomEvent(HABIB_AUTH_TOKEN_CHANGED_EVENT, { detail: { token: "new-token" } })); |
|
|
|
|
|
|
|
|
|
|
|
// All user-owned queries should be removed from the cache
|
|
|
|
|
|
await waitFor(() => { |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.profile())).toBeUndefined(); |
|
|
|
|
|
}); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.formOverview("profile", "en"))).toBeUndefined(); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.formSection("profile", "job", "en"))).toBeUndefined(); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.cattellQuestions("en"))).toBeUndefined(); |
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.glasserQuestions("en"))).toBeUndefined(); |
|
|
|
|
|
|
|
|
|
|
|
// Config query MUST be preserved (public/global)
|
|
|
|
|
|
expect(queryClient.getQueryData(marriageQueryKeys.config())).toEqual({ min_age: 18 }); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
it("runs legacy V3 migration once on mount", async () => { |
|
|
|
|
|
window.localStorage.setItem("marriage:sections:old_slug:answers:v2", JSON.stringify({ pending_sync: true })); |
|
|
|
|
|
expect(window.localStorage.getItem("marriage:storage-migration:v3")).toBeNull(); |
|
|
|
|
|
|
|
|
|
|
|
render( |
|
|
|
|
|
<QueryClientProvider client={queryClient}> |
|
|
|
|
|
<AuthDataBoundary> |
|
|
|
|
|
<div>Mounted</div> |
|
|
|
|
|
</AuthDataBoundary> |
|
|
|
|
|
</QueryClientProvider>, |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
|
|
await waitFor(() => { |
|
|
|
|
|
expect(window.localStorage.getItem("marriage:storage-migration:v3")).toBe("done"); |
|
|
|
|
|
}); |
|
|
|
|
|
expect(window.localStorage.getItem("marriage:sections:old_slug:answers:v2")).toBeNull(); |
|
|
|
|
|
}); |
|
|
|
|
|
}); |