Skip to content

Commit 1bcc7a4

Browse files
committed
Added initial sync status tests to web.
1 parent 076b4ee commit 1bcc7a4

File tree

2 files changed

+105
-1
lines changed

2 files changed

+105
-1
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
import { describe, expect, it } from 'vitest';
2+
import { ConnectedDatabaseUtils, generateConnectedDatabase } from './utils/generateConnectedDatabase';
3+
4+
const UPLOAD_TIMEOUT_MS = 3000;
5+
6+
describe(
7+
'Sync Status when streaming',
8+
{ sequential: true },
9+
describeSyncStatusStreamingTests(() =>
10+
generateConnectedDatabase({
11+
powerSyncOptions: {
12+
flags: {
13+
useWebWorker: false,
14+
enableMultiTabs: false
15+
}
16+
}
17+
})
18+
)
19+
);
20+
21+
function describeSyncStatusStreamingTests(createConnectedDatabase: () => Promise<ConnectedDatabaseUtils>) {
22+
return () => {
23+
it('Should have downloadError on stream failure', async () => {
24+
const { powersync, waitForStream, remote, connector } = await createConnectedDatabase();
25+
remote.errorOnStreamStart = true;
26+
27+
// Making sure the field change takes effect
28+
const newStream = waitForStream();
29+
remote.streamController?.close();
30+
await newStream;
31+
32+
let resolveDownloadError: () => void;
33+
const downloadErrorPromise = new Promise<void>((resolve) => {
34+
resolveDownloadError = resolve;
35+
});
36+
let receivedUploadError = false;
37+
38+
powersync.registerListener({
39+
statusChanged: (status) => {
40+
if (status.dataFlowStatus.downloadError) {
41+
resolveDownloadError();
42+
receivedUploadError = true;
43+
}
44+
}
45+
});
46+
47+
// Download error should be specified
48+
await downloadErrorPromise;
49+
});
50+
51+
it('Should have uploadError on failed uploads', async () => {
52+
const { powersync, uploadSpy } = await createConnectedDatabase();
53+
expect(powersync.connected).toBe(true);
54+
55+
let uploadCounter = 0;
56+
// This test will throw an exception a few times before successfully uploading
57+
const throwCounter = 2;
58+
uploadSpy.mockImplementation(async (db) => {
59+
if (uploadCounter++ < throwCounter) {
60+
throw new Error(`Force upload error`);
61+
}
62+
// Now actually do the upload
63+
const tx = await db.getNextCrudTransaction();
64+
await tx?.complete();
65+
});
66+
67+
let resolveUploadError: () => void;
68+
const uploadErrorPromise = new Promise<void>((resolve) => {
69+
resolveUploadError = resolve;
70+
});
71+
let receivedUploadError = false;
72+
73+
let resolveClearedUploadError: () => void;
74+
const clearedUploadErrorPromise = new Promise<void>((resolve) => {
75+
resolveClearedUploadError = resolve;
76+
});
77+
78+
powersync.registerListener({
79+
statusChanged: (status) => {
80+
if (status.dataFlowStatus.uploadError) {
81+
resolveUploadError();
82+
receivedUploadError = true;
83+
} else if (receivedUploadError) {
84+
resolveClearedUploadError();
85+
}
86+
}
87+
});
88+
89+
// do something which should trigger an upload
90+
await powersync.execute('INSERT INTO users (id, name) VALUES (uuid(), ?)', ['name']);
91+
92+
// Upload error should be specified
93+
await uploadErrorPromise;
94+
95+
// Upload error should be cleared after successful upload
96+
await clearedUploadErrorPromise;
97+
});
98+
};
99+
}

packages/web/tests/utils/MockStreamOpenFactory.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class TestConnector implements PowerSyncBackendConnector {
3434

3535
export class MockRemote extends AbstractRemote {
3636
streamController: ReadableStreamDefaultController<StreamingSyncLine> | null;
37-
37+
errorOnStreamStart = false;
3838
constructor(
3939
connector: RemoteConnector,
4040
protected onStreamRequested: () => void
@@ -61,6 +61,7 @@ export class MockRemote extends AbstractRemote {
6161
}
6262
throw new Error('Not implemented');
6363
}
64+
6465
async postStreaming(
6566
path: string,
6667
data: any,
@@ -71,6 +72,10 @@ export class MockRemote extends AbstractRemote {
7172
start: (controller) => {
7273
this.streamController = controller;
7374
this.onStreamRequested();
75+
if (this.errorOnStreamStart) {
76+
controller.error(new Error('Mock error on stream start'));
77+
}
78+
7479
signal?.addEventListener('abort', () => {
7580
try {
7681
controller.close();

0 commit comments

Comments
 (0)