tqf
Version:
React Query hooks for Firebase.
222 lines (174 loc) • 5.25 kB
text/typescript
import React from "react";
import { QueryClient } from "@tanstack/react-query";
import { renderHook } from "@testing-library/react-hooks";
import { Functions } from "firebase/functions";
import { genId, init } from "./helpers";
import { useFunctionsCall, useFunctionsQuery } from "../src";
import { act } from "react-test-renderer";
describe("Authentication", () => {
let client: QueryClient;
let wrapper: React.FC<{ children: React.ReactNode }>;
let functions: Functions;
beforeEach(() => {
const config = init();
client = config.client;
wrapper = config.wrapper;
functions = config.functions;
});
afterEach(async () => {
client.clear();
});
describe("useFunctionsQuery", () => {
// seems to run fine on its own but fails when run in all tests
test.skip("it returns a valid response", async () => {
const hookId = genId();
const { result, waitFor } = renderHook(
() => useFunctionsQuery(hookId, functions, "test"),
{
wrapper,
}
);
await waitFor(() => result.current.isSuccess);
expect(result.current.data).toEqual({ response: null });
});
test("it accepts data", async () => {
const hookId = genId();
const foo = {
bar: "baz",
};
const { result, waitFor } = renderHook(
() => useFunctionsQuery(hookId, functions, "test", foo),
{
wrapper,
}
);
await waitFor(() => result.current.isSuccess);
expect(result.current.data).toEqual({ response: foo });
});
test("it throw on invalid trigger", async () => {
const hookId = genId();
const { result, waitFor } = renderHook(
() => useFunctionsQuery(hookId, functions, "foo"),
{
wrapper,
}
);
await waitFor(() => result.current.isError);
expect(result.current.error).toBeDefined();
});
test("it requeries on key change", async () => {
const hookId1 = genId();
const hookId2 = genId();
const data1 = { foo: "bar" };
const data2 = { bar: "baz" };
const { result, waitFor, rerender } = renderHook<
{
id: string;
data: any;
},
any
>(({ id, data }) => useFunctionsQuery(id, functions, "test", data), {
wrapper: (props) => wrapper({ children: props.children }),
initialProps: {
id: hookId1,
data: data1,
},
});
await waitFor(() => result.current.isSuccess);
expect(result.current.data).toEqual({ response: data1 });
rerender({ id: hookId2, data: data2 });
await waitFor(() => result.current.isSuccess);
expect(result.current.data).toEqual({ response: data2 });
});
test("it handles specific types", async () => {
const hookId = genId();
type RequestData = {
foo: string;
};
type ResponseData = {
response: RequestData;
};
const foo: RequestData = {
foo: "bar",
};
const { result, waitFor } = renderHook(
() =>
useFunctionsQuery<RequestData, ResponseData>(
hookId,
functions,
"test",
foo
),
{
wrapper,
}
);
await waitFor(() => result.current.isSuccess);
expect(result.current.data.response.foo).toEqual("bar");
// @ts-expect-error
expect(result.current.data.response.bar).toBeUndefined();
});
test("it handles custom return type", async () => {
const hookId = genId();
type RequestData = {
foo: string;
};
type ResponseData = {
response: RequestData;
};
const foo: RequestData = {
foo: "bar",
};
const { result, waitFor } = renderHook(
() =>
useFunctionsQuery<RequestData, ResponseData, string>(
hookId,
functions,
"test",
foo,
undefined,
{
select(data) {
return data.response.foo;
},
}
),
{
wrapper,
}
);
await waitFor(() => result.current.isSuccess);
expect(result.current.data).toEqual("bar");
});
});
describe("useFunctionsCall", () => {
test("it calls the function", async () => {
const mock = jest.fn();
const { result, waitFor } = renderHook(
() =>
useFunctionsCall(functions, "test", undefined, {
onSuccess(data) {
mock(data);
},
}),
{ wrapper }
);
act(() => {
result.current.mutate(123);
});
await waitFor(() => result.current.isSuccess, { timeout: 5000 });
expect(mock.mock.calls[0][0]).toEqual({ response: 123 });
});
test("it throws when calling a bad function", async () => {
const { result, waitFor } = renderHook(
() => useFunctionsCall(functions, "foo"),
{ wrapper }
);
act(() => {
result.current.mutate(123);
});
await waitFor(() => result.current.isError);
expect(result.current.error).toBeDefined();
});
});
});