@@ -158,17 +158,25 @@ void main() {
158
158
}));
159
159
160
160
test ('GlobalStore.perAccount account is logged out while loading; then fails with HTTP status code 401' , () => awaitFakeAsync ((async ) async {
161
- final globalStore = LoadingTestGlobalStore (accounts: [eg.selfAccount]);
161
+ final globalStore = UpdateMachineTestGlobalStore (accounts: [eg.selfAccount]);
162
+ globalStore.prepareRegisterQueueResponse = (connection) =>
163
+ connection.prepare (
164
+ delay: TestGlobalStore .removeAccountDuration + Duration (seconds: 1 ),
165
+ apiException: eg.apiExceptionUnauthorized ());
166
+ final connection = globalStore.apiConnectionFromAccount (eg.selfAccount) as FakeApiConnection ;
162
167
final future = globalStore.perAccount (eg.selfAccount.id);
168
+ check (connection.takeRequests ()).length.equals (1 ); // register request
163
169
164
170
await logOutAccount (globalStore, eg.selfAccount.id);
165
171
check (globalStore.takeDoRemoveAccountCalls ())
166
172
.single.equals (eg.selfAccount.id);
167
173
168
- globalStore.completers[eg.selfAccount.id]!
169
- .single.completeError (eg.apiExceptionUnauthorized ());
170
174
await check (future).throws <AccountNotFoundException >();
171
175
check (globalStore.takeDoRemoveAccountCalls ()).isEmpty ();
176
+ // no poll, server-emoji-data, or register-token requests
177
+ check (connection.takeRequests ()).isEmpty ();
178
+ // TODO(#1354) uncomment
179
+ // check(connection).isOpen.isFalse();
172
180
}));
173
181
174
182
// TODO test insertAccount
@@ -266,11 +274,20 @@ void main() {
266
274
});
267
275
268
276
test ('when store loading' , () async {
269
- final globalStore = LoadingTestGlobalStore (accounts: [eg.selfAccount]);
277
+ final globalStore = UpdateMachineTestGlobalStore (accounts: [eg.selfAccount]);
270
278
checkGlobalStore (globalStore, eg.selfAccount.id,
271
279
expectAccount: true , expectStore: false );
272
280
273
- // don't await; we'll complete/await it manually after removeAccount
281
+ // assert(globalStore.useCachedApiConnections);
282
+ // Cache a connection and get this reference to it,
283
+ // so we can check later that it gets closed.
284
+ // final connection = globalStore.apiConnectionFromAccount(eg.selfAccount) as FakeApiConnection;
285
+
286
+ globalStore.prepareRegisterQueueResponse = (connection) {
287
+ connection.prepare (
288
+ delay: TestGlobalStore .removeAccountDuration + Duration (seconds: 1 ),
289
+ json: eg.initialSnapshot ().toJson ());
290
+ };
274
291
final loadingFuture = globalStore.perAccount (eg.selfAccount.id);
275
292
276
293
checkGlobalStore (globalStore, eg.selfAccount.id,
@@ -284,13 +301,14 @@ void main() {
284
301
expectAccount: false , expectStore: false );
285
302
check (notifyCount).equals (1 );
286
303
287
- globalStore.completers[eg.selfAccount.id]! .single
288
- .complete (eg.store (account: eg.selfAccount, initialSnapshot: eg.initialSnapshot ()));
289
- // TODO test that the never-used store got disposed and its connection closed
290
- await check (loadingFuture).throws <AccountNotFoundException >();
304
+ // Actually throws a null-check error; that's the bug #1354.
305
+ // TODO(#1354) should specifically throw AccountNotFoundException
306
+ await check (loadingFuture).throws ();
291
307
checkGlobalStore (globalStore, eg.selfAccount.id,
292
308
expectAccount: false , expectStore: false );
293
309
check (notifyCount).equals (1 ); // no extra notify
310
+ // TODO(#1354) uncomment
311
+ // check(connection).isOpen.isFalse();
294
312
295
313
check (globalStore.debugNumPerAccountStoresLoading).equals (0 );
296
314
});
@@ -992,44 +1010,39 @@ void main() {
992
1010
});
993
1011
994
1012
group ('UpdateMachine.poll reload failure' , () {
995
- late LoadingTestGlobalStore globalStore;
996
-
997
- List <Completer <PerAccountStore >> completers () =>
998
- globalStore.completers[eg.selfAccount.id]! ;
999
-
1000
- Future <void > prepareReload (FakeAsync async ) async {
1001
- globalStore = LoadingTestGlobalStore (accounts: [eg.selfAccount]);
1002
-
1003
- // Simulate the setup that [TestGlobalStore.doLoadPerAccount] would do.
1004
- // (These tests use [LoadingTestGlobalStore] for greater control in
1005
- // later steps; that requires this setup step to be finer-grained too.)
1006
- final updateMachine = eg.updateMachine (
1007
- globalStore: globalStore, account: eg.selfAccount);
1008
- final store = updateMachine.store;
1009
- final future = globalStore.perAccount (eg.selfAccount.id);
1010
- completers ().single.complete (store);
1011
- await future;
1012
- completers ().clear ();
1013
+ late UpdateMachineTestGlobalStore globalStore;
1013
1014
1014
- updateMachine.debugPauseLoop ();
1015
- updateMachine.poll ();
1016
- (store.connection as FakeApiConnection ).prepare (
1015
+ Future <void > prepareReload (FakeAsync async , {
1016
+ required void Function (FakeApiConnection ) prepareRegisterQueueResponse,
1017
+ }) async {
1018
+ globalStore = UpdateMachineTestGlobalStore (accounts: [eg.selfAccount]);
1019
+
1020
+ final store = await globalStore.perAccount (eg.selfAccount.id);
1021
+ final updateMachine = store.updateMachine! ;
1022
+
1023
+ final connection = store.connection as FakeApiConnection ;
1024
+ connection.prepare (
1017
1025
apiException: eg.apiExceptionBadEventQueueId ());
1026
+ globalStore.prepareRegisterQueueResponse = prepareRegisterQueueResponse;
1027
+ // When we reload, we should get a new connection,
1028
+ // just like when the app runs live. This is more realistic,
1029
+ // and we don't want a glitch where we try to double-close a connection
1030
+ // just because of the test infrastructure. (One of the tests
1031
+ // logs out the account, and the connection shouldn't be used after that.)
1032
+ globalStore.clearCachedApiConnections ();
1018
1033
updateMachine.debugAdvanceLoop ();
1019
- async .elapse (Duration .zero);
1034
+ async .elapse (Duration .zero); // the bad-event-queue error arrives
1020
1035
check (store).isLoading.isTrue ();
1021
1036
}
1022
1037
1023
1038
test ('user logged out before new store is loaded' , () => awaitFakeAsync ((async ) async {
1024
- await prepareReload (async );
1025
- check (completers ()).single.isCompleted.isFalse ();
1039
+ await prepareReload (async , prepareRegisterQueueResponse: (connection) {
1040
+ connection.prepare (
1041
+ delay: TestGlobalStore .removeAccountDuration + Duration (seconds: 1 ),
1042
+ json: eg.initialSnapshot ().toJson ());
1043
+ });
1026
1044
1027
- // [PerAccountStore.fromInitialSnapshot] requires the account
1028
- // to be in the global store when called; do so before logging out.
1029
- final newStore = eg.store (globalStore: globalStore, account: eg.selfAccount);
1030
1045
await logOutAccount (globalStore, eg.selfAccount.id);
1031
- completers ().single.complete (newStore);
1032
- check (completers ()).single.isCompleted.isTrue ();
1033
1046
check (globalStore.takeDoRemoveAccountCalls ()).single.equals (eg.selfAccount.id);
1034
1047
1035
1048
async .elapse (TestGlobalStore .removeAccountDuration);
@@ -1038,15 +1051,19 @@ void main() {
1038
1051
async .flushTimers ();
1039
1052
// Reload never succeeds and there are no unhandled errors.
1040
1053
check (globalStore.perAccountSync (eg.selfAccount.id)).isNull ();
1041
- }));
1054
+ }),
1055
+ // An unhandled error is actually the bug #1354, so skip for now
1056
+ // TODO(#1354) unskip
1057
+ skip: true );
1042
1058
1043
1059
test ('new store is not loaded, gets HTTP 401 error instead' , () => awaitFakeAsync ((async ) async {
1044
- await prepareReload (async );
1045
- check (completers ()).single.isCompleted.isFalse ();
1060
+ await prepareReload (async , prepareRegisterQueueResponse: (connection) {
1061
+ connection.prepare (
1062
+ delay: Duration (seconds: 1 ),
1063
+ apiException: eg.apiExceptionUnauthorized ());
1064
+ });
1046
1065
1047
- completers ().single.completeError (eg.apiExceptionUnauthorized ());
1048
- async .elapse (Duration .zero);
1049
- check (completers ()).single.isCompleted.isTrue ();
1066
+ async .elapse (const Duration (seconds: 1 ));
1050
1067
check (globalStore.takeDoRemoveAccountCalls ()).single.equals (eg.selfAccount.id);
1051
1068
1052
1069
async .elapse (TestGlobalStore .removeAccountDuration);
0 commit comments