Skip to content
This repository was archived by the owner on Oct 9, 2025. It is now read-only.

Commit 74626c8

Browse files
committed
chore: add extra tests for coverage
1 parent 3fed9ba commit 74626c8

9 files changed

+781
-71
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@ docs/v2
44
.env
55
.nyc_output
66
coverage/
7-
.claude/settings.local.json
7+
.claude/settings.local.json
8+
.DS_Store

test/RealtimeChannel.lifecycle.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -532,7 +532,7 @@ describe('Channel Lifecycle Management', () => {
532532
test('_rejoin does nothing when channel state is leaving', () => {
533533
// Set up channel to be in 'leaving' state
534534
channel.state = CHANNEL_STATES.leaving
535-
535+
536536
// Spy on socket methods to verify no actions are taken
537537
const leaveOpenTopicSpy = vi.spyOn(testSetup.socket, '_leaveOpenTopic')
538538
const resendSpy = vi.spyOn(channel.joinPush, 'resend')

test/RealtimeChannel.postgres.test.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,7 +599,10 @@ describe('PostgreSQL payload transformation', () => {
599599
table: 'users',
600600
commit_timestamp: '2023-01-01T00:00:00Z',
601601
errors: [],
602-
columns: [{ name: 'id', type: 'int4' }, { name: 'name', type: 'text' }],
602+
columns: [
603+
{ name: 'id', type: 'int4' },
604+
{ name: 'name', type: 'text' },
605+
],
603606
record: { id: 1, name: 'updated' },
604607
old_record: { id: 1, name: 'original' },
605608
},
@@ -627,7 +630,10 @@ describe('PostgreSQL payload transformation', () => {
627630
table: 'users',
628631
commit_timestamp: '2023-01-01T00:00:00Z',
629632
errors: [],
630-
columns: [{ name: 'id', type: 'int4' }, { name: 'name', type: 'text' }],
633+
columns: [
634+
{ name: 'id', type: 'int4' },
635+
{ name: 'name', type: 'text' },
636+
],
631637
old_record: { id: 2, name: 'deleted' },
632638
},
633639
},

test/RealtimeChannel.presence.test.ts

Lines changed: 113 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -136,30 +136,35 @@ describe('Presence message filtering', () => {
136136
describe('Presence helper methods', () => {
137137
test('gets presence state', () => {
138138
channel.presence.state = { u1: [{ id: 1, presence_ref: '1' }] }
139-
assert.deepEqual(channel.presenceState(), { u1: [{ id: 1, presence_ref: '1' }] })
139+
assert.deepEqual(channel.presenceState(), {
140+
u1: [{ id: 1, presence_ref: '1' }],
141+
})
140142
})
141143

142144
test.each([
143145
{
144146
method: 'track',
145147
payload: { id: 123 },
146148
expectedCall: { type: 'presence', event: 'track', payload: { id: 123 } },
147-
timeout: 1000
149+
timeout: 1000,
148150
},
149151
{
150-
method: 'untrack',
152+
method: 'untrack',
151153
payload: undefined,
152154
expectedCall: { type: 'presence', event: 'untrack' },
153-
timeout: {}
154-
}
155-
])('$method presence via send method', async ({ method, payload, expectedCall, timeout }) => {
156-
setupJoinedChannelWithSocket(channel, testSetup.socket)
157-
const sendStub = vi.spyOn(channel, 'send').mockResolvedValue('ok')
155+
timeout: {},
156+
},
157+
])(
158+
'$method presence via send method',
159+
async ({ method, payload, expectedCall, timeout }) => {
160+
setupJoinedChannelWithSocket(channel, testSetup.socket)
161+
const sendStub = vi.spyOn(channel, 'send').mockResolvedValue('ok')
158162

159-
await (payload ? channel[method](payload) : channel[method]())
163+
await (payload ? channel[method](payload) : channel[method]())
160164

161-
expect(sendStub).toHaveBeenCalledWith(expectedCall, timeout)
162-
})
165+
expect(sendStub).toHaveBeenCalledWith(expectedCall, timeout)
166+
}
167+
)
163168
})
164169

165170
describe('RealtimePresence static methods', () => {
@@ -197,8 +202,10 @@ describe('RealtimePresence static methods', () => {
197202
initialState: {},
198203
newState: { u1: [{ id: 1, presence_ref: '1' }] },
199204
expectedResult: { u1: [{ id: 1, presence_ref: '1' }] },
200-
expectedJoined: { u1: { current: [], newPres: [{ id: 1, presence_ref: '1' }] } },
201-
expectedLeft: {}
205+
expectedJoined: {
206+
u1: { current: [], newPres: [{ id: 1, presence_ref: '1' }] },
207+
},
208+
expectedLeft: {},
202209
},
203210
{
204211
name: 'should handle onJoin and onLeave callbacks',
@@ -212,7 +219,7 @@ describe('RealtimePresence static methods', () => {
212219
},
213220
expectedLeft: {
214221
u4: { current: [], leftPres: [{ id: 4, presence_ref: '4' }] },
215-
}
222+
},
216223
},
217224
{
218225
name: 'should only join newly added presences',
@@ -233,30 +240,44 @@ describe('RealtimePresence static methods', () => {
233240
u3: {
234241
current: [{ id: 3, presence_ref: '3' }],
235242
newPres: [{ id: 3, presence_ref: '3.new' }],
236-
}
243+
},
237244
},
238-
expectedLeft: {}
239-
}
240-
])('$name', ({ initialState, newState, expectedResult, expectedJoined, expectedLeft }) => {
241-
const stateBefore = clone(initialState)
242-
const joined: any = {}
243-
const left: any = {}
245+
expectedLeft: {},
246+
},
247+
])(
248+
'$name',
249+
({
250+
initialState,
251+
newState,
252+
expectedResult,
253+
expectedJoined,
254+
expectedLeft,
255+
}) => {
256+
const stateBefore = clone(initialState)
257+
const joined: any = {}
258+
const left: any = {}
259+
260+
const onJoin = (key: string, current: any, newPres: any) => {
261+
joined[key] = { current, newPres }
262+
}
263+
const onLeave = (key: string, current: any, leftPres: any) => {
264+
left[key] = { current, leftPres }
265+
}
244266

245-
const onJoin = (key: string, current: any, newPres: any) => {
246-
joined[key] = { current, newPres }
247-
}
248-
const onLeave = (key: string, current: any, leftPres: any) => {
249-
left[key] = { current, leftPres }
267+
// @ts-ignore - accessing static private method for testing
268+
const result = RealtimePresence.syncState(
269+
initialState,
270+
newState,
271+
onJoin,
272+
onLeave
273+
)
274+
275+
assert.deepEqual(initialState, stateBefore)
276+
assert.deepEqual(result, expectedResult)
277+
assert.deepEqual(joined, expectedJoined)
278+
assert.deepEqual(left, expectedLeft)
250279
}
251-
252-
// @ts-ignore - accessing static private method for testing
253-
const result = RealtimePresence.syncState(initialState, newState, onJoin, onLeave)
254-
255-
assert.deepEqual(initialState, stateBefore)
256-
assert.deepEqual(result, expectedResult)
257-
assert.deepEqual(joined, expectedJoined)
258-
assert.deepEqual(left, expectedLeft)
259-
})
280+
)
260281
})
261282

262283
describe('syncDiff and utility methods', () => {
@@ -265,16 +286,19 @@ describe('RealtimePresence static methods', () => {
265286
name: 'sync empty state with joins',
266287
initialState: {},
267288
diff: { joins: { u1: [{ id: 1, presence_ref: '1' }] }, leaves: {} },
268-
expected: { u1: [{ id: 1, presence_ref: '1' }] }
289+
expected: { u1: [{ id: 1, presence_ref: '1' }] },
269290
},
270291
{
271292
name: 'add presence and remove empty key',
272293
initialState: fixtures.state(),
273294
diff: { joins: fixtures.joins(), leaves: fixtures.leaves() },
274295
expected: {
275-
u1: [{ id: 1, presence_ref: '1' }, { id: 1, presence_ref: '1.2' }],
276-
u3: [{ id: 3, presence_ref: '3' }]
277-
}
296+
u1: [
297+
{ id: 1, presence_ref: '1' },
298+
{ id: 1, presence_ref: '1.2' },
299+
],
300+
u3: [{ id: 3, presence_ref: '3' }],
301+
},
278302
},
279303
{
280304
name: 'remove presence while leaving key if others exist',
@@ -285,38 +309,59 @@ describe('RealtimePresence static methods', () => {
285309
],
286310
},
287311
diff: { joins: {}, leaves: { u1: [{ id: 1, presence_ref: '1' }] } },
288-
expected: { u1: [{ id: 1, presence_ref: '1.2' }] }
312+
expected: { u1: [{ id: 1, presence_ref: '1.2' }] },
289313
},
290314
{
291315
name: 'handle undefined callbacks',
292316
initialState: { u1: [{ id: 1, presence_ref: '1' }] },
293-
diff: { joins: { u2: [{ id: 2, presence_ref: '2' }] }, leaves: { u1: [{ id: 1, presence_ref: '1' }] } },
317+
diff: {
318+
joins: { u2: [{ id: 2, presence_ref: '2' }] },
319+
leaves: { u1: [{ id: 1, presence_ref: '1' }] },
320+
},
294321
expected: { u2: [{ id: 2, presence_ref: '2' }] },
295-
useUndefinedCallbacks: true
322+
useUndefinedCallbacks: true,
323+
},
324+
])(
325+
'syncDiff: $name',
326+
({ initialState, diff, expected, useUndefinedCallbacks }) => {
327+
// @ts-ignore - accessing static private method for testing
328+
const result = useUndefinedCallbacks
329+
? RealtimePresence.syncDiff(initialState, diff, undefined, undefined)
330+
: RealtimePresence.syncDiff(initialState, diff)
331+
332+
assert.deepEqual(result, expected)
296333
}
297-
])('syncDiff: $name', ({ initialState, diff, expected, useUndefinedCallbacks }) => {
298-
// @ts-ignore - accessing static private method for testing
299-
const result = useUndefinedCallbacks
300-
? RealtimePresence.syncDiff(initialState, diff, undefined, undefined)
301-
: RealtimePresence.syncDiff(initialState, diff)
302-
303-
assert.deepEqual(result, expected)
304-
})
334+
)
305335

