@@ -671,30 +671,6 @@ void main() {
671
671
});
672
672
}
673
673
674
- test ('expired queue disposes registered MessageListView instances' , () => awaitFakeAsync ((async ) async {
675
- // Regression test for: https://github.com/zulip/zulip-flutter/issues/810
676
- await preparePoll ();
677
-
678
- // Make sure there are [MessageListView]s in the message store.
679
- MessageListView .init (store: store, narrow: const MentionsNarrow ());
680
- MessageListView .init (store: store, narrow: const StarredMessagesNarrow ());
681
- check (store.debugMessageListViews).length.equals (2 );
682
-
683
- // Let the server expire the event queue.
684
- connection.prepare (httpStatus: 400 , json: {
685
- 'result' : 'error' , 'code' : 'BAD_EVENT_QUEUE_ID' ,
686
- 'queue_id' : updateMachine.queueId,
687
- 'msg' : 'Bad event queue ID: ${updateMachine .queueId }' ,
688
- });
689
- updateMachine.debugAdvanceLoop ();
690
- async .flushMicrotasks ();
691
- await Future <void >.delayed (Duration .zero);
692
-
693
- // The old store's [MessageListView]s have been disposed.
694
- // (And no exception was thrown; that was #810.)
695
- check (store.debugMessageListViews).isEmpty ();
696
- }));
697
-
698
674
void checkRetry (void Function () prepareError) {
699
675
awaitFakeAsync ((async ) async {
700
676
await preparePoll (lastEventId: 1 );
@@ -727,31 +703,75 @@ void main() {
727
703
728
704
// These cases are ordered by how far the request got before it failed.
729
705
706
+ void prepareNetworkExceptionSocketException () {
707
+ connection.prepare (exception: const SocketException ('failed' ));
708
+ }
709
+
710
+ void prepareNetworkException () {
711
+ connection.prepare (exception: Exception ("failed" ));
712
+ }
713
+
714
+ void prepareServer5xxException () {
715
+ connection.prepare (httpStatus: 500 , body: 'splat' );
716
+ }
717
+
718
+ void prepareMalformedServerResponseException () {
719
+ connection.prepare (httpStatus: 200 , body: 'nonsense' );
720
+ }
721
+
722
+ void prepareZulipApiExceptionBadRequest () {
723
+ connection.prepare (httpStatus: 400 , json: {
724
+ 'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' });
725
+ }
726
+
727
+ void prepareExpiredEventQueue () {
728
+ connection.prepare (httpStatus: 400 , json: {
729
+ 'result' : 'error' , 'code' : 'BAD_EVENT_QUEUE_ID' ,
730
+ 'queue_id' : updateMachine.queueId,
731
+ 'msg' : 'Bad event queue ID: ${updateMachine .queueId }' ,
732
+ });
733
+ }
734
+
730
735
test ('retries on NetworkException' , () {
731
- checkRetry (() => connection. prepare (exception : Exception ( "failed" )) );
736
+ checkRetry (prepareNetworkException );
732
737
});
733
738
734
739
test ('retries on Server5xxException' , () {
735
- checkRetry (() => connection. prepare (httpStatus : 500 , body : 'splat' ) );
740
+ checkRetry (prepareServer5xxException );
736
741
});
737
742
738
743
test ('retries on MalformedServerResponseException' , () {
739
- checkRetry (() => connection. prepare (httpStatus : 200 , body : 'nonsense' ) );
744
+ checkRetry (prepareMalformedServerResponseException );
740
745
});
741
746
742
747
test ('retries on generic ZulipApiException' , () {
743
- checkRetry (() => connection.prepare (httpStatus: 400 , json: {
744
- 'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' }));
748
+ checkRetry (prepareZulipApiExceptionBadRequest);
745
749
});
746
750
747
751
test ('reloads on expired queue' , () {
748
- checkReload (() => connection.prepare (httpStatus: 400 , json: {
749
- 'result' : 'error' , 'code' : 'BAD_EVENT_QUEUE_ID' ,
750
- 'queue_id' : updateMachine.queueId,
751
- 'msg' : 'Bad event queue ID: ${updateMachine .queueId }' ,
752
- }));
752
+ checkReload (prepareExpiredEventQueue);
753
753
});
754
754
755
+ test ('expired queue disposes registered MessageListView instances' , () => awaitFakeAsync ((async ) async {
756
+ // Regression test for: https://github.com/zulip/zulip-flutter/issues/810
757
+ await preparePoll ();
758
+
759
+ // Make sure there are [MessageListView]s in the message store.
760
+ MessageListView .init (store: store, narrow: const MentionsNarrow ());
761
+ MessageListView .init (store: store, narrow: const StarredMessagesNarrow ());
762
+ check (store.debugMessageListViews).length.equals (2 );
763
+
764
+ // Let the server expire the event queue.
765
+ prepareExpiredEventQueue ();
766
+ updateMachine.debugAdvanceLoop ();
767
+ async .flushMicrotasks ();
768
+ await Future <void >.delayed (Duration .zero);
769
+
770
+ // The old store's [MessageListView]s have been disposed.
771
+ // (And no exception was thrown; that was #810.)
772
+ check (store.debugMessageListViews).isEmpty ();
773
+ }));
774
+
755
775
group ('report error' , () {
756
776
String ? lastReportedError;
757
777
String ? takeLastReportedError () {
@@ -781,8 +801,7 @@ void main() {
781
801
test ('report non-transient errors' , () => awaitFakeAsync ((async ) async {
782
802
await prepare ();
783
803
784
- connection.prepare (httpStatus: 400 , json: {
785
- 'result' : 'error' , 'code' : 'BAD_REQUEST' , 'msg' : 'Bad request' });
804
+ prepareZulipApiExceptionBadRequest ();
786
805
pollAndFail (async );
787
806
check (takeLastReportedError ()).isNotNull ().startsWith (
788
807
"Error connecting to Zulip. Retrying…\n "
@@ -794,14 +813,14 @@ void main() {
794
813
795
814
// There should be no user visible error messages during these retries.
796
815
for (int i = 0 ; i < UpdateMachine .transientFailureCountNotifyThreshold; i++ ) {
797
- connection. prepare (httpStatus : 500 , body : 'splat' );
816
+ prepareServer5xxException ( );
798
817
pollAndFail (async );
799
818
check (takeLastReportedError ()).isNull ();
800
819
// This skips the pending polling backoff.
801
820
async .flushTimers ();
802
821
}
803
822
804
- connection. prepare (httpStatus : 500 , body : 'splat' );
823
+ prepareServer5xxException ( );
805
824
pollAndFail (async );
806
825
check (takeLastReportedError ()).isNotNull ().startsWith (
807
826
"Error connecting to Zulip. Retrying…\n "
@@ -812,14 +831,14 @@ void main() {
812
831
await prepare ();
813
832
814
833
for (int i = 0 ; i < UpdateMachine .transientFailureCountNotifyThreshold; i++ ) {
815
- connection. prepare (exception : const SocketException ( 'failed' ) );
834
+ prepareNetworkExceptionSocketException ( );
816
835
pollAndFail (async );
817
836
check (takeLastReportedError ()).isNull ();
818
837
// This skips the pending polling backoff.
819
838
async .flushTimers ();
820
839
}
821
840
822
- connection. prepare (exception : const SocketException ( 'failed' ) );
841
+ prepareNetworkExceptionSocketException ( );
823
842
pollAndFail (async );
824
843
// Normally we start showing user visible error messages for transient
825
844
// errors after enough number of retries.
0 commit comments