Skip to content

Commit 5957d6f

Browse files
authored
Add tests for refetch and error with no data returned (#13249)
Closes #12667 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Tests** * Added comprehensive test coverage for `watchQuery` refetch behavior when GraphQL errors occur, verifying correct stream state management and promise handling across different error handling configurations. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
1 parent 7c5dcde commit 5957d6f

1 file changed

Lines changed: 225 additions & 0 deletions

File tree

Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
import {
2+
ApolloClient,
3+
CombinedGraphQLErrors,
4+
gql,
5+
InMemoryCache,
6+
NetworkStatus,
7+
} from "@apollo/client";
8+
import { MockLink } from "@apollo/client/testing";
9+
import { ObservableStream } from "@apollo/client/testing/internal";
10+
11+
test("maintains data with errorPolicy: none when refetch returns error with no data", async () => {
12+
const query = gql`
13+
query people {
14+
allPeople {
15+
people {
16+
name
17+
}
18+
}
19+
}
20+
`;
21+
22+
const data = { allPeople: { people: [{ name: "Luke Skywalker" }] } };
23+
24+
const client = new ApolloClient({
25+
cache: new InMemoryCache(),
26+
link: new MockLink([
27+
{
28+
request: { query },
29+
result: { data },
30+
delay: 20,
31+
},
32+
{
33+
request: { query },
34+
result: { errors: [{ message: "Oops" }] },
35+
delay: 20,
36+
},
37+
]),
38+
});
39+
40+
const observable = client.watchQuery({ query, errorPolicy: "none" });
41+
const stream = new ObservableStream(observable);
42+
43+
await expect(stream).toEmitTypedValue({
44+
data: undefined,
45+
dataState: "empty",
46+
loading: true,
47+
networkStatus: NetworkStatus.loading,
48+
partial: true,
49+
});
50+
51+
await expect(stream).toEmitTypedValue({
52+
data,
53+
dataState: "complete",
54+
loading: false,
55+
networkStatus: NetworkStatus.ready,
56+
partial: false,
57+
});
58+
59+
await expect(observable.refetch()).rejects.toStrictEqualTyped(
60+
new CombinedGraphQLErrors({ errors: [{ message: "Oops" }] })
61+
);
62+
63+
await expect(stream).toEmitTypedValue({
64+
data,
65+
dataState: "complete",
66+
loading: true,
67+
networkStatus: NetworkStatus.refetch,
68+
partial: false,
69+
});
70+
71+
await expect(stream).toEmitTypedValue({
72+
data,
73+
dataState: "complete",
74+
error: new CombinedGraphQLErrors({ errors: [{ message: "Oops" }] }),
75+
loading: false,
76+
networkStatus: NetworkStatus.error,
77+
partial: false,
78+
});
79+
80+
await expect(stream).not.toEmitAnything();
81+
});
82+
83+
test("returns data as undefined with errorPolicy: all when refetch returns error with no data", async () => {
84+
const query = gql`
85+
query people {
86+
allPeople {
87+
people {
88+
name
89+
}
90+
}
91+
}
92+
`;
93+
94+
const data = { allPeople: { people: [{ name: "Luke Skywalker" }] } };
95+
96+
const client = new ApolloClient({
97+
cache: new InMemoryCache(),
98+
link: new MockLink([
99+
{
100+
request: { query },
101+
result: { data },
102+
delay: 20,
103+
},
104+
{
105+
request: { query },
106+
result: { errors: [{ message: "Oops" }] },
107+
delay: 20,
108+
},
109+
]),
110+
});
111+
112+
const observable = client.watchQuery({ query, errorPolicy: "all" });
113+
const stream = new ObservableStream(observable);
114+
115+
await expect(stream).toEmitTypedValue({
116+
data: undefined,
117+
dataState: "empty",
118+
loading: true,
119+
networkStatus: NetworkStatus.loading,
120+
partial: true,
121+
});
122+
123+
await expect(stream).toEmitTypedValue({
124+
data,
125+
dataState: "complete",
126+
loading: false,
127+
networkStatus: NetworkStatus.ready,
128+
partial: false,
129+
});
130+
131+
await expect(observable.refetch()).resolves.toStrictEqualTyped({
132+
data: undefined,
133+
error: new CombinedGraphQLErrors({ errors: [{ message: "Oops" }] }),
134+
});
135+
136+
await expect(stream).toEmitTypedValue({
137+
data,
138+
dataState: "complete",
139+
loading: true,
140+
networkStatus: NetworkStatus.refetch,
141+
partial: false,
142+
});
143+
144+
await expect(stream).toEmitTypedValue({
145+
data: undefined,
146+
dataState: "empty",
147+
error: new CombinedGraphQLErrors({ errors: [{ message: "Oops" }] }),
148+
loading: false,
149+
networkStatus: NetworkStatus.error,
150+
partial: true,
151+
});
152+
153+
await expect(stream).not.toEmitAnything();
154+
});
155+
156+
test("returns data as undefined with errorPolicy: ignore when refetch returns error with no data", async () => {
157+
const query = gql`
158+
query people {
159+
allPeople {
160+
people {
161+
name
162+
}
163+
}
164+
}
165+
`;
166+
167+
const data = { allPeople: { people: [{ name: "Luke Skywalker" }] } };
168+
169+
const client = new ApolloClient({
170+
cache: new InMemoryCache(),
171+
link: new MockLink([
172+
{
173+
request: { query },
174+
result: { data },
175+
delay: 20,
176+
},
177+
{
178+
request: { query },
179+
result: { errors: [{ message: "Oops" }] },
180+
delay: 20,
181+
},
182+
]),
183+
});
184+
185+
const observable = client.watchQuery({ query, errorPolicy: "ignore" });
186+
const stream = new ObservableStream(observable);
187+
188+
await expect(stream).toEmitTypedValue({
189+
data: undefined,
190+
dataState: "empty",
191+
loading: true,
192+
networkStatus: NetworkStatus.loading,
193+
partial: true,
194+
});
195+
196+
await expect(stream).toEmitTypedValue({
197+
data,
198+
dataState: "complete",
199+
loading: false,
200+
networkStatus: NetworkStatus.ready,
201+
partial: false,
202+
});
203+
204+
await expect(observable.refetch()).resolves.toStrictEqualTyped({
205+
data: undefined,
206+
});
207+
208+
await expect(stream).toEmitTypedValue({
209+
data,
210+
dataState: "complete",
211+
loading: true,
212+
networkStatus: NetworkStatus.refetch,
213+
partial: false,
214+
});
215+
216+
await expect(stream).toEmitTypedValue({
217+
data: undefined,
218+
dataState: "empty",
219+
loading: false,
220+
networkStatus: NetworkStatus.ready,
221+
partial: true,
222+
});
223+
224+
await expect(stream).not.toEmitAnything();
225+
});

0 commit comments

Comments
 (0)