306336
test('static utility methods work correctly', () => {
307337
// Test map function
308-
const state = { u1: [{ id: 1, presence_ref: '1' }], u2: [{ id: 2, presence_ref: '2' }] }
338+
const state = {
339+
u1: [{ id: 1, presence_ref: '1' }],
340+
u2: [{ id: 2, presence_ref: '2' }],
341+
}
309342
// @ts-ignore - accessing static private method for testing
310-
const mapResult = RealtimePresence.map(state, (key, presences) => ({ key, count: presences.length }))
311-
assert.deepEqual(mapResult, [{ key: 'u1', count: 1 }, { key: 'u2', count: 1 }])
343+
const mapResult = RealtimePresence.map(state, (key, presences) => ({
344+
key,
345+
count: presences.length,
346+
}))
347+
assert.deepEqual(mapResult, [
348+
{ key: 'u1', count: 1 },
349+
{ key: 'u2', count: 1 },
350+
])
312351

313352
// Test transformState function
314353
const rawState = {
315-
u1: { metas: [{ id: 1, phx_ref: '1', phx_ref_prev: 'prev1', name: 'User 1' }] }
354+
u1: {
355+
metas: [
356+
{ id: 1, phx_ref: '1', phx_ref_prev: 'prev1', name: 'User 1' },
357+
],
358+
},
316359
}
317360
// @ts-ignore - accessing static private method for testing
318361
const transformResult = RealtimePresence.transformState(rawState)
319-
assert.deepEqual(transformResult, { u1: [{ id: 1, presence_ref: '1', name: 'User 1' }] })
362+
assert.deepEqual(transformResult, {
363+
u1: [{ id: 1, presence_ref: '1', name: 'User 1' }],
364+
})
320365
assert.ok(!transformResult.u1[0].hasOwnProperty('phx_ref'))
321366

322367
// Test cloneDeep function
@@ -334,23 +379,31 @@ describe('RealtimePresence static methods', () => {
334379
// Test custom channel events
335380
const customChannel = testSetup.socket.channel('custom-presence')
336381
const customPresence = new RealtimePresence(customChannel, {
337-
events: { state: 'custom_state', diff: 'custom_diff' }
382+
events: { state: 'custom_state', diff: 'custom_diff' },
383+
})
384+
385+
customChannel._trigger('custom_state', {
386+
user1: { metas: [{ id: 1, phx_ref: '1' }] },
338387
})
339-
340-
customChannel._trigger('custom_state', { user1: { metas: [{ id: 1, phx_ref: '1' }] } })
341388
assert.ok(customPresence.state.user1)
342389
assert.equal(customPresence.state.user1[0].presence_ref, '1')
343390

344391
// Test pending diffs behavior
345392
const presence = new RealtimePresence(channel)
346393

347394
// Send diff before state (should be pending)
348-
channel._trigger('presence_diff', { joins: {}, leaves: { u2: [{ id: 2, presence_ref: '2' }] } })
395+
channel._trigger('presence_diff', {
396+
joins: {},
397+
leaves: { u2: [{ id: 2, presence_ref: '2' }] },
398+
})
349399
assert.equal(presence.pendingDiffs.length, 1)
350400

351401
// Send state (should apply pending diffs)
352402
channel.joinPush.ref = 'test-ref'
353-
channel._trigger('presence_state', { u1: [{ id: 1, presence_ref: '1' }], u2: [{ id: 2, presence_ref: '2' }] })
403+
channel._trigger('presence_state', {
404+
u1: [{ id: 1, presence_ref: '1' }],
405+
u2: [{ id: 2, presence_ref: '2' }],
406+
})
354407
assert.equal(presence.pendingDiffs.length, 0)
355408
})
356409
})

test/RealtimeClient.config.test.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,6 @@ describe('endpointURL', () => {
5151
})
5252
// Clear params after construction to test empty params scenario
5353
socket.params = {}
54-
assert.equal(
55-
socket.endpointURL(),
56-
`${testSetup.url}/websocket?vsn=1.0.0`
57-
)
54+
assert.equal(socket.endpointURL(), `${testSetup.url}/websocket?vsn=1.0.0`)
5855
})
5956
})

0 commit comments

Comments
 (0)