Skip to content

Commit e3211e7

Browse files
committed
chore: Added more goTrueClient tests
1 parent ae1bab2 commit e3211e7

File tree

1 file changed

+313
-0
lines changed

1 file changed

+313
-0
lines changed

test/GoTrueClient.test.ts

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,39 @@ describe('GoTrueClient', () => {
3939
refreshAccessTokenSpy.mockClear()
4040
})
4141

42+
test('should handle debug function in settings', async () => {
43+
const debugSpy = jest.fn()
44+
const client = new GoTrueClient({
45+
url: 'http://localhost:9999',
46+
debug: debugSpy,
47+
})
48+
49+
await client.initialize()
50+
expect(debugSpy).toHaveBeenCalled()
51+
})
52+
53+
test('should handle custom lock implementation', async () => {
54+
const customLock = jest.fn().mockResolvedValue(undefined)
55+
const client = new GoTrueClient({
56+
url: 'http://localhost:9999',
57+
lock: customLock,
58+
})
59+
60+
await client.initialize()
61+
expect(customLock).toHaveBeenCalled()
62+
})
63+
64+
test('should handle userStorage configuration', async () => {
65+
const userStorage = memoryLocalStorageAdapter()
66+
const client = new GoTrueClient({
67+
url: 'http://localhost:9999',
68+
userStorage,
69+
})
70+
71+
await client.initialize()
72+
expect(client['userStorage']).toBe(userStorage)
73+
})
74+
4275
describe('Sessions', () => {
4376
test('refreshSession() should return a new session using a passed-in refresh token', async () => {
4477
const { email, password } = mockUserCredentials()
@@ -557,6 +590,67 @@ describe('GoTrueClient', () => {
557590
expect(data.session).toBeNull()
558591
expect(data.user).toBeNull()
559592
})
593+
594+
test('should handle signUp with invalid credentials', async () => {
595+
const { data, error } = await auth.signUp({
596+
email: 'invalid-email',
597+
password: '123', // too short
598+
})
599+
600+
expect(error).toBeDefined()
601+
expect(data.user).toBeNull()
602+
expect(data.session).toBeNull()
603+
})
604+
605+
test('should handle signInWithPassword with invalid credentials', async () => {
606+
const { data, error } = await auth.signInWithPassword({
607+
608+
password: 'wrongpassword',
609+
})
610+
611+
expect(error).toBeDefined()
612+
expect(data.user).toBeNull()
613+
expect(data.session).toBeNull()
614+
})
615+
616+
test('should handle signInWithOAuth with invalid provider', async () => {
617+
const { data, error } = await auth.signInWithOAuth({
618+
provider: 'invalid-provider' as any,
619+
})
620+
621+
expect(error).toBeNull()
622+
expect(data.url).toBeDefined()
623+
})
624+
625+
test('should handle signInWithOtp with invalid email', async () => {
626+
const { data, error } = await auth.signInWithOtp({
627+
email: 'invalid-email',
628+
})
629+
630+
expect(error).toBeDefined()
631+
expect(data.user).toBeNull()
632+
})
633+
634+
test('should handle signInWithOtp with invalid phone', async () => {
635+
const { data, error } = await auth.signInWithOtp({
636+
phone: 'invalid-phone',
637+
})
638+
639+
expect(error).toBeDefined()
640+
expect(data.user).toBeNull()
641+
})
642+
643+
test('should handle verifyOtp with invalid code', async () => {
644+
const { data, error } = await auth.verifyOtp({
645+
646+
token: 'invalid-token',
647+
type: 'email',
648+
})
649+
650+
expect(error).toBeDefined()
651+
expect(data.user).toBeNull()
652+
expect(data.session).toBeNull()
653+
})
560654
})
561655

562656
describe('signInWithOtp', () => {
@@ -1146,6 +1240,40 @@ describe('The auth client can signin with third-party oAuth providers', () => {
11461240
expect(provider).toBeTruthy()
11471241
})
11481242

1243+
test('should handle exchangeCodeForSession with invalid code', async () => {
1244+
const { data, error } = await auth.exchangeCodeForSession('invalid-code')
1245+
expect(error).toBeDefined()
1246+
expect(data.session).toBeNull()
1247+
expect(data.user).toBeNull()
1248+
})
1249+
1250+
test('should handle signInWithOAuth with redirectTo option', async () => {
1251+
const { data, error } = await auth.signInWithOAuth({
1252+
provider: 'google',
1253+
options: {
1254+
redirectTo: 'http://localhost:3000/callback',
1255+
},
1256+
})
1257+
1258+
expect(error).toBeNull()
1259+
expect(data.url).toBeDefined()
1260+
})
1261+
1262+
test('should handle signInWithOAuth with queryParams', async () => {
1263+
const { data, error } = await auth.signInWithOAuth({
1264+
provider: 'github',
1265+
options: {
1266+
queryParams: {
1267+
access_type: 'offline',
1268+
prompt: 'consent',
1269+
},
1270+
},
1271+
})
1272+
1273+
expect(error).toBeNull()
1274+
expect(data.url).toBeDefined()
1275+
})
1276+
11491277
describe('Developers can subscribe and unsubscribe', () => {
11501278
const {
11511279
data: { subscription },
@@ -1422,6 +1550,45 @@ describe('MFA', () => {
14221550
expect(result.data.phone).toHaveLength(1)
14231551
}
14241552
})
1553+
1554+
test('should handle MFA enroll without session', async () => {
1555+
await auth.signOut()
1556+
const { data, error } = await auth.mfa.enroll({
1557+
factorType: 'totp',
1558+
})
1559+
1560+
expect(error).toBeDefined()
1561+
expect(data?.id).toBeUndefined()
1562+
})
1563+
1564+
test('should handle MFA challenge without session', async () => {
1565+
const { data, error } = await auth.mfa.challenge({
1566+
factorId: 'test-factor-id',
1567+
})
1568+
1569+
expect(error).toBeDefined()
1570+
expect(data?.id).toBeUndefined()
1571+
})
1572+
1573+
test('should handle MFA verify without session', async () => {
1574+
const { data, error } = await auth.mfa.verify({
1575+
factorId: 'test-factor-id',
1576+
challengeId: 'test-challenge-id',
1577+
code: '123456',
1578+
})
1579+
1580+
expect(error).toBeDefined()
1581+
expect(data?.access_token).toBeUndefined()
1582+
})
1583+
1584+
test('should handle MFA unenroll without session', async () => {
1585+
const { data, error } = await auth.mfa.unenroll({
1586+
factorId: 'test-factor-id',
1587+
})
1588+
1589+
expect(error).toBeDefined()
1590+
expect(data?.id).toBeUndefined()
1591+
})
14251592
})
14261593

14271594
describe('getClaims', () => {
@@ -2038,6 +2205,74 @@ describe('Web3 Authentication', () => {
20382205
'@supabase/auth-js: No accounts available. Please ensure the wallet is connected.'
20392206
)
20402207
})
2208+
2209+
test('should handle signInWithWeb3 with unsupported chain', async () => {
2210+
const credentials = {
2211+
chain: 'polygon' as any,
2212+
message: 'test message',
2213+
signature: '0xtest-signature' as any,
2214+
}
2215+
2216+
await expect(
2217+
auth.signInWithWeb3(credentials)
2218+
).rejects.toThrow('Unsupported chain "polygon"')
2219+
})
2220+
2221+
test('should handle signInWithWeb3 with missing message', async () => {
2222+
const credentials = {
2223+
chain: 'ethereum',
2224+
signature: 'test signature',
2225+
} as any
2226+
2227+
await expect(
2228+
auth.signInWithWeb3(credentials)
2229+
).rejects.toThrow('Both wallet and url must be specified in non-browser environments')
2230+
})
2231+
2232+
test('should handle signInWithWeb3 with missing wallet', async () => {
2233+
const credentials = {
2234+
chain: 'ethereum',
2235+
message: 'test message',
2236+
} as any
2237+
2238+
const { data, error } = await auth.signInWithWeb3(credentials)
2239+
expect(error).toBeDefined()
2240+
expect(data.session).toBeNull()
2241+
expect(data.user).toBeNull()
2242+
})
2243+
2244+
test('should handle signInWithWeb3 with invalid signature', async () => {
2245+
const credentials = {
2246+
chain: 'ethereum',
2247+
message: 'test message',
2248+
signature: '0xinvalid-signature' as any,
2249+
} as any
2250+
2251+
const { data, error } = await auth.signInWithWeb3(credentials)
2252+
expect(error).toBeDefined()
2253+
expect(data.session).toBeNull()
2254+
expect(data.user).toBeNull()
2255+
})
2256+
2257+
test('should handle signInWithWeb3 in non-browser environment', async () => {
2258+
const credentials = {
2259+
chain: 'ethereum',
2260+
message: 'test message',
2261+
wallet: {
2262+
request: jest.fn(),
2263+
on: jest.fn(),
2264+
removeListener: jest.fn(),
2265+
},
2266+
options: {
2267+
url: 'http://localhost:9999',
2268+
},
2269+
} as any
2270+
2271+
const { data, error } = await auth.signInWithWeb3(credentials)
2272+
expect(error).toBeDefined()
2273+
expect(data.session).toBeNull()
2274+
expect(data.user).toBeNull()
2275+
})
20412276
})
20422277

20432278
describe('ID Token Authentication', () => {
@@ -2239,6 +2474,14 @@ describe('Auto Refresh', () => {
22392474
expect(session?.access_token).not.toEqual(signUpData.session?.access_token)
22402475
})
22412476
})
2477+
2478+
test('should handle auto refresh start/stop multiple times', async () => {
2479+
await autoRefreshClient.startAutoRefresh()
2480+
await autoRefreshClient.startAutoRefresh() // Should handle duplicate calls
2481+
2482+
await autoRefreshClient.stopAutoRefresh()
2483+
await autoRefreshClient.stopAutoRefresh() // Should handle duplicate calls
2484+
})
22422485
})
22432486

22442487
describe('Session Management', () => {
@@ -2285,6 +2528,60 @@ describe('Session Management', () => {
22852528
// Cleanup
22862529
subscription?.unsubscribe()
22872530
})
2531+
2532+
test('should handle getSession when no session exists', async () => {
2533+
// Clear any existing session first
2534+
await auth.signOut()
2535+
const { data, error } = await auth.getSession()
2536+
expect(data.session).toBeNull()
2537+
expect(error).toBeNull()
2538+
})
2539+
2540+
test('should handle refreshSession with invalid refresh token', async () => {
2541+
const { data, error } = await auth.refreshSession({
2542+
refresh_token: 'invalid-refresh-token',
2543+
})
2544+
2545+
expect(error).toBeDefined()
2546+
expect(data.session).toBeNull()
2547+
})
2548+
2549+
test('should handle setSession with invalid session data', async () => {
2550+
const { data, error } = await auth.setSession({
2551+
access_token: 'invalid-token',
2552+
refresh_token: 'invalid-refresh-token',
2553+
})
2554+
2555+
expect(error).toBeDefined()
2556+
expect(data.session).toBeNull()
2557+
})
2558+
2559+
test('should handle getUser without valid session', async () => {
2560+
await auth.signOut()
2561+
const { data, error } = await auth.getUser()
2562+
expect(data.user).toBeNull()
2563+
expect(error).toBeDefined()
2564+
})
2565+
2566+
test('should handle updateUser without valid session', async () => {
2567+
await auth.signOut()
2568+
const { data, error } = await auth.updateUser({
2569+
data: { name: 'Test User' },
2570+
})
2571+
2572+
expect(error).toBeDefined()
2573+
expect(data.user).toBeNull()
2574+
})
2575+
2576+
test('should handle custom URL parameters', async () => {
2577+
const client = new GoTrueClient({
2578+
url: 'http://localhost:9999',
2579+
detectSessionInUrl: false,
2580+
})
2581+
2582+
await client.initialize()
2583+
expect(client['detectSessionInUrl']).toBe(false)
2584+
})
22882585
})
22892586

22902587
describe('Session Management Edge Cases', () => {
@@ -2538,6 +2835,22 @@ describe('Storage adapter edge cases', () => {
25382835
expect(url).toContain('code_challenge=')
25392836
expect(url).toContain('code_challenge_method=')
25402837
})
2838+
2839+
test('should handle localStorage not supported', async () => {
2840+
// Mock supportsLocalStorage to return false
2841+
jest.doMock('../src/lib/helpers', () => ({
2842+
...jest.requireActual('../src/lib/helpers'),
2843+
supportsLocalStorage: () => false,
2844+
}))
2845+
2846+
const client = new GoTrueClient({
2847+
url: 'http://localhost:9999',
2848+
})
2849+
2850+
await client.initialize()
2851+
// Should fall back to memory storage
2852+
expect(client['storage']).toBeDefined()
2853+
})
25412854
})
25422855

25432856
describe('SSO Authentication', () => {

0 commit comments

Comments
 (0)