|
1 | 1 | import 'dart:async';
|
2 | 2 |
|
3 | 3 | import 'package:checks/checks.dart';
|
| 4 | +import 'package:http/http.dart' as http; |
4 | 5 | import 'package:test/scaffolding.dart';
|
5 | 6 | import 'package:zulip/model/store.dart';
|
| 7 | +import 'package:zulip/notifications.dart'; |
6 | 8 |
|
7 | 9 | import '../api/fake_api.dart';
|
8 | 10 | import '../example_data.dart' as eg;
|
| 11 | +import '../stdlib_checks.dart'; |
| 12 | +import 'binding.dart'; |
9 | 13 | import 'test_store.dart';
|
10 | 14 |
|
11 | 15 | void main() {
|
| 16 | + TestZulipBinding.ensureInitialized(); |
| 17 | + |
12 | 18 | final account1 = eg.selfAccount.copyWith(id: 1);
|
13 | 19 | final account2 = eg.otherAccount.copyWith(id: 2);
|
14 | 20 |
|
@@ -100,6 +106,70 @@ void main() {
|
100 | 106 | check(await globalStore.perAccount(1)).identicalTo(store1);
|
101 | 107 | check(completers(1)).length.equals(1);
|
102 | 108 | });
|
| 109 | + |
| 110 | + group('PerAccountStore.registerNotificationToken', () { |
| 111 | + late LivePerAccountStore store; |
| 112 | + late FakeApiConnection connection; |
| 113 | + |
| 114 | + void prepareStore() { |
| 115 | + store = eg.liveStore(); |
| 116 | + connection = store.connection as FakeApiConnection; |
| 117 | + } |
| 118 | + |
| 119 | + void checkLastRequest({required String token}) { |
| 120 | + check(connection.lastRequest).isA<http.Request>() |
| 121 | + ..method.equals('POST') |
| 122 | + ..url.path.equals('/api/v1/users/me/android_gcm_reg_id') |
| 123 | + ..bodyFields.deepEquals({'token': token}); |
| 124 | + } |
| 125 | + |
| 126 | + test('token already known', () async { |
| 127 | + // This tests the case where [NotificationService.start] has already |
| 128 | + // learned the token before the store is created. |
| 129 | + // (This is probably the common case.) |
| 130 | + addTearDown(testBinding.reset); |
| 131 | + testBinding.firebaseMessagingInitialToken = '012abc'; |
| 132 | + addTearDown(NotificationService.debugReset); |
| 133 | + await NotificationService.instance.start(); |
| 134 | + |
| 135 | + // On store startup, send the token. |
| 136 | + prepareStore(); |
| 137 | + connection.prepare(json: {}); |
| 138 | + await store.registerNotificationToken(); |
| 139 | + checkLastRequest(token: '012abc'); |
| 140 | + |
| 141 | + // If the token changes, send it again. |
| 142 | + testBinding.firebaseMessaging.setToken('456def'); |
| 143 | + connection.prepare(json: {}); |
| 144 | + await null; // Run microtasks. TODO use FakeAsync for these tests. |
| 145 | + checkLastRequest(token: '456def'); |
| 146 | + }); |
| 147 | + |
| 148 | + test('token initially unknown', () async { |
| 149 | + // This tests the case where the store is created while our |
| 150 | + // request for the token is still pending. |
| 151 | + addTearDown(testBinding.reset); |
| 152 | + testBinding.firebaseMessagingInitialToken = '012abc'; |
| 153 | + addTearDown(NotificationService.debugReset); |
| 154 | + final startFuture = NotificationService.instance.start(); |
| 155 | + |
| 156 | + // On store startup, send nothing (because we have nothing to send). |
| 157 | + prepareStore(); |
| 158 | + await store.registerNotificationToken(); |
| 159 | + check(connection.lastRequest).isNull(); |
| 160 | + |
| 161 | + // When the token later appears, send it. |
| 162 | + connection.prepare(json: {}); |
| 163 | + await startFuture; |
| 164 | + checkLastRequest(token: '012abc'); |
| 165 | + |
| 166 | + // If the token subsequently changes, send it again. |
| 167 | + testBinding.firebaseMessaging.setToken('456def'); |
| 168 | + connection.prepare(json: {}); |
| 169 | + await null; // Run microtasks. TODO use FakeAsync for these tests. |
| 170 | + checkLastRequest(token: '456def'); |
| 171 | + }); |
| 172 | + }); |
103 | 173 | }
|
104 | 174 |
|
105 | 175 | class LoadingTestGlobalStore extends TestGlobalStore {
|
|
0 commit comments