Skip to content

Commit 6672e44

Browse files
nivekzmicimize
authored andcommitted
fix(flutter): Query.didUpdateWidget and policy overrides
1 parent 145d35c commit 6672e44

File tree

2 files changed

+234
-1
lines changed

2 files changed

+234
-1
lines changed

packages/graphql_flutter/lib/src/widgets/query.dart

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ class QueryState extends State<Query> {
7272
void didUpdateWidget(Query oldWidget) {
7373
super.didUpdateWidget(oldWidget);
7474

75-
if (!observableQuery.options.areEqualTo(_options)) {
75+
final GraphQLClient client = GraphQLProvider.of(context).value;
76+
77+
final optionsWithOverrides = _options;
78+
optionsWithOverrides.policies = client.defaultPolicies.watchQuery
79+
.withOverrides(optionsWithOverrides.policies);
80+
81+
if (!observableQuery.options.areEqualTo(optionsWithOverrides)) {
7682
_initQuery();
7783
}
7884
}
Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
import 'package:flutter/material.dart';
2+
import 'package:flutter_test/flutter_test.dart';
3+
import 'package:graphql_flutter/graphql_flutter.dart';
4+
import 'package:graphql_flutter/src/widgets/query.dart';
5+
import 'package:http/http.dart';
6+
import 'package:mockito/mockito.dart';
7+
8+
class MockHttpClient extends Mock implements Client {}
9+
10+
final query = gql("""
11+
query Foo {
12+
foo
13+
}
14+
""");
15+
16+
class Page extends StatefulWidget {
17+
final Map<String, dynamic> variables;
18+
final FetchPolicy fetchPolicy;
19+
final ErrorPolicy errorPolicy;
20+
21+
Page({
22+
Key key,
23+
this.variables,
24+
this.fetchPolicy,
25+
this.errorPolicy,
26+
}): super(key: key);
27+
28+
@override
29+
State<StatefulWidget> createState() => PageState();
30+
}
31+
32+
class PageState extends State<Page> {
33+
Map<String, dynamic> variables;
34+
FetchPolicy fetchPolicy;
35+
ErrorPolicy errorPolicy;
36+
37+
@override
38+
void initState() {
39+
super.initState();
40+
variables = widget.variables;
41+
fetchPolicy = widget.fetchPolicy;
42+
errorPolicy = widget.errorPolicy;
43+
}
44+
45+
setVariables(Map<String, dynamic> newVariables) {
46+
setState(() {
47+
variables = newVariables;
48+
});
49+
}
50+
51+
setFetchPolicy(FetchPolicy newFetchPolicy) {
52+
setState(() {
53+
fetchPolicy = newFetchPolicy;
54+
});
55+
}
56+
57+
setErrorPolicy(ErrorPolicy newErrorPolicy) {
58+
setState(() {
59+
errorPolicy = newErrorPolicy;
60+
});
61+
}
62+
63+
@override
64+
Widget build(BuildContext context) {
65+
return Query(
66+
options: QueryOptions(
67+
documentNode: query,
68+
variables: variables,
69+
fetchPolicy: fetchPolicy,
70+
errorPolicy: errorPolicy,
71+
),
72+
builder: (QueryResult result, {
73+
Refetch refetch,
74+
FetchMore fetchMore
75+
}) => Container(),
76+
);
77+
}
78+
}
79+
80+
void main() {
81+
group('Query', () {
82+
MockHttpClient mockHttpClient;
83+
HttpLink httpLink;
84+
ValueNotifier<GraphQLClient> client;
85+
86+
setUp(() async {
87+
mockHttpClient = MockHttpClient();
88+
httpLink = HttpLink(
89+
uri: 'https://unused/graphql',
90+
httpClient: mockHttpClient,
91+
);
92+
client = ValueNotifier(
93+
GraphQLClient(
94+
cache: InMemoryCache(storagePrefix: 'test'),
95+
link: httpLink,
96+
),
97+
);
98+
});
99+
100+
testWidgets('does not issue network request on same options',
101+
(WidgetTester tester) async {
102+
final page = Page(
103+
variables: {
104+
'foo': 1,
105+
},
106+
fetchPolicy: FetchPolicy.networkOnly,
107+
errorPolicy: ErrorPolicy.ignore,
108+
);
109+
110+
await tester.pumpWidget(GraphQLProvider(
111+
client: client,
112+
child: page,
113+
));
114+
115+
verify(mockHttpClient.send(any)).called(1);
116+
117+
tester.state<PageState>(find.byWidget(page))
118+
..setVariables({'foo': 1})
119+
..setFetchPolicy(FetchPolicy.networkOnly)
120+
..setErrorPolicy(ErrorPolicy.ignore);
121+
await tester.pump();
122+
verifyNoMoreInteractions(mockHttpClient);
123+
});
124+
125+
testWidgets('does not issue network request when policies stays null',
126+
(WidgetTester tester) async {
127+
final page = Page(
128+
variables: {
129+
'foo': 1,
130+
},
131+
);
132+
133+
await tester.pumpWidget(GraphQLProvider(
134+
client: client,
135+
child: page,
136+
));
137+
138+
verify(mockHttpClient.send(any)).called(1);
139+
140+
tester.state<PageState>(find.byWidget(page))
141+
..setFetchPolicy(null)
142+
..setErrorPolicy(null);
143+
await tester.pump();
144+
verifyNoMoreInteractions(mockHttpClient);
145+
});
146+
147+
testWidgets('issues a new network request when variables change',
148+
(WidgetTester tester) async {
149+
final page = Page(
150+
variables: {
151+
'foo': 1,
152+
},
153+
);
154+
155+
await tester.pumpWidget(GraphQLProvider(
156+
client: client,
157+
child: page,
158+
));
159+
160+
verify(mockHttpClient.send(any)).called(1);
161+
162+
tester.state<PageState>(find.byWidget(page))
163+
.setVariables({'foo': 2});
164+
await tester.pump();
165+
verify(mockHttpClient.send(any)).called(1);
166+
});
167+
168+
testWidgets('issues a new network request when fetch policy changes',
169+
(WidgetTester tester) async {
170+
final page = Page(
171+
fetchPolicy: FetchPolicy.networkOnly,
172+
);
173+
174+
await tester.pumpWidget(GraphQLProvider(
175+
client: client,
176+
child: page,
177+
));
178+
179+
verify(mockHttpClient.send(any)).called(1);
180+
181+
tester.state<PageState>(find.byWidget(page))
182+
.setFetchPolicy(FetchPolicy.cacheFirst);
183+
await tester.pump();
184+
verify(mockHttpClient.send(any)).called(1);
185+
});
186+
187+
testWidgets('issues a new network request when error policy changes',
188+
(WidgetTester tester) async {
189+
final page = Page(
190+
errorPolicy: ErrorPolicy.all,
191+
);
192+
193+
await tester.pumpWidget(GraphQLProvider(
194+
client: client,
195+
child: page,
196+
));
197+
198+
verify(mockHttpClient.send(any)).called(1);
199+
200+
tester.state<PageState>(find.byWidget(page))
201+
.setErrorPolicy(ErrorPolicy.none);
202+
await tester.pump();
203+
verify(mockHttpClient.send(any)).called(1);
204+
});
205+
206+
testWidgets('does not issues new network request when policies are effectively unchanged',
207+
(WidgetTester tester) async {
208+
final page = Page(
209+
fetchPolicy: FetchPolicy.cacheAndNetwork,
210+
errorPolicy: null,
211+
);
212+
213+
await tester.pumpWidget(GraphQLProvider(
214+
client: client,
215+
child: page,
216+
));
217+
218+
verify(mockHttpClient.send(any)).called(1);
219+
220+
tester.state<PageState>(find.byWidget(page))
221+
..setFetchPolicy(null)
222+
..setErrorPolicy(ErrorPolicy.none);
223+
await tester.pump();
224+
verifyNoMoreInteractions(mockHttpClient);
225+
});
226+
});
227+
}

0 commit comments

Comments
 (0)