Skip to content

Commit

Permalink
Basic tests of passing an options function to useQuery.
Browse files Browse the repository at this point in the history
  • Loading branch information
benjamn committed Mar 2, 2022
1 parent 18a8f7e commit 803d110
Showing 1 changed file with 226 additions and 0 deletions.
226 changes: 226 additions & 0 deletions src/react/hooks/__tests__/useQuery.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -761,6 +761,232 @@ describe('useQuery Hook', () => {
});
});

describe("options functions", () => {
it("can provide a default fetchPolicy", async () => {
const query = gql`query { hello }`;
const link = mockSingleLink(
{
request: { query },
result: { data: { hello: 'from link' } },
},
);

const client = new ApolloClient({
link,
cache: new InMemoryCache(),
ssrMode: true,
});

const fetchPolicyLog: Array<{
oldFetchPolicy: string | undefined;
newFetchPolicy: string;
}> = [];

let defaultFetchPolicy: WatchQueryFetchPolicy = "cache-and-network";

const { result, waitForNextUpdate } = renderHook(
() => useQuery(query, oldOptions => {
const {
fetchPolicy = defaultFetchPolicy,
} = oldOptions;

const newOptions = {
fetchPolicy,
};

fetchPolicyLog.push({
oldFetchPolicy: oldOptions.fetchPolicy,
newFetchPolicy: newOptions.fetchPolicy,
});

return newOptions;
}),
{
wrapper: ({ children }) => (
<ApolloProvider client={client}>
{children}
</ApolloProvider>
),
}
);

expect(result.current.loading).toBe(true);
expect(result.current.data).toBeUndefined();
expect(fetchPolicyLog).toEqual([
{
oldFetchPolicy: void 0,
newFetchPolicy: "cache-and-network",
},
]);

// Change the default fetchPolicy to verify that it is not used the second
// time useQuery is called.
defaultFetchPolicy = "network-only";

await waitForNextUpdate();

expect(result.current.loading).toBe(false);
expect(result.current.data).toEqual({ hello: 'from link' });
expect(fetchPolicyLog).toEqual([
{
oldFetchPolicy: void 0,
newFetchPolicy: "cache-and-network",
},
{
oldFetchPolicy: "cache-and-network",
newFetchPolicy: "cache-and-network",
},
]);
});

it("can mutate old options object directly", async () => {
const query = gql`query { hello }`;
const link = mockSingleLink(
{
request: { query },
result: { data: { hello: 'from link' } },
},
);

const client = new ApolloClient({
link,
cache: new InMemoryCache(),
ssrMode: true,
});

const fetchPolicyLog: WatchQueryFetchPolicy[] = [];
let defaultFetchPolicy: WatchQueryFetchPolicy = "network-only";

const { result, waitForNextUpdate } = renderHook(
() => useQuery(query, options => {
if (!options.fetchPolicy) {
options.fetchPolicy = defaultFetchPolicy;
}
fetchPolicyLog.push(options.fetchPolicy);
return options;
}),
{
wrapper: ({ children }) => (
<ApolloProvider client={client}>
{children}
</ApolloProvider>
),
}
);

expect(result.current.loading).toBe(true);
expect(result.current.data).toBeUndefined();
expect(fetchPolicyLog).toEqual([
"network-only",
]);

// Change the default fetchPolicy to verify that it is not used the second
// time useQuery is called.
defaultFetchPolicy = "cache-first";

await waitForNextUpdate();

expect(result.current.loading).toBe(false);
expect(result.current.data).toEqual({ hello: 'from link' });
expect(fetchPolicyLog).toEqual([
"network-only",
"network-only",
]);
});

it("can provide options.client without ApolloProvider", async () => {
const query = gql`query { hello }`;
const link = mockSingleLink(
{
request: { query },
result: { data: { hello: 'from link' } },
},
);

const client = new ApolloClient({
link,
cache: new InMemoryCache(),
ssrMode: true,
});

const { result, waitForNextUpdate } = renderHook(
() => useQuery(query, () => ({ client })),
// We deliberately do not provide the usual ApolloProvider wrapper for
// this test, since we are providing the client directly to useQuery.
// {
// wrapper: ({ children }) => (
// <ApolloProvider client={client}>
// {children}
// </ApolloProvider>
// ),
// }
);

expect(result.current.loading).toBe(true);
expect(result.current.data).toBeUndefined();

await waitForNextUpdate();

expect(result.current.loading).toBe(false);
expect(result.current.data).toEqual({ hello: 'from link' });
});

it("leaves options unchanged if omitted from returned object", async () => {
const query = gql`query { hello }`;
const defaultVariables = {
first: true,
};
const link = mockSingleLink(
{
request: { query, variables: defaultVariables },
result: { data: { hello: 'from link' } },
},
);

const client = new ApolloClient({
link,
cache: new InMemoryCache(),
ssrMode: true,
});

const { result, waitForNextUpdate } = renderHook(
() => useQuery(query, oldOptions => {
const newOptions = { client, ...oldOptions };

if (newOptions.variables) {
// If oldOptions.variables was defined, then it will be preserved
// when newOptions are Object.assign'd into the oldOptions, even if
// we remove newOptions.variables here.
delete newOptions.variables;
} else {
// We need to return newOptions.variables at least once to get them
// into the effective options, though.
newOptions.variables = defaultVariables;
}

return newOptions;
}),
// We deliberately do not provide the usual ApolloProvider wrapper for
// this test, since we are providing the client directly to useQuery.
// {
// wrapper: ({ children }) => (
// <ApolloProvider client={client}>
// {children}
// </ApolloProvider>
// ),
// }
);

expect(result.current.loading).toBe(true);
expect(result.current.data).toBeUndefined();

await waitForNextUpdate();

expect(result.current.loading).toBe(false);
expect(result.current.data).toEqual({ hello: 'from link' });
});
});

describe('polling', () => {
it('should support polling', async () => {
const query = gql`{ hello }`;
Expand Down

0 comments on commit 803d110

Please sign in to comment.