Create with query wrapper
This commit is contained in:
parent
78d99da6df
commit
78d40f1abc
42
component/with-query-handling.tsx
Normal file
42
component/with-query-handling.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { useQuery, DocumentNode, OperationVariables } from "@apollo/client";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
/**
|
||||||
|
* A higher-order component that provides loading and error handling for GraphQL queries.
|
||||||
|
* @param {React.ComponentType} WrappedComponent - The component to wrap.
|
||||||
|
* @param {DocumentNode} query - The GraphQL query to execute.
|
||||||
|
* @param {string} dataKey - The key in the data object to pass to the wrapped component.
|
||||||
|
* @param {Object} queryOptions - Optional. Additional options for the Apollo query.
|
||||||
|
* @returns {React.ComponentType} A component that renders the WrappedComponent with loading and error handling.
|
||||||
|
*/
|
||||||
|
/* eslint-disable react/display-name */
|
||||||
|
type WithQueryHandlingProps = {
|
||||||
|
WrappedComponent: React.ComponentType<any>;
|
||||||
|
query: DocumentNode;
|
||||||
|
dataKey: string;
|
||||||
|
queryOptions?: OperationVariables;
|
||||||
|
};
|
||||||
|
|
||||||
|
function withQueryHandling({
|
||||||
|
WrappedComponent,
|
||||||
|
query,
|
||||||
|
dataKey,
|
||||||
|
queryOptions = {},
|
||||||
|
}: WithQueryHandlingProps) {
|
||||||
|
return function (props: any) {
|
||||||
|
// You can replace 'any' with specific props type if known
|
||||||
|
const { loading, error, data } = useQuery(query, queryOptions);
|
||||||
|
|
||||||
|
if (loading) {
|
||||||
|
return <Text>Loading...</Text>;
|
||||||
|
}
|
||||||
|
if (error) {
|
||||||
|
return <Text>Error: {error.message}</Text>;
|
||||||
|
}
|
||||||
|
|
||||||
|
const specificData = data[dataKey];
|
||||||
|
return <WrappedComponent {...props} data={specificData} />;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withQueryHandling;
|
65
test/component/with-query-handling.test.tsx
Normal file
65
test/component/with-query-handling.test.tsx
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
import React from "react";
|
||||||
|
import { render, cleanup, waitFor } from "@testing-library/react-native";
|
||||||
|
import "@testing-library/jest-native/extend-expect";
|
||||||
|
import { gql, useQuery } from "@apollo/client";
|
||||||
|
import withQueryHandling from "../../component/with-query-handling";
|
||||||
|
import { Text } from "react-native";
|
||||||
|
|
||||||
|
jest.mock("@apollo/client", () => ({
|
||||||
|
...jest.requireActual("@apollo/client"),
|
||||||
|
useQuery: jest.fn(),
|
||||||
|
}));
|
||||||
|
|
||||||
|
const MockComponent: React.FC<{ data?: string }> = ({ data }) => (
|
||||||
|
<Text>{data ? data : "No Data"}</Text>
|
||||||
|
);
|
||||||
|
|
||||||
|
const MOCK_QUERY = gql`
|
||||||
|
query GetMockData {
|
||||||
|
mockData {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
describe("withQueryHandling HOC Tests", () => {
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
cleanup();
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render loading state initially", async () => {
|
||||||
|
(useQuery as jest.Mock).mockReturnValue({
|
||||||
|
loading: true,
|
||||||
|
error: undefined,
|
||||||
|
data: undefined,
|
||||||
|
});
|
||||||
|
const WrappedComponent = withQueryHandling({
|
||||||
|
WrappedComponent: MockComponent,
|
||||||
|
query: MOCK_QUERY,
|
||||||
|
dataKey: "mockDataKey",
|
||||||
|
});
|
||||||
|
const { getByText } = render(<WrappedComponent />);
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(getByText("Loading...")).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should render the wrapped component with data", () => {
|
||||||
|
const mockData = { getShots: "shots" };
|
||||||
|
(useQuery as jest.Mock).mockReturnValue({
|
||||||
|
loading: false,
|
||||||
|
error: undefined,
|
||||||
|
data: mockData,
|
||||||
|
});
|
||||||
|
const WrappedComponent = withQueryHandling({
|
||||||
|
WrappedComponent: MockComponent,
|
||||||
|
query: MOCK_QUERY,
|
||||||
|
dataKey: "getShots",
|
||||||
|
});
|
||||||
|
const { getByText } = render(<WrappedComponent />);
|
||||||
|
expect(getByText("shots")).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user