test(sync): test devices sync through their sync service
A test device synced by calling the engine itself, so its repositories never heard of what a sync merged; reading the database each time, they didn't need to. Since cards and reviews are kept until something changes them, a device went on reading its cards from before the sync, and the conflict test failed. Devices now sync through their SyncService, as the app does, and fail when the sync failed. SYNC_TEST_SERVER_DIR names the server folder whose database the SQL checks read, for a worktree testing against another checkout's running server. All 30 sync tests pass. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
This commit is contained in:
parent
99f5ab77c9
commit
f1fee7e63c
1 changed files with 27 additions and 7 deletions
|
|
@ -68,7 +68,10 @@ Future<pg.Result> queryServer(
|
|||
}
|
||||
|
||||
Future<pg.Connection> _openServerDatabase() async {
|
||||
const server = '../halkyon_learn_server';
|
||||
// A worktree's tests run against the server `serverpod start` runs, which
|
||||
// may be another checkout's: SYNC_TEST_SERVER_DIR names its server folder.
|
||||
final server =
|
||||
Platform.environment['SYNC_TEST_SERVER_DIR'] ?? '../halkyon_learn_server';
|
||||
const settings = pg.ConnectionSettings(sslMode: pg.SslMode.disable);
|
||||
final development = loadYaml(
|
||||
File('$server/config/development.yaml').readAsStringSync(),
|
||||
|
|
@ -169,9 +172,17 @@ final class SyncDevice(
|
|||
database.path,
|
||||
persistentUserId: space,
|
||||
);
|
||||
// The gateways ask for a sync after every write; these tests sync
|
||||
// explicitly instead, so the requests go nowhere.
|
||||
final syncRequests = SyncService(({required onMerge}) async {});
|
||||
// Syncs as the app's do, so what a sync merges reaches the repositories
|
||||
// (which keep what they read until then). The gateways ask for a sync
|
||||
// after every write; these tests sync explicitly instead ([sync]), so
|
||||
// a request would wait a day.
|
||||
final syncRequests = SyncService(
|
||||
({required onMerge}) => client.offlineSync.syncOnce(
|
||||
db,
|
||||
onInboundMerge: (space) => onMerge(),
|
||||
),
|
||||
debounce: const Duration(days: 1),
|
||||
);
|
||||
final cards = CardRepository(
|
||||
SyncCardGateway(db, syncRequests, person.authUserId.uuid),
|
||||
);
|
||||
|
|
@ -213,8 +224,17 @@ final class SyncDevice(
|
|||
/// Explore).
|
||||
protocol.Client get client => _client;
|
||||
|
||||
/// Sends this device's changes and receives everyone else's.
|
||||
Future<void> sync() => _client.offlineSync.syncOnce(_db);
|
||||
/// Sends this device's changes and receives everyone else's, through
|
||||
/// its sync service, as the app syncs; throws when the sync failed.
|
||||
Future<void> sync() async {
|
||||
final done = _syncRequests.statusChanges.firstWhere(
|
||||
(status) => !status.syncing,
|
||||
);
|
||||
_syncRequests.syncNow();
|
||||
if ((await done).failure != null) {
|
||||
throw StateError('The sync failed; the log says why.');
|
||||
}
|
||||
}
|
||||
|
||||
/// The studyset with [id] on this device, or null.
|
||||
Future<Studyset?> studyset(String id) async {
|
||||
|
|
|
|||
Loading…
Reference in a new issue