import React from "react";
import { render, act, waitFor } from "@testing-library/react-native";
import { StaticFeedResolver } from "../resolvers/StaticFeedResolver";
import { View } from "react-native";
import { ReloadDataFunction } from "@applicaster/zapp-react-native-utils/reactHooks/feed/useFeedLoader";
type MockChildrenArgs = {
zappPipesData?: {
loading: boolean;
data?: any;
error?: Error | null;
};
reloadData?: ReloadDataFunction;
};
describe("StaticFeedResolver", () => {
const mockChildren = jest.fn((_args: MockChildrenArgs) => (
));
const mockComponent = {
id: "test-component",
position: 1,
} as any;
const mockGetStaticComponentFeed = jest.fn();
beforeEach(() => {
jest.clearAllMocks();
mockGetStaticComponentFeed.mockResolvedValue({ entry: [{ id: "1" }] });
});
it("should generate correct static URL based on component", () => {
render(
{mockChildren}
);
expect(mockChildren).toHaveBeenCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
url: "static://component?id=test-component&position=1",
}),
})
);
});
it("should start with loading state", () => {
render(
{mockChildren}
);
expect(mockChildren).toHaveBeenCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
loading: true,
data: null,
error: null,
}),
})
);
});
it("should fetch data when mounted", async () => {
render(
{mockChildren}
);
expect(mockGetStaticComponentFeed).toHaveBeenCalledWith({
index: 0,
component: mockComponent,
});
await waitFor(() => {
expect(mockChildren).toHaveBeenLastCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
loading: false,
data: { entry: [{ id: "1" }] },
}),
})
);
});
});
it("should handle errors from getStaticComponentFeed", async () => {
const error = new Error("Test error");
mockGetStaticComponentFeed.mockRejectedValue(error);
render(
{mockChildren}
);
await waitFor(() => {
expect(mockChildren).toHaveBeenLastCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
loading: false,
error,
}),
})
);
});
});
it("should provide a reloadData function that refreshes the data", async () => {
render(
{mockChildren}
);
await waitFor(() => {
expect(mockChildren).toHaveBeenLastCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
loading: false,
}),
})
);
});
const { reloadData } =
mockChildren.mock.calls[mockChildren.mock.calls.length - 1][0];
mockGetStaticComponentFeed.mockClear();
mockGetStaticComponentFeed.mockResolvedValue({ entry: [{ id: "2" }] });
await act(async () => {
await reloadData();
});
expect(mockGetStaticComponentFeed).toHaveBeenCalledWith({
index: 0,
component: mockComponent,
});
await waitFor(() => {
expect(mockChildren).toHaveBeenLastCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
data: { entry: [{ id: "2" }] },
}),
})
);
});
});
it("should handle errors in reloadData", async () => {
render(
{mockChildren}
);
await waitFor(() => {
expect(mockChildren).toHaveBeenLastCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
loading: false,
}),
})
);
});
const { reloadData } =
mockChildren.mock.calls[mockChildren.mock.calls.length - 1][0];
const error = new Error("Reload error");
mockGetStaticComponentFeed.mockRejectedValue(error);
await expect(reloadData()).rejects.toEqual(error);
await waitFor(() => {
expect(mockChildren).toHaveBeenLastCalledWith(
expect.objectContaining({
zappPipesData: expect.objectContaining({
error,
}),
})
);
});
});
it("should not fetch data if getStaticComponentFeed is not provided", async () => {
render(
{mockChildren}
);
expect(mockGetStaticComponentFeed).not.toHaveBeenCalled();
});
it("should provide reloadData function that resolves immediately if getStaticComponentFeed is not provided", async () => {
render(
{mockChildren}
);
const { reloadData } = mockChildren.mock.calls[0][0];
await expect(reloadData()).resolves.toBeUndefined();
});
});