Skip to content

Commit 7480353

Browse files
committed
Fix unit test for loading more data via requestSnapshot in the Electric collection
1 parent 06df69f commit 7480353

File tree

2 files changed

+75
-36
lines changed

2 files changed

+75
-36
lines changed

packages/electric-db-collection/src/electric.ts

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@ import {
1515
import { compileSQL } from "./sql-compiler"
1616
import type {
1717
BaseCollectionConfig,
18-
Collection,
1918
CollectionConfig,
2019
DeleteMutationFnParams,
2120
Fn,
2221
InsertMutationFnParams,
23-
OnLoadMoreOptions,
2422
SyncConfig,
2523
UpdateMutationFnParams,
2624
UtilsRecord,
@@ -420,9 +418,9 @@ function createElectricSync<T extends Row<unknown>>(
420418
})
421419

422420
return {
423-
onLoadMore: (opts) => {
421+
onLoadMore: async (opts) => {
424422
const snapshotParams = compileSQL<T>(opts)
425-
return stream.requestSnapshot(snapshotParams)
423+
await stream.requestSnapshot(snapshotParams)
426424
},
427425
cleanup: () => {
428426
// Unsubscribe from the stream
@@ -436,4 +434,3 @@ function createElectricSync<T extends Row<unknown>>(
436434
getSyncMetadata,
437435
}
438436
}
439-

packages/electric-db-collection/tests/electric-live-query.test.ts

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -57,25 +57,34 @@ const mockSubscribe = vi.fn()
5757
const mockRequestSnapshot = vi.fn()
5858
const mockStream = {
5959
subscribe: mockSubscribe,
60-
requestSnapshot: (...args: any) => {
61-
mockRequestSnapshot(...args)
62-
const results = mockRequestSnapshot.mock.results
63-
const lastResult = results[results.length - 1]!.value
64-
65-
const subscribers = mockSubscribe.mock.calls.map(args => args[0])
66-
subscribers.forEach(subscriber => subscriber(lastResult.data.map((row: any) => ({
67-
type: `insert`,
60+
requestSnapshot: async (...args: any) => {
61+
const result = await mockRequestSnapshot(...args)
62+
const subscribers = mockSubscribe.mock.calls.map((args) => args[0])
63+
const data = [...result.data]
64+
65+
const messages: Array<Message<any>> = data.map((row: any) => ({
6866
value: row.value,
6967
key: row.key,
70-
}))))
71-
}
68+
headers: row.headers,
69+
}))
70+
71+
if (messages.length > 0) {
72+
// add an up-to-date message
73+
messages.push({
74+
headers: { control: `up-to-date` },
75+
})
76+
}
77+
78+
subscribers.forEach((subscriber) => subscriber(messages))
79+
return result
80+
},
7281
}
7382

7483
// Mock the requestSnapshot method
7584
// to return an empty array of data
7685
// since most tests don't use it
7786
mockRequestSnapshot.mockResolvedValue({
78-
data: []
87+
data: [],
7988
})
8089

8190
vi.mock(`@electric-sql/client`, async () => {
@@ -360,14 +369,9 @@ describe.each([
360369
})
361370

362371
if (autoIndex === `eager`) {
363-
it.only(`should load more data via requestSnapshot when creating live query with higher limit`, async () => {
364-
// Reset mocks
365-
vi.clearAllMocks()
372+
it(`should load more data via requestSnapshot when creating live query with higher limit`, async () => {
366373
mockRequestSnapshot.mockResolvedValue({
367-
data: [
368-
{ key: 5, value: { id: 5, name: `Eve`, age: 30, email: `[email protected]`, active: true } },
369-
{ key: 6, value: { id: 6, name: `Frank`, age: 35, email: `[email protected]`, active: true } },
370-
],
374+
data: [],
371375
})
372376

373377
// Initial sync with limited data
@@ -398,15 +402,45 @@ describe.each([
398402
expect(limitedLiveQuery.size).toBe(2) // Only first 2 active users
399403
expect(mockRequestSnapshot).toHaveBeenCalledTimes(1)
400404

401-
const callArgs = (index: number) => mockRequestSnapshot.mock.calls[index]?.[0]
405+
const callArgs = (index: number) =>
406+
mockRequestSnapshot.mock.calls[index]?.[0]
402407
expect(callArgs(0)).toMatchObject({
403-
params: { "1": "true" },
404-
where: "active = $1",
405-
orderBy: "age NULLS FIRST",
408+
params: { "1": `true` },
409+
where: `active = $1`,
410+
orderBy: `age NULLS FIRST`,
406411
limit: 2,
407412
})
408413

409-
// Create second live query with higher limit of 5
414+
// Next call will return a snapshot containing 2 rows
415+
// Calls after that will return the default empty snapshot
416+
mockRequestSnapshot.mockResolvedValueOnce({
417+
data: [
418+
{
419+
headers: { operation: `insert` },
420+
key: 5,
421+
value: {
422+
id: 5,
423+
name: `Eve`,
424+
age: 30,
425+
426+
active: true,
427+
},
428+
},
429+
{
430+
headers: { operation: `insert` },
431+
key: 6,
432+
value: {
433+
id: 6,
434+
name: `Frank`,
435+
age: 35,
436+
437+
active: true,
438+
},
439+
},
440+
],
441+
})
442+
443+
// Create second live query with higher limit of 6
410444
const expandedLiveQuery = createLiveQueryCollection({
411445
id: `expanded-users-live-query`,
412446
startSync: true,
@@ -427,26 +461,34 @@ describe.each([
427461
await new Promise((resolve) => setTimeout(resolve, 0))
428462

429463
// Verify that requestSnapshot was called with the correct parameters
430-
expect(mockRequestSnapshot).toHaveBeenCalledTimes(3)
464+
expect(mockRequestSnapshot).toHaveBeenCalledTimes(4)
431465

432466
// Check that first it requested a limit of 6 users
433467
expect(callArgs(1)).toMatchObject({
434-
params: { "1": "true" },
435-
where: "active = $1",
436-
orderBy: "age NULLS FIRST",
468+
params: { "1": `true` },
469+
where: `active = $1`,
470+
orderBy: `age NULLS FIRST`,
437471
limit: 6,
438472
})
439473

440474
// After this initial snapshot for the new live query it receives all 3 users from the local collection
441475
// so it still needs 3 more users to reach the limit of 6 so it requests 3 more to the sync layer
442476
expect(callArgs(2)).toMatchObject({
443-
params: { "1": "true", "2": "25" },
444-
where: "active = $1 AND age > $2",
445-
orderBy: "age NULLS FIRST",
477+
params: { "1": `true`, "2": `25` },
478+
where: `active = $1 AND age > $2`,
479+
orderBy: `age NULLS FIRST`,
446480
limit: 3,
447481
})
448482

449-
// The sync layer won't provide any more users so the DB is exhausted and it stops (i.e. doesn't request more)
483+
// The previous snapshot returned 2 more users so it still needs 1 more user to reach the limit of 6
484+
expect(callArgs(3)).toMatchObject({
485+
params: { "1": `true`, "2": `35` },
486+
where: `active = $1 AND age > $2`,
487+
orderBy: `age NULLS FIRST`,
488+
limit: 1,
489+
})
490+
491+
// The sync layer won't provide any more users so the DB is exhausted and it stops (i.e. doesn't request more)
450492

451493
// The expanded live query should now have more data
452494
expect(expandedLiveQuery.status).toBe(`ready`)

0 commit comments

Comments
 (0)