From 62a99e686e8d84af6869bad2768f600b9214b6c7 Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Tue, 18 Feb 2025 12:15:59 +0300 Subject: [PATCH 1/2] feat(react/auth): add useFetchSignInMethodsForEmailQuery --- packages/react/src/auth/index.ts | 2 +- ...seFetchSignInMethodsForEmailQuery.test.tsx | 130 ++++++++++++++++++ .../useFetchSignInMethodsForEmailQuery.ts | 23 ++++ 3 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 packages/react/src/auth/useFetchSignInMethodsForEmailQuery.test.tsx create mode 100644 packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts diff --git a/packages/react/src/auth/index.ts b/packages/react/src/auth/index.ts index 2cfdb487..1f44b90d 100644 --- a/packages/react/src/auth/index.ts +++ b/packages/react/src/auth/index.ts @@ -15,7 +15,7 @@ export { useApplyActionCodeMutation } from "./useApplyActionCodeMutation"; // useCheckActionCodeMutation // useConfirmPasswordResetMutation export { useCreateUserWithEmailAndPasswordMutation } from "./useCreateUserWithEmailAndPasswordMutation"; -// useFetchSignInMethodsForEmailQuery +export { useFetchSignInMethodsForEmailQuery } from "./useFetchSignInMethodsForEmailQuery"; export { useConfirmPasswordResetMutation } from "./useConfirmPasswordResetMutation"; // useCreateUserWithEmailAndPasswordMutation // useGetRedirectResultQuery diff --git a/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.test.tsx b/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.test.tsx new file mode 100644 index 00000000..2b2a3ca1 --- /dev/null +++ b/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.test.tsx @@ -0,0 +1,130 @@ +import { renderHook, waitFor } from "@testing-library/react"; +import { createUserWithEmailAndPassword } from "firebase/auth"; +import { useFetchSignInMethodsForEmailQuery } from "./useFetchSignInMethodsForEmailQuery"; +import { describe, test, expect, vi, beforeEach, afterEach } from "vitest"; +import { auth, expectFirebaseError, wipeAuth } from "~/testing-utils"; +import { queryClient, wrapper } from "../../utils"; + +describe("useFetchSignInMethodsForEmailQuery", () => { + const email = "tqf@invertase.io"; + const password = "TanstackQueryFirebase#123"; + + beforeEach(async () => { + queryClient.clear(); + await wipeAuth(); + const userCredential = await createUserWithEmailAndPassword( + auth, + email, + password + ); + }); + + afterEach(async () => { + vi.clearAllMocks(); + await auth.signOut(); + }); + + test("should fetch sign in methods for existing user", async () => { + const { result } = renderHook( + () => + useFetchSignInMethodsForEmailQuery(auth, email, { + queryKey: ["signInMethods", email], + }), + { wrapper } + ); + + expect(result.current.isLoading).toBe(true); + + await waitFor(() => { + expect(result.current.isSuccess).toBe(true); + }); + + expect(result.current.data).toContain("password"); + }); + + test("should return empty array for non-existent user", async () => { + const nonExistentEmail = "nonexistent@example.com"; + + const { result } = renderHook( + () => + useFetchSignInMethodsForEmailQuery(auth, nonExistentEmail, { + queryKey: ["signInMethods", nonExistentEmail], + }), + { wrapper } + ); + + await waitFor(() => { + expect(result.current.isSuccess).toBe(true); + }); + + expect(result.current.data).toEqual([]); + }); + + test("should not fetch when enabled is false", () => { + const { result } = renderHook( + () => + useFetchSignInMethodsForEmailQuery(auth, email, { + queryKey: ["signInMethods", email], + enabled: false, + }), + { wrapper } + ); + + expect(result.current.isLoading).toBe(false); + expect(result.current.isSuccess).toBe(false); + expect(result.current.isError).toBe(false); + expect(result.current.data).toBeUndefined(); + }); + + test("should refetch when email changes", async () => { + const newEmail = "another@example.com"; + + await createUserWithEmailAndPassword(auth, newEmail, email); + + const { result, rerender } = renderHook( + ({ email }) => + useFetchSignInMethodsForEmailQuery(auth, email, { + queryKey: ["signInMethods", email], + }), + { + wrapper, + initialProps: { email: email }, + } + ); + + expect(result.current.isLoading).toBe(true); + + await waitFor(() => { + expect(result.current.isSuccess).toBe(true); + expect(result.current.isLoading).toBe(false); + }); + expect(result.current.data).toContain("password"); + + rerender({ email: newEmail }); + + expect(result.current.isLoading).toBe(true); + + await waitFor(() => { + expect(result.current.data).toContain("password"); + expect(result.current.isLoading).toBe(false); + }); + }); + + test("should handle invalid email error", async () => { + const invalidEmail = "not-an-email"; + + const { result } = renderHook( + () => + useFetchSignInMethodsForEmailQuery(auth, invalidEmail, { + queryKey: ["signInMethods", invalidEmail], + }), + { wrapper } + ); + + await waitFor(() => { + expect(result.current.isError).toBe(true); + }); + + expectFirebaseError(result.current.error, "auth/invalid-email"); + }); +}); diff --git a/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts b/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts new file mode 100644 index 00000000..2d3c1419 --- /dev/null +++ b/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts @@ -0,0 +1,23 @@ +import { type UseQueryOptions, useQuery } from "@tanstack/react-query"; +import { + fetchSignInMethodsForEmail, + type Auth, + type AuthError, +} from "firebase/auth"; + +type AuthUseQueryOptions< + TData = unknown, + TError = Error, + TVariables = void +> = Omit, "queryFn">; + +export function useFetchSignInMethodsForEmailQuery( + auth: Auth, + email: string, + options: AuthUseQueryOptions +) { + return useQuery({ + ...options, + queryFn: async () => fetchSignInMethodsForEmail(auth, email), + }); +} From 555bdd57df912b0b3e7e2dd76c2af6be768a5f8e Mon Sep 17 00:00:00 2001 From: HassanBahati Date: Tue, 18 Feb 2025 15:40:50 +0300 Subject: [PATCH 2/2] _ --- packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts b/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts index 2d3c1419..a1d09019 100644 --- a/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts +++ b/packages/react/src/auth/useFetchSignInMethodsForEmailQuery.ts @@ -18,6 +18,6 @@ export function useFetchSignInMethodsForEmailQuery( ) { return useQuery({ ...options, - queryFn: async () => fetchSignInMethodsForEmail(auth, email), + queryFn: () => fetchSignInMethodsForEmail(auth, email), }); }