Skip to content

Commit

Permalink
Merge pull request #108 from HassanBahati/ft-add-useWriteBatchCommitM…
Browse files Browse the repository at this point in the history
…utation
  • Loading branch information
Ehesp authored Oct 10, 2024
2 parents 6309453 + 4d1704c commit 8a9daa1
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/react/src/firestore/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export { useDisableNetworkMutation } from "./useDisableNetworkMutation";
// useEnableNetworkMutation
export { useWaitForPendingWritesQuery } from "./useWaitForPendingWritesQuery";
export { useRunTransactionMutation } from "./useRunTransactionMutation";
// useWriteBatchCommitMutation (WriteBatch)
export { useWriteBatchCommitMutation } from "./useWriteBatchCommitMutation";
export { useDocumentQuery } from "./useDocumentQuery";
export { useCollectionQuery } from "./useCollectionQuery";
export { useGetAggregateFromServerQuery } from "./useGetAggregateFromServerQuery";
Expand Down
120 changes: 120 additions & 0 deletions packages/react/src/firestore/useWriteBatchCommitMutation.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import React from "react";
import { describe, expect, test, beforeEach } from "vitest";
import { renderHook, act, waitFor } from "@testing-library/react";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { firestore, wipeFirestore } from "~/testing-utils";
import { useWriteBatchCommitMutation } from "./useWriteBatchCommitMutation";
import { doc, getDoc, setDoc, writeBatch } from "firebase/firestore";

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

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

describe("useWriteBatchCommitMutation", () => {
beforeEach(async () => {
queryClient.clear();
await wipeFirestore();
});

test("successfully creates and commits a write batch", async () => {
const docRef1 = doc(firestore, "tests", "doc1");
const docRef2 = doc(firestore, "tests", "doc2");

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

await act(async () => {
const batch = writeBatch(firestore);
batch.set(docRef1, { value: "test1" });
batch.set(docRef2, { value: "test2" });
await result.current.mutate(batch);
});

const doc1Snapshot = await getDoc(docRef1);
const doc2Snapshot = await getDoc(docRef2);

await waitFor(async () => {
expect(doc1Snapshot.exists()).toBe(true);
expect(doc2Snapshot.exists()).toBe(true);

expect(doc1Snapshot.data()).toEqual({ value: "test1" });
expect(doc2Snapshot.data()).toEqual({ value: "test2" });
});
});

test("handles multiple operations in a single batch", async () => {
const docRef1 = doc(firestore, "tests", "doc1");
const docRef2 = doc(firestore, "tests", "doc2");
const docRef3 = doc(firestore, "tests", "doc3");

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

await setDoc(docRef1, { value: "initial1" });
await setDoc(docRef2, { value: "initial2" });

await act(async () => {
const batch = writeBatch(firestore);
batch.update(docRef1, { value: "updated1" });
batch.update(docRef1, { value: "updated1" });
batch.delete(docRef2);
batch.set(docRef3, { value: "new3" });
await result.current.mutate(batch);
});

const doc1Snapshot = await getDoc(docRef1);
const doc2Snapshot = await getDoc(docRef2);
const doc3Snapshot = await getDoc(docRef3);

await waitFor(async () => {
expect(doc1Snapshot.data()).toEqual({ value: "updated1" });
expect(doc2Snapshot.exists()).toBe(false);
expect(doc3Snapshot.data()).toEqual({ value: "new3" });
});
});

test("successfully creates and commits a write batch with nested fields", async () => {
const docRef1 = doc(firestore, "tests", "doc1");
const docRef2 = doc(firestore, "tests", "doc2");

await setDoc(docRef1, {
fieldToUpdate: { nestedField: "value" },
});

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

await act(async () => {
const batch = writeBatch(firestore);

batch.set(docRef2, { value: "test2" });
batch.update(docRef1, { "fieldToUpdate.nestedField": "newValue" });
await result.current.mutate(batch);
});

const doc1Snapshot = await getDoc(docRef1);
const doc2Snapshot = await getDoc(docRef2);

await waitFor(async () => {
expect(doc1Snapshot.exists()).toBe(true);
expect(doc2Snapshot.exists()).toBe(true);

expect(doc1Snapshot.data()).toEqual({
fieldToUpdate: { nestedField: "newValue" },
});
expect(doc2Snapshot.data()).toEqual({
value: "test2",
});
});
});
});
16 changes: 16 additions & 0 deletions packages/react/src/firestore/useWriteBatchCommitMutation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useMutation, type UseMutationOptions } from "@tanstack/react-query";
import { type FirestoreError, type WriteBatch } from "firebase/firestore";

type FirestoreUseMutationOptions<TError = Error> = Omit<
UseMutationOptions<void, TError, WriteBatch>,
"mutationFn"
>;

export function useWriteBatchCommitMutation(
options?: FirestoreUseMutationOptions<FirestoreError>
) {
return useMutation<void, FirestoreError, WriteBatch>({
...options,
mutationFn: (batch: WriteBatch) => batch.commit(),
});
}

0 comments on commit 8a9daa1

Please sign in to comment.