UNPKG

tqf

Version:

React Query hooks for Firebase.

238 lines (190 loc) 6.16 kB
/* * Copyright (c) 2016-present Invertase Limited & Contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this library except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import * as React from "react"; import { renderHook, act } from "@testing-library/react-hooks"; import { collection, doc, DocumentReference, Firestore, getDoc, getDocs, setDoc, writeBatch, } from "firebase/firestore"; import { genId, init } from "./helpers"; import { useFirestoreCollectionMutation, useFirestoreDocumentDeletion, useFirestoreDocumentMutation, useFirestoreTransaction, useFirestoreWriteBatch, } from "../src"; import axios from "axios"; describe("useFirestoreMutation", () => { let wrapper: React.FC<{ children: React.ReactNode }>; let firestore: Firestore; beforeEach(async () => { const config = init(); await axios.delete( `http://localhost:8080/emulator/v1/projects/${config.projectId}/databases/(default)/documents` ); wrapper = config.wrapper; firestore = config.firestore; }); describe("useFirestoreCollectionMutation", () => { test("it adds a document", async () => { const ref = collection(firestore, "tests"); const { result, waitFor } = renderHook( () => useFirestoreCollectionMutation(ref), { wrapper, } ); act(() => { result.current.mutate({ foo: "bar" }); }); await waitFor(() => result.current.isSuccess, { timeout: 5000 }); const snapshot = await getDocs(ref); expect(snapshot.size).toBe(1); expect(snapshot.docs[0].data()).toEqual({ foo: "bar" }); }); }); describe("useFirestoreDocumentMutation", () => { test("it sets a document", async () => { const ref = doc(firestore, "tests", genId()); await setDoc(ref, { foo: "baz" }); const { result, waitFor } = renderHook( () => useFirestoreDocumentMutation(ref), { wrapper, } ); act(() => { result.current.mutate({ foo: "bar" }); }); await waitFor(() => result.current.isSuccess, { timeout: 5000 }); const snapshot = await getDoc(ref); expect(snapshot.data()).toEqual({ foo: "bar" }); }); test("it sets a document with merge", async () => { const ref = doc(firestore, "tests", genId()); await setDoc(ref, { foo: "baz" }); const { result, waitFor } = renderHook( () => useFirestoreDocumentMutation(ref, { merge: true }), { wrapper, } ); act(() => { result.current.mutate({ bar: "baz" }); }); await waitFor(() => result.current.isSuccess, { timeout: 5000 }); const snapshot = await getDoc(ref); expect(snapshot.data()).toEqual({ foo: "baz", bar: "baz" }); }); }); describe("useFirestoreDocumentDeletion", () => { it("deletes a document", async () => { const ref = doc(firestore, "tests", genId()); await setDoc(ref, { foo: "baz" }); const { result, waitFor } = renderHook( () => useFirestoreDocumentDeletion(ref), { wrapper, } ); act(() => { result.current.mutate(); }); await waitFor(() => result.current.isSuccess, { timeout: 5000 }); const snapshot = await getDoc(ref); expect(snapshot.exists()).toBe(false); }); }); describe("useFirestoreTransaction", () => { it("transacts a document", async () => { const ref = doc(firestore, "tests", genId()) as DocumentReference<Doc>; type Doc = { foo: number; }; await setDoc(ref, { foo: 10 }); const mock = jest.fn(); const { result, waitFor } = renderHook( () => useFirestoreTransaction<number>( firestore, async (tsx) => { const doc = await tsx.get(ref); const newValue = doc.data().foo + 1; tsx.update(ref, { foo: newValue }); return newValue; }, { onSuccess(value) { mock(value); }, } ), { wrapper, } ); act(() => { result.current.mutate(); }); await waitFor(() => result.current.isSuccess, { timeout: 5000 }); const snapshot = await getDoc(ref); expect(snapshot.data().foo).toBe(11); expect(mock.mock.calls[0][0]).toBe(11); expect(mock.mock.calls.length).toBe(1); }); }); describe("useFirestoreWriteBatch", () => { it("commits documents", async () => { const ref1 = doc(firestore, "tests", genId()); const ref2 = doc(firestore, "tests", genId()); const ref3 = doc(firestore, "tests", genId()); await Promise.all([ setDoc(ref1, { foo: "bar" }), setDoc(ref2, { foo: "bar" }), setDoc(ref3, { foo: "bar" }), ]); const batch = writeBatch(firestore); batch.set(ref1, { foo: "baz" }); batch.update(ref2, { bar: "baz" }); batch.delete(ref3); const { result, waitFor } = renderHook( () => useFirestoreWriteBatch(batch), { wrapper, } ); act(() => { result.current.mutate(); }); await waitFor(() => result.current.isSuccess, { timeout: 5000 }); const snapshot1 = await getDoc(ref1); expect(snapshot1.data().foo).toEqual("baz"); const snapshot2 = await getDoc(ref2); expect(snapshot2.data().foo).toEqual("bar"); expect(snapshot2.data().bar).toEqual("baz"); const snapshot3 = await getDoc(ref3); expect(snapshot3.exists()).toBe(false); }); }); });