Skip to content

Commit

Permalink
fix tests
Browse files Browse the repository at this point in the history
  • Loading branch information
stevensJourney committed Oct 30, 2024
1 parent bf8cd83 commit f42b9a8
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 103 deletions.
3 changes: 3 additions & 0 deletions packages/powersync/lib/src/streaming_sync.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,9 @@ class StreamingSyncImplementation {
}
}
} finally {
// The client should no longer be connected at this point
// Adding this update allows for breaking out of an in-progress updateLoop
_updateStatus(connected: false);
_abort!.completeAbort();
}
}
Expand Down
219 changes: 116 additions & 103 deletions packages/powersync/test/connected_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,115 +14,128 @@ import 'utils/test_utils_impl.dart';
final testUtils = TestUtils();

void main() {
late TestHttpServerHelper testServer;
late String path;

setUp(() async {
path = testUtils.dbPath();
testServer = TestHttpServerHelper();
await testServer.start();
});

tearDown(() async {
await testUtils.cleanDb(path: path);
await testServer.stop();
});

test('should connect to mock PowerSync instance', () async {
final connector = TestConnector(() async {
return PowerSyncCredentials(
endpoint: testServer.uri.toString(),
token: 'token not used here',
expiresAt: DateTime.now());
group('connected tests', () {
late String path;
setUp(() async {
path = testUtils.dbPath();
});

final db = PowerSyncDatabase.withFactory(
await testUtils.testFactory(path: path),
schema: defaultSchema,
maxReaders: 3);
await db.initialize();

final connectedCompleter = Completer();

db.statusStream.listen((status) {
if (status.connected) {
connectedCompleter.complete();
}
tearDown(() async {
// await testUtils.cleanDb(path: path);
});

// Add a basic command for the test server to send
testServer.addEvent('{"token_expires_in": 3600}\n');

await db.connect(connector: connector);
await connectedCompleter.future;

expect(db.connected, isTrue);
});

test('should trigger uploads when connection is re-established', () async {
int uploadCounter = 0;
Completer uploadTriggeredCompleter = Completer();

final connector = TestConnector(() async {
return PowerSyncCredentials(
endpoint: testServer.uri.toString(),
token: 'token not used here',
expiresAt: DateTime.now());
}, uploadData: (database) async {
uploadCounter++;
uploadTriggeredCompleter.complete();
throw Exception('No uploads occur here');
createTestServer() async {
final testServer = TestHttpServerHelper();
await testServer.start();
return testServer;
}

test('should connect to mock PowerSync instance', () async {
final testServer = await createTestServer();
// Cant do this inside the createTestServer function unfortunately
addTearDown(() => testServer.stop());

final connector = TestConnector(() async {
return PowerSyncCredentials(
endpoint: testServer.uri.toString(),
token: 'token not used here',
expiresAt: DateTime.now());
});

final db = PowerSyncDatabase.withFactory(
await testUtils.testFactory(path: path),
schema: defaultSchema,
maxReaders: 3);
await db.initialize();

final connectedCompleter = Completer();

db.statusStream.listen((status) {
if (status.connected) {
connectedCompleter.complete();
}
});

// Add a basic command for the test server to send
testServer.addEvent('{"token_expires_in": 3600}\n');

await db.connect(connector: connector);
await connectedCompleter.future;

expect(db.connected, isTrue);
await db.disconnect();
});

final db = PowerSyncDatabase.withFactory(
await testUtils.testFactory(path: path),
schema: defaultSchema,
maxReaders: 3);
await db.initialize();

// Create an item which should trigger an upload.
await db.execute(
'INSERT INTO customers (id, name) VALUES (uuid(), ?)', ['steven']);

// Create a new completer to await the next upload
uploadTriggeredCompleter = Completer();

// Connect the PowerSync instance
final connectedCompleter = Completer();
// The first connection attempt will fail
final connectedErroredCompleter = Completer();

db.statusStream.listen((status) {
if (status.connected) {
connectedCompleter.complete();
}
if (status.downloadError != null &&
!connectedErroredCompleter.isCompleted) {
connectedErroredCompleter.complete();
}
test('should trigger uploads when connection is re-established', () async {
int uploadCounter = 0;
Completer uploadTriggeredCompleter = Completer();
final testServer = await createTestServer();
// Cant do this inside the createTestServer function unfortunately
addTearDown(() => testServer.stop());

final connector = TestConnector(() async {
return PowerSyncCredentials(
endpoint: testServer.uri.toString(),
token: 'token not used here',
expiresAt: DateTime.now());
}, uploadData: (database) async {
uploadCounter++;
uploadTriggeredCompleter.complete();
throw Exception('No uploads occur here');
});

final db = PowerSyncDatabase.withFactory(
await testUtils.testFactory(path: path),
schema: defaultSchema,
maxReaders: 3);
await db.initialize();

// Create an item which should trigger an upload.
await db.execute(
'INSERT INTO customers (id, name) VALUES (uuid(), ?)', ['steven']);

// Create a new completer to await the next upload
uploadTriggeredCompleter = Completer();

// Connect the PowerSync instance
final connectedCompleter = Completer();
// The first connection attempt will fail
final connectedErroredCompleter = Completer();

db.statusStream.listen((status) {
if (status.connected && !connectedCompleter.isCompleted) {
connectedCompleter.complete();
}
if (status.downloadError != null &&
!connectedErroredCompleter.isCompleted) {
connectedErroredCompleter.complete();
}
});

// The first command will not be valid, this simulates a failed connection
testServer.addEvent('asdf\n');
await db.connect(connector: connector);

// The connect operation should have triggered an upload (even though it fails to connect)
await uploadTriggeredCompleter.future;
expect(uploadCounter, equals(1));
// Create a new completer for the next iteration
uploadTriggeredCompleter = Completer();

// Connection attempt should initially fail
await connectedErroredCompleter.future;
expect(db.currentStatus.anyError, isNotNull);

// Now send a valid command. Which will result in successful connection
await testServer.clearEvents();
testServer.addEvent('{"token_expires_in": 3600}\n');
await connectedCompleter.future;
expect(db.connected, isTrue);

await uploadTriggeredCompleter.future;
expect(uploadCounter, equals(2));

await db.disconnect();
});

// The first command will not be valid, this simulates a failed connection
testServer.addEvent('asdf\n');
await db.connect(connector: connector);

// The connect operation should have triggered an upload (even though it fails to connect)
await uploadTriggeredCompleter.future;
expect(uploadCounter, equals(1));
// Create a new completer for the next iteration
uploadTriggeredCompleter = Completer();

// Connection attempt should initially fail
await connectedErroredCompleter.future;
expect(db.currentStatus.anyError, isNotNull);

// Now send a valid command. Which will result in successful connection
await testServer.clearEvents();
testServer.addEvent('{"token_expires_in": 3600}\n');
await connectedCompleter.future;
expect(db.connected, isTrue);

await uploadTriggeredCompleter.future;
expect(uploadCounter, equals(2));
});
}

0 comments on commit f42b9a8

Please sign in to comment.