@@ -39,6 +39,39 @@ describe('GoTrueClient', () => {
39
39
refreshAccessTokenSpy . mockClear ( )
40
40
} )
41
41
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
+
42
75
describe ( 'Sessions' , ( ) => {
43
76
test ( 'refreshSession() should return a new session using a passed-in refresh token' , async ( ) => {
44
77
const { email, password } = mockUserCredentials ( )
@@ -557,6 +590,67 @@ describe('GoTrueClient', () => {
557
590
expect ( data . session ) . toBeNull ( )
558
591
expect ( data . user ) . toBeNull ( )
559
592
} )
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
+ } )
560
654
} )
561
655
562
656
describe ( 'signInWithOtp' , ( ) => {
@@ -1146,6 +1240,40 @@ describe('The auth client can signin with third-party oAuth providers', () => {
1146
1240
expect ( provider ) . toBeTruthy ( )
1147
1241
} )
1148
1242
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
+
1149
1277
describe ( 'Developers can subscribe and unsubscribe' , ( ) => {
1150
1278
const {
1151
1279
data : { subscription } ,
@@ -1422,6 +1550,45 @@ describe('MFA', () => {
1422
1550
expect ( result . data . phone ) . toHaveLength ( 1 )
1423
1551
}
1424
1552
} )
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
+ } )
1425
1592
} )
1426
1593
1427
1594
describe ( 'getClaims' , ( ) => {
@@ -2038,6 +2205,74 @@ describe('Web3 Authentication', () => {
2038
2205
'@supabase/auth-js: No accounts available. Please ensure the wallet is connected.'
2039
2206
)
2040
2207
} )
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
+ } )
2041
2276
} )
2042
2277
2043
2278
describe ( 'ID Token Authentication' , ( ) => {
@@ -2239,6 +2474,14 @@ describe('Auto Refresh', () => {
2239
2474
expect ( session ?. access_token ) . not . toEqual ( signUpData . session ?. access_token )
2240
2475
} )
2241
2476
} )
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
+ } )
2242
2485
} )
2243
2486
2244
2487
describe ( 'Session Management' , ( ) => {
@@ -2285,6 +2528,60 @@ describe('Session Management', () => {
2285
2528
// Cleanup
2286
2529
subscription ?. unsubscribe ( )
2287
2530
} )
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
+ } )
2288
2585
} )
2289
2586
2290
2587
describe ( 'Session Management Edge Cases' , ( ) => {
@@ -2538,6 +2835,22 @@ describe('Storage adapter edge cases', () => {
2538
2835
expect ( url ) . toContain ( 'code_challenge=' )
2539
2836
expect ( url ) . toContain ( 'code_challenge_method=' )
2540
2837
} )
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
+ } )
2541
2854
} )
2542
2855
2543
2856
describe ( 'SSO Authentication' , ( ) => {
0 commit comments