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(); }); });