Skip to content

Commit afe5a5a

Browse files
committed
test(realtime): fixed ci integration testing for node
1 parent 52f0184 commit afe5a5a

File tree

4 files changed

+40
-52
lines changed

4 files changed

+40
-52
lines changed

packages/core/supabase-js/src/SupabaseClient.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -157,10 +157,13 @@ export default class SupabaseClient<
157157
...settings.realtime,
158158
})
159159
if (this.accessToken) {
160-
this.realtime.setAuth().catch((e) => {
161-
console.warn('Failed to set initial Realtime auth token:', e)
162-
})
160+
setTimeout(() => {
161+
this.accessToken?.()
162+
?.then((token) => this.realtime.setAuth(token))
163+
.catch((e) => console.warn('Failed to set initial Realtime auth token:', e))
164+
}, 0)
163165
}
166+
164167
this.rest = new PostgrestClient(new URL('rest/v1', baseUrl).href, {
165168
headers: this.headers,
166169
schema: settings.db.schema,

packages/core/supabase-js/test/integration.test.ts

Lines changed: 32 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1+
import { assert } from 'console'
12
import { createClient, RealtimeChannel, SupabaseClient } from '../src/index'
2-
3+
import { sign } from 'jsonwebtoken'
34
// These tests assume that a local Supabase server is already running
45
// Start a local Supabase instance with 'supabase start' before running these tests
56
// Default local dev credentials from Supabase CLI
67
const SUPABASE_URL = 'http://127.0.0.1:54321'
78
const ANON_KEY =
89
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6ImFub24iLCJleHAiOjE5ODM4MTI5OTZ9.CRXP1A7WOeoJeXxjNni43kdQwgnWNReilDMblYTn_I0'
9-
10+
const JWT_SECRET = 'super-secret-jwt-token-with-at-least-32-characters-long'
1011
// For Node.js < 22, we need to provide a WebSocket implementation
1112
// Node.js 22+ has native WebSocket support
1213
let wsTransport: any = undefined
@@ -292,7 +293,7 @@ describe('Supabase Integration Tests', () => {
292293

293294
channel
294295
.on('broadcast', { event: '*' }, (payload) => (receivedMessage = payload))
295-
.subscribe((status) => {
296+
.subscribe((status, err) => {
296297
if (status == 'SUBSCRIBED') subscribed = true
297298
})
298299

@@ -316,52 +317,6 @@ describe('Supabase Integration Tests', () => {
316317
expect(receivedMessage).toBeDefined()
317318
expect(supabase.realtime.getChannels().length).toBe(1)
318319
}, 10000)
319-
320-
test('should automatically set auth token when using custom JWT without manual setAuth()', async () => {
321-
// Sign up a user with the normal client to get a real JWT token
322-
await supabase.auth.signOut()
323-
const email = `custom-jwt-${Date.now()}@example.com`
324-
const password = 'password123'
325-
const { data: signUpData } = await supabase.auth.signUp({ email, password })
326-
expect(signUpData.session).toBeDefined()
327-
const realJwtToken = signUpData.session!.access_token
328-
329-
const customJwtClient = createClient(SUPABASE_URL, ANON_KEY, {
330-
accessToken: async () => realJwtToken,
331-
realtime: {
332-
heartbeatIntervalMs: 500,
333-
...(wsTransport && { transport: wsTransport }),
334-
},
335-
})
336-
337-
await new Promise((resolve) => setTimeout(resolve, 100))
338-
339-
expect((customJwtClient.realtime as any).accessTokenValue).toBe(realJwtToken)
340-
341-
const customChannelName = `custom-jwt-channel-${crypto.randomUUID()}`
342-
const config = { broadcast: { self: true }, private: true }
343-
const customChannel = customJwtClient.channel(customChannelName, { config })
344-
345-
expect((customChannel as any).joinPush.payload.access_token).toBe(realJwtToken)
346-
347-
let subscribed = false
348-
let attempts = 0
349-
350-
customChannel.subscribe((status) => {
351-
if (status == 'SUBSCRIBED') subscribed = true
352-
})
353-
354-
while (!subscribed) {
355-
if (attempts > 50) throw new Error('Timeout waiting for subscription')
356-
await new Promise((resolve) => setTimeout(resolve, 100))
357-
attempts++
358-
}
359-
360-
expect(subscribed).toBe(true)
361-
expect(customJwtClient.realtime.getChannels().length).toBe(1)
362-
363-
await customJwtClient.removeAllChannels()
364-
}, 10000)
365320
})
366321
})
367322

@@ -404,3 +359,31 @@ describe('Storage API', () => {
404359
expect(deleteError).toBeNull()
405360
})
406361
})
362+
363+
describe('Custom JWT', () => {
364+
describe('Realtime', () => {
365+
test('will connect with a properly signed jwt token', async () => {
366+
const jwtToken = sign({ sub: '1234567890' }, JWT_SECRET, { expiresIn: '1h' })
367+
const supabaseWithCustomJwt = createClient(SUPABASE_URL, ANON_KEY, {
368+
accessToken: () => Promise.resolve(jwtToken),
369+
})
370+
await new Promise((resolve) => setTimeout(resolve, 100))
371+
expect(supabaseWithCustomJwt.realtime.accessTokenValue).toBe(jwtToken)
372+
let subscribed = false
373+
let attempts = 0
374+
supabaseWithCustomJwt.channel('test-channel').subscribe((status) => {
375+
if (status == 'SUBSCRIBED') subscribed = true
376+
})
377+
378+
// Wait for subscription
379+
while (!subscribed) {
380+
if (attempts > 50) throw new Error('Timeout waiting for subscription')
381+
await new Promise((resolve) => setTimeout(resolve, 100))
382+
attempts++
383+
}
384+
385+
expect(subscribed).toBe(true)
386+
//
387+
}, 10000)
388+
})
389+
})

supabase/.branches/_current_branch

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
main

supabase/.temp/cli-latest

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
v2.54.11

0 commit comments

Comments
 (0)