Skip to content

Commit 89917ba

Browse files
committed
Fix unit test for loading more data via requestSnapshot in the Electric collection
1 parent 874afb0 commit 89917ba

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 () => {
@@ -458,14 +467,9 @@ describe.each([
458467
subscription.unsubscribe()
459468
})
460469
if (autoIndex === `eager`) {
461-
it.only(`should load more data via requestSnapshot when creating live query with higher limit`, async () => {
462-
// Reset mocks
463-
vi.clearAllMocks()
470+
it(`should load more data via requestSnapshot when creating live query with higher limit`, async () => {
464471
mockRequestSnapshot.mockResolvedValue({
465-
data: [
466-
{ key: 5, value: { id: 5, name: `Eve`, age: 30, email: `[email protected]`, active: true } },
467-
{ key: 6, value: { id: 6, name: `Frank`, age: 35, email: `[email protected]`, active: true } },
468-
],
472+
data: [],
469473
})
470474

471475
// Initial sync with limited data
@@ -496,15 +500,45 @@ describe.each([
496500
expect(limitedLiveQuery.size).toBe(2) // Only first 2 active users
497501
expect(mockRequestSnapshot).toHaveBeenCalledTimes(1)
498502

499-
const callArgs = (index: number) => mockRequestSnapshot.mock.calls[index]?.[0]
503+
const callArgs = (index: number) =>
504+
mockRequestSnapshot.mock.calls[index]?.[0]
500505
expect(callArgs(0)).toMatchObject({
501-
params: { "1": "true" },
502-
where: "active = $1",
503-
orderBy: "age NULLS FIRST",
506+
params: { "1": `true` },
507+
where: `active = $1`,
508+
orderBy: `age NULLS FIRST`,
504509
limit: 2,
505510
})
506511

507-
// Create second live query with higher limit of 5
512+
// Next call will return a snapshot containing 2 rows
513+
// Calls after that will return the default empty snapshot
514+
mockRequestSnapshot.mockResolvedValueOnce({
515+
data: [
516+
{
517+
headers: { operation: `insert` },
518+
key: 5,
519+
value: {
520+
id: 5,
521+
name: `Eve`,
522+
age: 30,
523+
524+
active: true,
525+
},
526+
},
527+
{
528+
headers: { operation: `insert` },
529+
key: 6,
530+
value: {
531+
id: 6,
532+
name: `Frank`,
533+
age: 35,
534+
535+
active: true,
536+
},
537+
},
538+
],
539+
})
540+
541+
// Create second live query with higher limit of 6
508542
const expandedLiveQuery = createLiveQueryCollection({
509543
id: `expanded-users-live-query`,
510544
startSync: true,
@@ -525,26 +559,34 @@ describe.each([
525559
await new Promise((resolve) => setTimeout(resolve, 0))
526560

527561
// Verify that requestSnapshot was called with the correct parameters
528-
expect(mockRequestSnapshot).toHaveBeenCalledTimes(3)
562+
expect(mockRequestSnapshot).toHaveBeenCalledTimes(4)
529563

530564
// Check that first it requested a limit of 6 users
531565
expect(callArgs(1)).toMatchObject({
532-
params: { "1": "true" },
533-
where: "active = $1",
534-
orderBy: "age NULLS FIRST",
566+
params: { "1": `true` },
567+
where: `active = $1`,
568+
orderBy: `age NULLS FIRST`,
535569
limit: 6,
536570
})
537571

538572
// After this initial snapshot for the new live query it receives all 3 users from the local collection
539573
// so it still needs 3 more users to reach the limit of 6 so it requests 3 more to the sync layer
540574
expect(callArgs(2)).toMatchObject({
541-
params: { "1": "true", "2": "25" },
542-
where: "active = $1 AND age > $2",
543-
orderBy: "age NULLS FIRST",
575+
params: { "1": `true`, "2": `25` },
576+
where: `active = $1 AND age > $2`,
577+
orderBy: `age NULLS FIRST`,
544578
limit: 3,
545579
})
546580

547-
// The sync layer won't provide any more users so the DB is exhausted and it stops (i.e. doesn't request more)
581+
// The previous snapshot returned 2 more users so it still needs 1 more user to reach the limit of 6
582+
expect(callArgs(3)).toMatchObject({
583+
params: { "1": `true`, "2": `35` },
584+
where: `active = $1 AND age > $2`,
585+
orderBy: `age NULLS FIRST`,
586+
limit: 1,
587+
})
588+
589+
// The sync layer won't provide any more users so the DB is exhausted and it stops (i.e. doesn't request more)
548590

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

0 commit comments

Comments
 (0)