Skip to content

Commit

Permalink
Merge branch 'next' into ft-add-useConnectQuery
Browse files Browse the repository at this point in the history
  • Loading branch information
HassanBahati committed Dec 6, 2024
2 parents 91a7e9f + b424dd1 commit a1a3811
Show file tree
Hide file tree
Showing 19 changed files with 1,256 additions and 4 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
"@vitest/coverage-istanbul": "^2.0.5",
"firebase": "^10.14.1",
"happy-dom": "^15.7.3",
"@types/jsonwebtoken": "^9.0.7",
"jsonwebtoken": "^9.0.2",
"react": "^18.3.1",
"tsup": "^8.2.4",
"typescript": "^5.6.2",
Expand Down
12 changes: 8 additions & 4 deletions packages/react/src/auth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,22 @@
// useSendPasswordResetEmailMutation
export { useSendSignInLinkToEmailMutation } from "./useSendSignInLinkToEmailMutation";
export { useSignInAnonymouslyMutation } from "./useSignInAnonymouslyMutation";
// useSignInWithCredentialMutation
export { useSignInWithCredentialMutation } from "./useSignInWithCredentialMutation";
// useSignInWithCustomTokenMutation
// useSignInWithEmailAndPasswordMutation
export { useSignInWithEmailAndPasswordMutation } from "./useSignInWithEmailAndPasswordMutation";
// useSignInWithEmailLinkMutation
// useSignInWithPhoneNumberMutation
// useSignInWithPopupMutation
// useSignInWithRedirectMutation
// useSignOutMutation
export { useSignOutMutation } from "./useSignOutMutation";
// useUpdateCurrentUserMutation
// useSignOutMutation
export { useUpdateCurrentUserMutation } from "./useUpdateCurrentUserMutation";
// useValidatePasswordMutation
// useVerifyPasswordResetCodeMutation
export { useVerifyPasswordResetCodeMutation } from "./useVerifyPasswordResetCodeMutation";
// useDeleteUserMutation
export { useDeleteUserMutation } from "./useDeleteUserMutation";
// useLinkWithCredentialMutation
// useLinkWithPhoneNumberMutation
// useLinkWithPopupMutation
Expand All @@ -39,7 +43,7 @@ export { useSignInAnonymouslyMutation } from "./useSignInAnonymouslyMutation";
// useReauthenticateWithCredentialMutation
// useReauthenticateWithPopupMutation
// useReauthenticateWithRedirectMutation
// useReloadMutation
export { useReloadMutation } from "./useReloadMutation";
// useSendEmailVerificationMutation
// useUnlinkMutation
// useUpdateEmailMutation
Expand Down
101 changes: 101 additions & 0 deletions packages/react/src/auth/useDeleteUserMutation.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from "react";
import { describe, expect, test, beforeEach, afterEach, vi } from "vitest";
import { renderHook, act, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { auth, wipeAuth } from "~/testing-utils";
import { createUserWithEmailAndPassword, type User } from "firebase/auth";
import { useDeleteUserMutation } from "./useDeleteUserMutation";

const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
});

