@@ -249,6 +249,53 @@ void main() {
249
249
await Future .delayed (Duration .zero);
250
250
check (store.userSettings! .twentyFourHourTime).isTrue ();
251
251
}));
252
+
253
+ void checkRetry (void Function () prepareError) {
254
+ awaitFakeAsync ((async ) async {
255
+ await prepareStore (lastEventId: 1 );
256
+ updateMachine.debugPauseLoop ();
257
+ updateMachine.poll ();
258
+ check (async .pendingTimers).length.equals (0 );
259
+
260
+ // Make the request, inducing an error in it.
261
+ prepareError ();
262
+ updateMachine.debugAdvanceLoop ();
263
+ async .flushMicrotasks ();
264
+ checkLastRequest (lastEventId: 1 );
265
+
266
+ // Polling doesn't resume immediately; there's a timer.
267
+ check (async .pendingTimers).length.equals (1 );
268
+ updateMachine.debugAdvanceLoop ();
269
+ async .flushMicrotasks ();
270
+ check (connection.lastRequest).isNull ();
271
+ check (async .pendingTimers).length.equals (1 );
272
+
273
+ // Polling continues after a timer.
274
+ connection.prepare (json: GetEventsResult (events: [
275
+ HeartbeatEvent (id: 2 ),
276
+ ], queueId: null ).toJson ());
277
+ async .flushTimers ();
278
+ checkLastRequest (lastEventId: 1 );
279
+ check (updateMachine.lastEventId).equals (2 );
280
+ });
281
+ }
282
+
283
+ test ('retries on Server5xxException' , () {
284
+ checkRetry (() => connection.prepare (httpStatus: 500 , body: 'splat' ));
285
+ });
286
+
287
+ test ('retries on NetworkException' , () {
288
+ checkRetry (() => connection.prepare (exception: Exception ("failed" )));
289
+ });
290
+
291
+ test ('retries on ZulipApiException' , () {
292
+ checkRetry (() => connection.prepare (httpStatus: 400 , json: {
293
+ 'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' }));
294
+ });
295
+
296
+ test ('retries on MalformedServerResponseException' , () {
297
+ checkRetry (() => connection.prepare (httpStatus: 200 , body: 'nonsense' ));
298
+ });
252
299
});
253
300
254
301
group ('UpdateMachine.registerNotificationToken' , () {
0 commit comments