@@ -44,6 +44,7 @@ void main() {
4444 await testUtils.testFactory (path: path),
4545 schema: defaultSchema,
4646 maxReaders: 3 );
47+ addTearDown (() => {db.close ()});
4748 await db.initialize ();
4849
4950 final connectedCompleter = Completer ();
@@ -83,6 +84,9 @@ void main() {
8384 await testUtils.testFactory (path: path),
8485 schema: defaultSchema,
8586 maxReaders: 3 );
87+ // Shorter retry delay, to speed up tests
88+ db.retryDelay = Duration (milliseconds: 10 );
89+ addTearDown (() => {db.close ()});
8690 await db.initialize ();
8791
8892 // Create an item which should trigger an upload.
@@ -132,5 +136,111 @@ void main() {
132136
133137 await db.disconnect ();
134138 });
139+
140+ test ('should persist local changes when there is no write checkpoint' ,
141+ () async {
142+ final testServer = await createTestServer ();
143+ final connector = TestConnector (() async {
144+ return PowerSyncCredentials (
145+ endpoint: testServer.uri.toString (),
146+ token: 'token not used here' ,
147+ expiresAt: DateTime .now ());
148+ }, uploadData: (database) async {
149+ final tx = await database.getNextCrudTransaction ();
150+ if (tx != null ) {
151+ await tx.complete ();
152+ }
153+ });
154+
155+ final db = PowerSyncDatabase .withFactory (
156+ await testUtils.testFactory (path: path),
157+ schema: defaultSchema,
158+ maxReaders: 3 );
159+ addTearDown (() => {db.close ()});
160+ await db.initialize ();
161+
162+ // Create an item which should trigger an upload.
163+ await db.execute (
164+ 'INSERT INTO customers (id, name) VALUES (uuid(), ?)' , ['steven' ]);
165+
166+ // Manually simulate upload before connecting.
167+ // This is simpler than doing this via connect() and waiting for it to complete.
168+ await connector.uploadData (db);
169+
170+ // Check that the data is present locally
171+ expect (
172+ await db.getAll ('select name from customers' ),
173+ equals ([
174+ {'name' : 'steven' }
175+ ]));
176+
177+ // Connect and send a checkpoint back, but no write checkpoint.
178+ testServer
179+ .addEvent ('{"checkpoint": {"last_op_id": "10", "buckets": []}}\n ' );
180+ testServer.addEvent ('{"checkpoint_complete": {"last_op_id": "10"}}\n ' );
181+
182+ // Now connect and wait for sync to complete
183+ await db.connect (connector: connector);
184+ await db.statusStream
185+ .firstWhere ((status) => status.connected && status.downloading);
186+ await Future .delayed (Duration (milliseconds: 20 ));
187+ expect (
188+ await db.getAll ('select name from customers' ),
189+ equals ([
190+ {'name' : 'steven' }
191+ ]));
192+ });
193+
194+ test ('should remove local changes when there a write checkpoint' , () async {
195+ // The only difference between this and the one above, is that the synced
196+ // checkpoint here contains a write checkpoint, matching the write-checkpoint2.json
197+ // API. This will trigger the local changes to be removed.
198+ final testServer = await createTestServer ();
199+ final connector = TestConnector (() async {
200+ return PowerSyncCredentials (
201+ endpoint: testServer.uri.toString (),
202+ token: 'token not used here' ,
203+ expiresAt: DateTime .now ());
204+ }, uploadData: (database) async {
205+ final tx = await database.getNextCrudTransaction ();
206+ if (tx != null ) {
207+ await tx.complete ();
208+ }
209+ });
210+
211+ final db = PowerSyncDatabase .withFactory (
212+ await testUtils.testFactory (path: path),
213+ schema: defaultSchema,
214+ maxReaders: 3 );
215+ addTearDown (() => {db.close ()});
216+ await db.initialize ();
217+
218+ // Create an item which should trigger an upload.
219+ await db.execute (
220+ 'INSERT INTO customers (id, name) VALUES (uuid(), ?)' , ['steven' ]);
221+
222+ // Manually simulate upload before connecting.
223+ // This is simpler than doing this via connect() and waiting for it to complete.
224+ await connector.uploadData (db);
225+
226+ // Check that the data is present locally
227+ expect (
228+ await db.getAll ('select name from customers' ),
229+ equals ([
230+ {'name' : 'steven' }
231+ ]));
232+
233+ // Connect and send a checkpoint back, but no write checkpoint.
234+ testServer.addEvent (
235+ '{"checkpoint": {"last_op_id": "10", "buckets": [], "write_checkpoint": "10"}}\n ' );
236+ testServer.addEvent ('{"checkpoint_complete": {"last_op_id": "10"}}\n ' );
237+
238+ // Now connect and wait for sync to complete
239+ await db.connect (connector: connector);
240+ await db.statusStream
241+ .firstWhere ((status) => status.connected && status.downloading);
242+ await Future .delayed (Duration (milliseconds: 20 ));
243+ expect (await db.getAll ('select name from customers' ), equals ([]));
244+ });
135245 });
136246}
0 commit comments