Skip to content

Commit a48b39e

Browse files
committed
Add failing test for defer with network-only and errors returned
1 parent 5f08c11 commit a48b39e

1 file changed

Lines changed: 108 additions & 0 deletions

File tree

src/core/__tests__/client.watchQuery/deferGraphQL17Alpha9.test.ts

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5984,6 +5984,114 @@ test('does not return complete cached deferred data while streaming with a "netw
59845984
await expect(stream).not.toEmitAnything();
59855985
});
59865986

5987+
test('does not return complete cached deferred data when a defer boundary completes with errors with a "network-only" fetch policy', async () => {
5988+
const query = gql`
5989+
query {
5990+
greeting {
5991+
message
5992+
... on Greeting @defer {
5993+
recipient {
5994+
name
5995+
}
5996+
}
5997+
}
5998+
}
5999+
`;
6000+
6001+
const { httpLink, enqueueInitialChunk, enqueueSubsequentChunk } =
6002+
mockDeferStreamGraphQL17Alpha9();
6003+
const cache = new InMemoryCache();
6004+
6005+
cache.writeQuery({
6006+
query,
6007+
data: {
6008+
greeting: {
6009+
__typename: "Greeting",
6010+
message: "Cached hello",
6011+
recipient: { __typename: "Person", name: "Cached Alice" },
6012+
},
6013+
},
6014+
});
6015+
6016+
const client = new ApolloClient({
6017+
cache,
6018+
link: httpLink,
6019+
incrementalHandler: new GraphQL17Alpha9Handler(),
6020+
});
6021+
6022+
const stream = new ObservableStream(
6023+
client.watchQuery({
6024+
query,
6025+
fetchPolicy: "network-only",
6026+
errorPolicy: "all",
6027+
})
6028+
);
6029+
6030+
await expect(stream).toEmitTypedValue({
6031+
data: undefined,
6032+
dataState: "empty",
6033+
loading: true,
6034+
networkStatus: NetworkStatus.loading,
6035+
partial: true,
6036+
});
6037+
6038+
enqueueInitialChunk({
6039+
data: { greeting: { __typename: "Greeting", message: "Hello world" } },
6040+
pending: [{ id: "0", path: ["greeting"] }],
6041+
hasNext: true,
6042+
});
6043+
6044+
await expect(stream).toEmitTypedValue({
6045+
data: markAsStreaming({
6046+
greeting: { __typename: "Greeting", message: "Hello world" },
6047+
}),
6048+
dataState: "streaming",
6049+
loading: true,
6050+
networkStatus: NetworkStatus.streaming,
6051+
partial: true,
6052+
});
6053+
6054+
// The error bubbles to the defer boundary without nullifying a field, so the
6055+
// network never delivers `recipient` at all.
6056+
enqueueSubsequentChunk({
6057+
completed: [
6058+
{
6059+
id: "0",
6060+
errors: [
6061+
{
6062+
message: "Could not fetch recipient",
6063+
path: ["greeting", "recipient"],
6064+
},
6065+
],
6066+
},
6067+
],
6068+
hasNext: false,
6069+
});
6070+
6071+
// The boundary leaves `pending` once it completes, so it is no longer pruned
6072+
// and the cached `recipient` fills the hole the network left behind.
6073+
await expect(stream).toEmitTypedValue({
6074+
data: markAsStreaming({
6075+
greeting: { __typename: "Greeting", message: "Hello world" },
6076+
}),
6077+
dataState: "streaming",
6078+
error: new CombinedGraphQLErrors({
6079+
data: { greeting: { __typename: "Greeting", message: "Hello world" } },
6080+
errors: [
6081+
{
6082+
message: "Could not fetch recipient",
6083+
path: ["greeting", "recipient"],
6084+
},
6085+
],
6086+
}),
6087+
loading: false,
6088+
networkStatus: NetworkStatus.error,
6089+
partial: true,
6090+
});
6091+
6092+
await expect(stream).not.toEmitAnything();
6093+
});
6094+
59876095
test('does not return a partial cached defer boundary while streaming with a "network-only" fetch policy', async () => {
59886096
const query = gql`
59896097
query {

0 commit comments

Comments
 (0)