| 
8 | 8 |   TestSetup,  | 
9 | 9 |   setupJoinedChannelWithSocket,  | 
10 | 10 | } from './helpers/setup'  | 
 | 11 | +import { REALTIME_LISTEN_TYPES } from '../src/RealtimeChannel'  | 
11 | 12 | 
 
  | 
12 | 13 | const defaultTimeout = 1000  | 
13 | 14 | 
 
  | 
@@ -167,6 +168,96 @@ describe('Presence helper methods', () => {  | 
167 | 168 |   )  | 
168 | 169 | })  | 
169 | 170 | 
 
  | 
 | 171 | +describe('Presence configuration override', () => {  | 
 | 172 | +  test('should enable presence when config.presence.enabled is true even without bindings', () => {  | 
 | 173 | +    const channelWithPresenceEnabled = testSetup.socket.channel(  | 
 | 174 | +      'test-presence-override',  | 
 | 175 | +      { config: { presence: { enabled: true } } }  | 
 | 176 | +    )  | 
 | 177 | +    assert.equal(  | 
 | 178 | +      channelWithPresenceEnabled.bindings[REALTIME_LISTEN_TYPES.PRESENCE]  | 
 | 179 | +        ?.length,  | 
 | 180 | +      undefined  | 
 | 181 | +    )  | 
 | 182 | +    channelWithPresenceEnabled.subscribe()  | 
 | 183 | +    const joinPayload = channelWithPresenceEnabled.joinPush.payload  | 
 | 184 | +    assert.equal(joinPayload.config.presence.enabled, true)  | 
 | 185 | +    channelWithPresenceEnabled.unsubscribe()  | 
 | 186 | +  })  | 
 | 187 | + | 
 | 188 | +  test('should enable presence when both bindings exist and config.presence.enabled is true', () => {  | 
 | 189 | +    const channelWithBoth = testSetup.socket.channel('test-presence-both', {  | 
 | 190 | +      config: { presence: { enabled: true } },  | 
 | 191 | +    })  | 
 | 192 | +    channelWithBoth.on('presence', { event: 'sync' }, () => {})  | 
 | 193 | +    channelWithBoth.subscribe()  | 
 | 194 | +    const joinPayload = channelWithBoth.joinPush.payload  | 
 | 195 | +    assert.equal(joinPayload.config.presence.enabled, true)  | 
 | 196 | +    channelWithBoth.unsubscribe()  | 
 | 197 | +  })  | 
 | 198 | + | 
 | 199 | +  test('should enable presence when only bindings exist (existing behavior)', () => {  | 
 | 200 | +    const channelWithBindingsOnly = testSetup.socket.channel(  | 
 | 201 | +      'test-presence-bindings-only'  | 
 | 202 | +    )  | 
 | 203 | +    channelWithBindingsOnly.on('presence', { event: 'sync' }, () => {})  | 
 | 204 | +    channelWithBindingsOnly.subscribe()  | 
 | 205 | +    const joinPayload = channelWithBindingsOnly.joinPush.payload  | 
 | 206 | +    assert.equal(joinPayload.config.presence.enabled, true)  | 
 | 207 | +    channelWithBindingsOnly.unsubscribe()  | 
 | 208 | +  })  | 
 | 209 | + | 
 | 210 | +  test('should not enable presence when neither bindings exist nor config.presence.enabled is true', () => {  | 
 | 211 | +    const channelWithNeither = testSetup.socket.channel('test-presence-neither')  | 
 | 212 | +    assert.equal(  | 
 | 213 | +      channelWithNeither.bindings[REALTIME_LISTEN_TYPES.PRESENCE]?.length,  | 
 | 214 | +      undefined  | 
 | 215 | +    )  | 
 | 216 | +    channelWithNeither.subscribe()  | 
 | 217 | +    const joinPayload = channelWithNeither.joinPush.payload  | 
 | 218 | +    assert.equal(joinPayload.config.presence.enabled, false)  | 
 | 219 | +    channelWithNeither.unsubscribe()  | 
 | 220 | +  })  | 
 | 221 | + | 
 | 222 | +  test('should allow using track() method when presence is enabled via config override', async () => {  | 
 | 223 | +    const channelWithPresenceEnabled = testSetup.socket.channel(  | 
 | 224 | +      'test-presence-track',  | 
 | 225 | +      { config: { presence: { enabled: true } } }  | 
 | 226 | +    )  | 
 | 227 | +    setupJoinedChannelWithSocket(channelWithPresenceEnabled, testSetup.socket)  | 
 | 228 | +    const sendStub = vi  | 
 | 229 | +      .spyOn(channelWithPresenceEnabled, 'send')  | 
 | 230 | +      .mockResolvedValue('ok')  | 
 | 231 | +    await channelWithPresenceEnabled.track({ id: 123, name: 'Test User' })  | 
 | 232 | +    expect(sendStub).toHaveBeenCalledWith(  | 
 | 233 | +      {  | 
 | 234 | +        type: 'presence',  | 
 | 235 | +        event: 'track',  | 
 | 236 | +        payload: { id: 123, name: 'Test User' },  | 
 | 237 | +      },  | 
 | 238 | +      1000  | 
 | 239 | +    )  | 
 | 240 | +    channelWithPresenceEnabled.unsubscribe()  | 
 | 241 | +  })  | 
 | 242 | + | 
 | 243 | +  test('should allow using untrack() method when presence is enabled via config override', async () => {  | 
 | 244 | +    const channelWithPresenceEnabled = testSetup.socket.channel(  | 
 | 245 | +      'test-presence-untrack',  | 
 | 246 | +      { config: { presence: { enabled: true } } }  | 
 | 247 | +    )  | 
 | 248 | +    setupJoinedChannelWithSocket(channelWithPresenceEnabled, testSetup.socket)  | 
 | 249 | +    const sendStub = vi  | 
 | 250 | +      .spyOn(channelWithPresenceEnabled, 'send')  | 
 | 251 | +      .mockResolvedValue('ok')  | 
 | 252 | +    await channelWithPresenceEnabled.untrack()  | 
 | 253 | +    expect(sendStub).toHaveBeenCalledWith(  | 
 | 254 | +      { type: 'presence', event: 'untrack' },  | 
 | 255 | +      {}  | 
 | 256 | +    )  | 
 | 257 | +    channelWithPresenceEnabled.unsubscribe()  | 
 | 258 | +  })  | 
 | 259 | +})  | 
 | 260 | + | 
170 | 261 | describe('RealtimePresence static methods', () => {  | 
171 | 262 |   // Helper function to clone objects (from original RealtimePresence tests)  | 
172 | 263 |   const clone = (obj: any) => {  | 
 | 
0 commit comments