@@ -131,17 +131,25 @@ void main() {
131
131
}));
132
132
133
133
test ('GlobalStore.perAccount account is logged out while loading; then fails with HTTP status code 401' , () => awaitFakeAsync ((async ) async {
134
- final globalStore = LoadingTestGlobalStore (accounts: [eg.selfAccount]);
134
+ final globalStore = UpdateMachineTestGlobalStore (accounts: [eg.selfAccount]);
135
+ globalStore.prepareRegisterQueueResponse = (connection) =>
136
+ connection.prepare (
137
+ delay: TestGlobalStore .removeAccountDuration + Duration (seconds: 1 ),
138
+ apiException: eg.apiExceptionUnauthorized ());
139
+ final connection = globalStore.apiConnectionFromAccount (eg.selfAccount) as FakeApiConnection ;
135
140
final future = globalStore.perAccount (eg.selfAccount.id);
141
+ check (connection.takeRequests ()).length.equals (1 ); // register request
136
142
137
143
await logOutAccount (globalStore, eg.selfAccount.id);
138
144
check (globalStore.takeDoRemoveAccountCalls ())
139
145
.single.equals (eg.selfAccount.id);
140
146
141
- globalStore.completers[eg.selfAccount.id]!
142
- .single.completeError (eg.apiExceptionUnauthorized ());
143
147
await check (future).throws <AccountNotFoundException >();
144
148
check (globalStore.takeDoRemoveAccountCalls ()).isEmpty ();
149
+ // no poll, server-emoji-data, or register-token requests
150
+ check (connection.takeRequests ()).isEmpty ();
151
+ // TODO(#1354) uncomment
152
+ // check(connection).isOpen.isFalse();
145
153
}));
146
154
147
155
// TODO test insertAccount
@@ -239,11 +247,20 @@ void main() {
239
247
});
240
248
241
249
test ('when store loading' , () async {
242
- final globalStore = LoadingTestGlobalStore (accounts: [eg.selfAccount]);
250
+ final globalStore = UpdateMachineTestGlobalStore (accounts: [eg.selfAccount]);
243
251
checkGlobalStore (globalStore, eg.selfAccount.id,
244
252
expectAccount: true , expectStore: false );
245
253
246
- // don't await; we'll complete/await it manually after removeAccount
254
+ // assert(globalStore.useCachedApiConnections);
255
+ // Cache a connection and get this reference to it,
256
+ // so we can check later that it gets closed.
257
+ // final connection = globalStore.apiConnectionFromAccount(eg.selfAccount) as FakeApiConnection;
258
+
259
+ globalStore.prepareRegisterQueueResponse = (connection) {
260
+ connection.prepare (
261
+ delay: TestGlobalStore .removeAccountDuration + Duration (seconds: 1 ),
262
+ json: eg.initialSnapshot ().toJson ());
263
+ };
247
264
final loadingFuture = globalStore.perAccount (eg.selfAccount.id);
248
265
249
266
checkGlobalStore (globalStore, eg.selfAccount.id,
@@ -257,13 +274,14 @@ void main() {
257
274
expectAccount: false , expectStore: false );
258
275
check (notifyCount).equals (1 );
259
276
260
- globalStore.completers[eg.selfAccount.id]! .single
261
- .complete (eg.store (account: eg.selfAccount, initialSnapshot: eg.initialSnapshot ()));
262
- // TODO test that the never-used store got disposed and its connection closed
263
- await check (loadingFuture).throws <AccountNotFoundException >();
277
+ // Actually throws a null-check error; that's the bug #1354.
278
+ // TODO(#1354) should specifically throw AccountNotFoundException
279
+ await check (loadingFuture).throws ();
264
280
checkGlobalStore (globalStore, eg.selfAccount.id,
265
281
expectAccount: false , expectStore: false );
266
282
check (notifyCount).equals (1 ); // no extra notify
283
+ // TODO(#1354) uncomment
284
+ // check(connection).isOpen.isFalse();
267
285
268
286
check (globalStore.debugNumPerAccountStoresLoading).equals (0 );
269
287
});
@@ -966,41 +984,42 @@ void main() {
966
984
});
967
985
968
986
group ('UpdateMachine.poll reload failure' , () {
969
- late LoadingTestGlobalStore globalStore;
987
+ late UpdateMachineTestGlobalStore globalStore;
970
988
971
- List <Completer <PerAccountStore >> completers () =>
972
- globalStore.completers[eg.selfAccount.id]! ;
989
+ Future <void > prepareReload (FakeAsync async , {
990
+ required void Function (FakeApiConnection ) prepareRegisterQueueResponse,
991
+ }) async {
992
+ globalStore = UpdateMachineTestGlobalStore (accounts: [eg.selfAccount]);
973
993
974
- Future <void > prepareReload (FakeAsync async ) async {
975
- globalStore = LoadingTestGlobalStore (accounts: [eg.selfAccount]);
976
- final future = globalStore.perAccount (eg.selfAccount.id);
977
- final store = eg.store (globalStore: globalStore, account: eg.selfAccount);
978
- completers ().single.complete (store);
979
- await future;
980
- completers ().clear ();
981
- final updateMachine = globalStore.updateMachines[eg.selfAccount.id] =
982
- UpdateMachine .fromInitialSnapshot (
983
- store: store, initialSnapshot: eg.initialSnapshot ());
984
- updateMachine.debugPauseLoop ();
994
+ final store = await globalStore.perAccount (eg.selfAccount.id);
995
+ final updateMachine = store.updateMachine! ;
985
996
updateMachine.poll ();
986
997
987
- (store.connection as FakeApiConnection ).prepare (
998
+ final connection = store.connection as FakeApiConnection ;
999
+ connection.prepare (
988
1000
apiException: eg.apiExceptionBadEventQueueId ());
1001
+ globalStore.clearCachedApiConnections ();
1002
+ globalStore.prepareRegisterQueueResponse = (newConnection) {
1003
+ // Assert this is actually a new connection, not the one on
1004
+ // globalStore._perAccountStores, which at least one test will close
1005
+ // via logOutAccount.
1006
+ assert (! identical (connection, newConnection));
1007
+ prepareRegisterQueueResponse (newConnection);
1008
+ };
989
1009
updateMachine.debugAdvanceLoop ();
990
1010
async .elapse (Duration .zero);
991
1011
check (store).isLoading.isTrue ();
992
1012
}
993
1013
994
1014
test ('user logged out before new store is loaded' , () => awaitFakeAsync ((async ) async {
995
- await prepareReload (async );
996
- check (completers ()).single.isCompleted.isFalse ();
1015
+ await prepareReload (async ,
1016
+ prepareRegisterQueueResponse: (newConnection) {
1017
+ newConnection.prepare (
1018
+ delay: TestGlobalStore .removeAccountDuration + Duration (seconds: 1 ),
1019
+ json: eg.initialSnapshot ().toJson ());
1020
+ });
997
1021
998
- // [PerAccountStore.fromInitialSnapshot] requires the account
999
- // to be in the global store when called; do so before logging out.
1000
- final newStore = eg.store (globalStore: globalStore, account: eg.selfAccount);
1001
1022
await logOutAccount (globalStore, eg.selfAccount.id);
1002
- completers ().single.complete (newStore);
1003
- check (completers ()).single.isCompleted.isTrue ();
1004
1023
check (globalStore.takeDoRemoveAccountCalls ()).single.equals (eg.selfAccount.id);
1005
1024
1006
1025
async .elapse (TestGlobalStore .removeAccountDuration);
@@ -1009,15 +1028,20 @@ void main() {
1009
1028
async .flushTimers ();
1010
1029
// Reload never succeeds and there are no unhandled errors.
1011
1030
check (globalStore.perAccountSync (eg.selfAccount.id)).isNull ();
1012
- }));
1031
+ }),
1032
+ // An unhandled error is actually the bug #1354, so skip for now
1033
+ // TODO(#1354) unskip
1034
+ skip: true );
1013
1035
1014
1036
test ('new store is not loaded, gets HTTP 401 error instead' , () => awaitFakeAsync ((async ) async {
1015
- await prepareReload (async );
1016
- check (completers ()).single.isCompleted.isFalse ();
1037
+ await prepareReload (async ,
1038
+ prepareRegisterQueueResponse: (newConnection) {
1039
+ newConnection.prepare (
1040
+ delay: Duration (seconds: 1 ),
1041
+ apiException: eg.apiExceptionUnauthorized ());
1042
+ });
1017
1043
1018
- completers ().single.completeError (eg.apiExceptionUnauthorized ());
1019
- async .elapse (Duration .zero);
1020
- check (completers ()).single.isCompleted.isTrue ();
1044
+ async .elapse (const Duration (seconds: 1 ));
1021
1045
check (globalStore.takeDoRemoveAccountCalls ()).single.equals (eg.selfAccount.id);
1022
1046
1023
1047
async .elapse (TestGlobalStore .removeAccountDuration);
0 commit comments