@ledgerhq/live-common
Version:
Common ground for the Ledger Live apps
201 lines (173 loc) • 5.88 kB
text/typescript
/**
* @jest-environment jsdom
*/
import { renderHook } from "@testing-library/react";
import { useAssetsData } from "../useAssetsData";
import { useGetAssetsDataInfiniteQuery } from "../../state-manager/api";
jest.mock("../../state-manager/api", () => ({
useGetAssetsDataInfiniteQuery: jest.fn(),
}));
const mockuseGetAssetsDataInfiniteQuery = jest.mocked(useGetAssetsDataInfiniteQuery);
const defaultMockValues = {
data: undefined,
isLoading: false,
error: undefined,
fetchNextPage: jest.fn(),
isSuccess: true,
isFetching: false,
isError: false,
fetchPreviousPage: jest.fn(),
isFetchingPreviousPage: false,
refetch: jest.fn(),
status: "success",
};
describe("useAssetsData", () => {
beforeEach(() => {
jest.clearAllMocks();
});
it("should return loading state when API is loading", () => {
mockuseGetAssetsDataInfiniteQuery.mockReturnValue({
...defaultMockValues,
isLoading: true,
status: "pending",
});
const { result } = renderHook(() => useAssetsData({ product: "lld", version: "1.0.0" }));
expect(result.current.isLoading).toBe(true);
expect(result.current.data).toBe(undefined);
});
it("should return combined data from multiple pages", () => {
const mockPages = [
{
cryptoAssets: { bitcoin: { id: "bitcoin", name: "Bitcoin" } },
networks: { bitcoin: { id: "bitcoin", name: "Bitcoin" } },
cryptoOrTokenCurrencies: { bitcoin: { id: "bitcoin" } },
interestRates: {},
markets: {},
currenciesOrder: {
currenciesIds: ["bitcoin"],
metaCurrencyIds: ["bitcoin"],
key: "marketCap",
order: "desc",
},
pagination: { nextCursor: "cursor-2" },
},
{
cryptoAssets: { ethereum: { id: "ethereum", name: "Ethereum" } },
networks: { ethereum: { id: "ethereum", name: "Ethereum" } },
cryptoOrTokenCurrencies: { ethereum: { id: "ethereum" } },
interestRates: {},
markets: {},
currenciesOrder: {
currenciesIds: ["ethereum"],
metaCurrencyIds: ["ethereum"],
key: "marketCap",
order: "desc",
},
pagination: { nextCursor: undefined },
},
];
mockuseGetAssetsDataInfiniteQuery.mockReturnValue({
...defaultMockValues,
data: { pages: mockPages, pageParams: [{ cursor: "" }, { cursor: "cursor-2" }] },
});
const { result } = renderHook(() => useAssetsData({ product: "lld", version: "1.0.0" }));
expect(result.current.data).toEqual({
cryptoAssets: {
bitcoin: { id: "bitcoin", name: "Bitcoin" },
ethereum: { id: "ethereum", name: "Ethereum" },
},
networks: {
bitcoin: { id: "bitcoin", name: "Bitcoin" },
ethereum: { id: "ethereum", name: "Ethereum" },
},
cryptoOrTokenCurrencies: {
bitcoin: { id: "bitcoin" },
ethereum: { id: "ethereum" },
},
interestRates: {},
markets: {},
currenciesOrder: {
currenciesIds: ["bitcoin", "ethereum"],
metaCurrencyIds: ["bitcoin", "ethereum"],
key: "marketCap",
order: "desc",
},
pagination: { nextCursor: undefined },
});
expect(result.current.isLoading).toBe(false);
});
it("should return error when API has error", () => {
const mockError = new Error("API Error");
mockuseGetAssetsDataInfiniteQuery.mockReturnValue({
...defaultMockValues,
data: undefined,
error: mockError,
isSuccess: false,
isError: true,
status: "error",
});
const { result } = renderHook(() => useAssetsData({ product: "lld", version: "1.0.0" }));
expect(result.current.error).toBe(mockError);
expect(result.current.isLoading).toBe(false);
});
it("should provide loadNext function when there's a nextCursor", () => {
const mockFetchNextPage = jest.fn();
const mockPages = [
{
cryptoAssets: {},
networks: {},
cryptoOrTokenCurrencies: {},
interestRates: {},
markets: {},
currenciesOrder: {
currenciesIds: [],
metaCurrencyIds: [],
key: "marketCap",
order: "desc",
},
pagination: { nextCursor: "next-cursor-456" },
},
];
mockuseGetAssetsDataInfiniteQuery.mockReturnValue({
...defaultMockValues,
data: { pages: mockPages, pageParams: [{ cursor: "" }] },
fetchNextPage: mockFetchNextPage,
});
const { result } = renderHook(() => useAssetsData({ product: "lld", version: "1.0.0" }));
expect(result.current.loadNext).toBeDefined();
result.current.loadNext?.();
expect(mockFetchNextPage).toHaveBeenCalled();
});
it("should not provide loadNext function when there's no nextCursor", () => {
const mockPages = [
{
cryptoAssets: {},
networks: {},
cryptoOrTokenCurrencies: {},
interestRates: {},
markets: {},
currenciesOrder: {
currenciesIds: [],
metaCurrencyIds: [],
key: "marketCap",
order: "desc",
},
pagination: { nextCursor: undefined },
},
];
mockuseGetAssetsDataInfiniteQuery.mockReturnValue({
...defaultMockValues,
data: { pages: mockPages, pageParams: [{ cursor: "" }] },
});
const { result } = renderHook(() => useAssetsData({ product: "lld", version: "1.0.0" }));
expect(result.current.loadNext).toBeUndefined();
});
it("should return undefined data when no pages exist", () => {
mockuseGetAssetsDataInfiniteQuery.mockReturnValue({
...defaultMockValues,
});
const { result } = renderHook(() => useAssetsData({ product: "lld", version: "1.0.0" }));
expect(result.current.data).toBeUndefined();
expect(result.current.loadNext).toBeUndefined();
});
});