const wrapper = ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe("useVerifyPasswordResetCodeMutation", () => {
const email = "[email protected]";
const password = "TanstackQueryFirebase#123";
let user: User;

beforeEach(async () => {
queryClient.clear();
await wipeAuth();
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
user = userCredential.user;
});

afterEach(async () => {
vi.clearAllMocks();
await auth.signOut();
});

test("successfully verifies the reset code", async () => {
const { result } = renderHook(() => useDeleteUserMutation(auth), {
wrapper,
});

await act(async () => {
result.current.mutate(user);
});

await waitFor(() => expect(result.current.isSuccess).toBe(true));

expect(result.current.data).toBeUndefined();
});

test("resets mutation state correctly", async () => {
const { result } = renderHook(() => useDeleteUserMutation(auth), {
wrapper,
});

act(() => {
result.current.mutate(user);
});

await waitFor(() => {
expect(result.current.isSuccess).toBe(true);
});

act(() => {
result.current.reset();
});

await waitFor(() => {
expect(result.current.isIdle).toBe(true);
expect(result.current.data).toBeUndefined();
expect(result.current.error).toBeNull();
});
});

test("should call onSuccess when the user is successfully deleted", async () => {
const onSuccess = vi.fn();

const { result } = renderHook(
() =>
useDeleteUserMutation(auth, {
onSuccess,
}),
{
wrapper,
}
);

act(() => {
result.current.mutate(user);
});

await waitFor(() => expect(result.current.isSuccess).toBe(true));

expect(onSuccess).toHaveBeenCalledTimes(1);
expect(result.current.data).toBeUndefined();
});
});
18 changes: 18 additions & 0 deletions packages/react/src/auth/useDeleteUserMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { useMutation, type UseMutationOptions } from "@tanstack/react-query";
import { Auth, type AuthError, deleteUser, type User } from "firebase/auth";

type AuthUMutationOptions<
TData = unknown,
TError = Error,
TVariables = void
> = Omit<UseMutationOptions<TData, TError, TVariables>, "mutationFn">;

export function useDeleteUserMutation(
auth: Auth,
options?: AuthUMutationOptions<void, AuthError, User>
) {
return useMutation<void, AuthError, User>({
...options,
mutationFn: (user: User) => deleteUser(user),
});
}
70 changes: 70 additions & 0 deletions packages/react/src/auth/useReloadMutation.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from "react";
import { describe, expect, test, beforeEach, afterEach, vi } from "vitest";
import { renderHook, act, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { auth, wipeAuth } from "~/testing-utils";
import {
createUserWithEmailAndPassword,
signInWithEmailAndPassword,
type User,
} from "firebase/auth";
import { useReloadMutation } from "./useReloadMutation";

const queryClient = new QueryClient({
defaultOptions: {
queries: { retry: false },
mutations: { retry: false },
},
});

const wrapper = ({ children }: { children: React.ReactNode }) => (
<QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
);

describe("useReloadMutation", () => {
const email = "[email protected]";
const password = "TanstackQueryFirebase#123";
let user: User;
beforeEach(async () => {
queryClient.clear();
await wipeAuth();
const userCredential = await createUserWithEmailAndPassword(
auth,
email,
password
);
user = userCredential.user;
});

afterEach(async () => {
vi.clearAllMocks();
await auth.signOut();
});

test.sequential("should successfully reloads user data", async () => {
await signInWithEmailAndPassword(auth, email, password);

const { result } = renderHook(() => useReloadMutation(), { wrapper });

act(() => result.current.mutate(user));

await waitFor(() => expect(result.current.isSuccess).toBe(true));
});

test("should handle onSuccess callback", async () => {
await signInWithEmailAndPassword(auth, email, password);

const onSuccess = vi.fn();
const { result } = renderHook(() => useReloadMutation({ onSuccess }), {
wrapper,
});

act(() => {
result.current.mutate(user);
});

await waitFor(() => expect(result.current.isSuccess).toBe(true));

expect(onSuccess).toHaveBeenCalled();
});
});
17 changes: 17 additions & 0 deletions packages/react/src/auth/useReloadMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { useMutation, type UseMutationOptions } from "@tanstack/react-query";
import { AuthError, reload, type User } from "firebase/auth";

type AuthMutationOptions<
TData = unknown,
TError = Error,
TVariables = void
> = Omit<UseMutationOptions<TData, TError, TVariables>, "mutationFn">;

export function useReloadMutation(
options?: AuthMutationOptions<void, AuthError, User>
) {
return useMutation<void, AuthError, User>({
...options,
mutationFn: (user: User) => reload(user),
});
}
Loading

0 comments on commit a1a3811

Please sign in to comment.