@@ -17,25 +17,8 @@ const mockFetch = jest.fn();
17
17
global . fetch = mockFetch ;
18
18
19
19
describe ( "OAuth Authorization" , ( ) => {
20
- let mockProvider : OAuthClientProvider ;
21
-
22
20
beforeEach ( ( ) => {
23
21
mockFetch . mockReset ( ) ;
24
- mockProvider = {
25
- get redirectUrl ( ) { return "http://localhost:3000/callback" ; } ,
26
- get clientMetadata ( ) {
27
- return {
28
- redirect_uris : [ "http://localhost:3000/callback" ] ,
29
- client_name : "Test Client" ,
30
- } ;
31
- } ,
32
- clientInformation : jest . fn ( ) ,
33
- tokens : jest . fn ( ) ,
34
- saveTokens : jest . fn ( ) ,
35
- redirectToAuthorization : jest . fn ( ) ,
36
- saveCodeVerifier : jest . fn ( ) ,
37
- codeVerifier ( ) { return "verifier123" ; } ,
38
- } ;
39
22
} ) ;
40
23
41
24
describe ( "extractResourceMetadataUrl" , ( ) => {
@@ -480,9 +463,9 @@ describe("OAuth Authorization", () => {
480
463
{
481
464
metadata : undefined ,
482
465
clientInformation : validClientInfo ,
466
+ redirectUrl : "http://localhost:3000/callback" ,
483
467
resource : new URL ( "https://api.example.com/mcp-server" ) ,
484
- } ,
485
- mockProvider
468
+ }
486
469
) ;
487
470
488
471
expect ( authorizationUrl . toString ( ) ) . toMatch (
@@ -505,9 +488,9 @@ describe("OAuth Authorization", () => {
505
488
"https://auth.example.com" ,
506
489
{
507
490
clientInformation : validClientInfo ,
491
+ redirectUrl : "http://localhost:3000/callback" ,
508
492
scope : "read write profile" ,
509
- } ,
510
- mockProvider
493
+ }
511
494
) ;
512
495
513
496
expect ( authorizationUrl . searchParams . get ( "scope" ) ) . toBe ( "read write profile" ) ;
@@ -518,8 +501,8 @@ describe("OAuth Authorization", () => {
518
501
"https://auth.example.com" ,
519
502
{
520
503
clientInformation : validClientInfo ,
521
- } ,
522
- mockProvider
504
+ redirectUrl : "http://localhost:3000/callback" ,
505
+ }
523
506
) ;
524
507
525
508
expect ( authorizationUrl . searchParams . has ( "scope" ) ) . toBe ( false ) ;
@@ -530,9 +513,9 @@ describe("OAuth Authorization", () => {
530
513
"https://auth.example.com" ,
531
514
{
532
515
clientInformation : validClientInfo ,
516
+ redirectUrl : "http://localhost:3000/callback" ,
533
517
state : "foobar" ,
534
- } ,
535
- mockProvider
518
+ }
536
519
) ;
537
520
538
521
expect ( authorizationUrl . searchParams . get ( "state" ) ) . toBe ( "foobar" ) ;
@@ -543,8 +526,8 @@ describe("OAuth Authorization", () => {
543
526
"https://auth.example.com" ,
544
527
{
545
528
clientInformation : validClientInfo ,
546
- } ,
547
- mockProvider
529
+ redirectUrl : "http://localhost:3000/callback" ,
530
+ }
548
531
) ;
549
532
550
533
expect ( authorizationUrl . searchParams . has ( "state" ) ) . toBe ( false ) ;
@@ -556,8 +539,8 @@ describe("OAuth Authorization", () => {
556
539
{
557
540
metadata : validMetadata ,
558
541
clientInformation : validClientInfo ,
559
- } ,
560
- mockProvider
542
+ redirectUrl : "http://localhost:3000/callback" ,
543
+ }
561
544
) ;
562
545
563
546
expect ( authorizationUrl . toString ( ) ) . toMatch (
@@ -575,7 +558,8 @@ describe("OAuth Authorization", () => {
575
558
startAuthorization ( "https://auth.example.com" , {
576
559
metadata,
577
560
clientInformation : validClientInfo ,
578
- } , mockProvider )
561
+ redirectUrl : "http://localhost:3000/callback" ,
562
+ } )
579
563
) . rejects . toThrow ( / d o e s n o t s u p p o r t r e s p o n s e t y p e / ) ;
580
564
} ) ;
581
565
@@ -590,7 +574,8 @@ describe("OAuth Authorization", () => {
590
574
startAuthorization ( "https://auth.example.com" , {
591
575
metadata,
592
576
clientInformation : validClientInfo ,
593
- } , mockProvider )
577
+ redirectUrl : "http://localhost:3000/callback" ,
578
+ } )
594
579
) . rejects . toThrow ( / d o e s n o t s u p p o r t c o d e c h a l l e n g e m e t h o d / ) ;
595
580
} ) ;
596
581
} ) ;
@@ -620,8 +605,10 @@ describe("OAuth Authorization", () => {
620
605
const tokens = await exchangeAuthorization ( "https://auth.example.com" , {
621
606
clientInformation : validClientInfo ,
622
607
authorizationCode : "code123" ,
608
+ codeVerifier : "verifier123" ,
609
+ redirectUri : "http://localhost:3000/callback" ,
623
610
resource : new URL ( "https://api.example.com/mcp-server" ) ,
624
- } , mockProvider ) ;
611
+ } ) ;
625
612
626
613
expect ( tokens ) . toEqual ( validTokens ) ;
627
614
expect ( mockFetch ) . toHaveBeenCalledWith (
@@ -647,12 +634,6 @@ describe("OAuth Authorization", () => {
647
634
} ) ;
648
635
649
636
it ( "exchanges code for tokens with auth" , async ( ) => {
650
- mockProvider . addClientAuthentication = function ( url : URL , headers : Headers , params : URLSearchParams ) {
651
- headers . set ( "Authorization" , "Basic " + btoa ( validClientInfo . client_id + ":" + validClientInfo . client_secret ) ) ;
652
- params . set ( "example_url" , url . toString ( ) ) ;
653
- params . set ( "example_param" , "example_value" ) ;
654
- } ;
655
-
656
637
mockFetch . mockResolvedValueOnce ( {
657
638
ok : true ,
658
639
status : 200 ,
@@ -662,7 +643,14 @@ describe("OAuth Authorization", () => {
662
643
const tokens = await exchangeAuthorization ( "https://auth.example.com" , {
663
644
clientInformation : validClientInfo ,
664
645
authorizationCode : "code123" ,
665
- } , mockProvider ) ;
646
+ codeVerifier : "verifier123" ,
647
+ redirectUri : "http://localhost:3000/callback" ,
648
+ addClientAuthentication : ( url : URL , headers : Headers , params : URLSearchParams ) => {
649
+ headers . set ( "Authorization" , "Basic " + btoa ( validClientInfo . client_id + ":" + validClientInfo . client_secret ) ) ;
650
+ params . set ( "example_url" , url . toString ( ) ) ;
651
+ params . set ( "example_param" , "example_value" ) ;
652
+ } ,
653
+ } ) ;
666
654
667
655
expect ( tokens ) . toEqual ( validTokens ) ;
668
656
expect ( mockFetch ) . toHaveBeenCalledWith (
@@ -702,7 +690,9 @@ describe("OAuth Authorization", () => {
702
690
exchangeAuthorization ( "https://auth.example.com" , {
703
691
clientInformation : validClientInfo ,
704
692
authorizationCode : "code123" ,
705
- } , mockProvider )
693
+ redirectUri : "http://localhost:3000/callback" ,
694
+ codeVerifier : "verifier123" ,
695
+ } )
706
696
) . rejects . toThrow ( ) ;
707
697
} ) ;
708
698
@@ -715,8 +705,10 @@ describe("OAuth Authorization", () => {
715
705
await expect (
716
706
exchangeAuthorization ( "https://auth.example.com" , {
717
707
clientInformation : validClientInfo ,
708
+ redirectUri : "http://localhost:3000/callback" ,
718
709
authorizationCode : "code123" ,
719
- } , mockProvider )
710
+ codeVerifier : "verifier123" ,
711
+ } )
720
712
) . rejects . toThrow ( "Token exchange failed" ) ;
721
713
} ) ;
722
714
} ) ;
@@ -750,7 +742,7 @@ describe("OAuth Authorization", () => {
750
742
clientInformation : validClientInfo ,
751
743
refreshToken : "refresh123" ,
752
744
resource : new URL ( "https://api.example.com/mcp-server" ) ,
753
- } , mockProvider ) ;
745
+ } ) ;
754
746
755
747
expect ( tokens ) . toEqual ( validTokensWithNewRefreshToken ) ;
756
748
expect ( mockFetch ) . toHaveBeenCalledWith (
@@ -771,12 +763,6 @@ describe("OAuth Authorization", () => {
771
763
} ) ;
772
764
773
765
it ( "exchanges refresh token for new tokens with auth" , async ( ) => {
774
- mockProvider . addClientAuthentication = function ( url : URL , headers : Headers , params : URLSearchParams ) {
775
- headers . set ( "Authorization" , "Basic " + btoa ( validClientInfo . client_id + ":" + validClientInfo . client_secret ) ) ;
776
- params . set ( "example_url" , url . toString ( ) ) ;
777
- params . set ( "example_param" , "example_value" ) ;
778
- } ;
779
-
780
766
mockFetch . mockResolvedValueOnce ( {
781
767
ok : true ,
782
768
status : 200 ,
@@ -786,7 +772,12 @@ describe("OAuth Authorization", () => {
786
772
const tokens = await refreshAuthorization ( "https://auth.example.com" , {
787
773
clientInformation : validClientInfo ,
788
774
refreshToken : "refresh123" ,
789
- } , mockProvider ) ;
775
+ addClientAuthentication : ( url : URL , headers : Headers , params : URLSearchParams ) => {
776
+ headers . set ( "Authorization" , "Basic " + btoa ( validClientInfo . client_id + ":" + validClientInfo . client_secret ) ) ;
777
+ params . set ( "example_url" , url . toString ( ) ) ;
778
+ params . set ( "example_param" , "example_value" ) ;
779
+ } ,
780
+ } ) ;
790
781
791
782
expect ( tokens ) . toEqual ( validTokensWithNewRefreshToken ) ;
792
783
expect ( mockFetch ) . toHaveBeenCalledWith (
@@ -821,7 +812,7 @@ describe("OAuth Authorization", () => {
821
812
const tokens = await refreshAuthorization ( "https://auth.example.com" , {
822
813
clientInformation : validClientInfo ,
823
814
refreshToken,
824
- } , mockProvider ) ;
815
+ } ) ;
825
816
826
817
expect ( tokens ) . toEqual ( { refresh_token : refreshToken , ...validTokens } ) ;
827
818
} ) ;
@@ -840,7 +831,7 @@ describe("OAuth Authorization", () => {
840
831
refreshAuthorization ( "https://auth.example.com" , {
841
832
clientInformation : validClientInfo ,
842
833
refreshToken : "refresh123" ,
843
- } , mockProvider )
834
+ } )
844
835
) . rejects . toThrow ( ) ;
845
836
} ) ;
846
837
@@ -854,7 +845,7 @@ describe("OAuth Authorization", () => {
854
845
refreshAuthorization ( "https://auth.example.com" , {
855
846
clientInformation : validClientInfo ,
856
847
refreshToken : "refresh123" ,
857
- } , mockProvider )
848
+ } )
858
849
) . rejects . toThrow ( "Token refresh failed" ) ;
859
850
} ) ;
860
851
} ) ;
@@ -1599,7 +1590,9 @@ describe("OAuth Authorization", () => {
1599
1590
metadata : metadataWithBasicOnly ,
1600
1591
clientInformation : validClientInfo ,
1601
1592
authorizationCode : "code123" ,
1602
- } , mockProvider ) ;
1593
+ redirectUri : "http://localhost:3000/callback" ,
1594
+ codeVerifier : "verifier123" ,
1595
+ } ) ;
1603
1596
1604
1597
expect ( tokens ) . toEqual ( validTokens ) ;
1605
1598
const request = mockFetch . mock . calls [ 0 ] [ 1 ] ;
@@ -1625,7 +1618,9 @@ describe("OAuth Authorization", () => {
1625
1618
metadata : metadataWithPostOnly ,
1626
1619
clientInformation : validClientInfo ,
1627
1620
authorizationCode : "code123" ,
1628
- } , mockProvider ) ;
1621
+ redirectUri : "http://localhost:3000/callback" ,
1622
+ codeVerifier : "verifier123" ,
1623
+ } ) ;
1629
1624
1630
1625
expect ( tokens ) . toEqual ( validTokens ) ;
1631
1626
const request = mockFetch . mock . calls [ 0 ] [ 1 ] ;
@@ -1655,7 +1650,9 @@ describe("OAuth Authorization", () => {
1655
1650
metadata : metadataWithNoneOnly ,
1656
1651
clientInformation : clientInfoWithoutSecret ,
1657
1652
authorizationCode : "code123" ,
1658
- } , mockProvider ) ;
1653
+ redirectUri : "http://localhost:3000/callback" ,
1654
+ codeVerifier : "verifier123" ,
1655
+ } ) ;
1659
1656
1660
1657
expect ( tokens ) . toEqual ( validTokens ) ;
1661
1658
const request = mockFetch . mock . calls [ 0 ] [ 1 ] ;
@@ -1678,7 +1675,9 @@ describe("OAuth Authorization", () => {
1678
1675
const tokens = await exchangeAuthorization ( "https://auth.example.com" , {
1679
1676
clientInformation : validClientInfo ,
1680
1677
authorizationCode : "code123" ,
1681
- } , mockProvider ) ;
1678
+ redirectUri : "http://localhost:3000/callback" ,
1679
+ codeVerifier : "verifier123" ,
1680
+ } ) ;
1682
1681
1683
1682
expect ( tokens ) . toEqual ( validTokens ) ;
1684
1683
const request = mockFetch . mock . calls [ 0 ] [ 1 ] ;
@@ -1732,7 +1731,7 @@ describe("OAuth Authorization", () => {
1732
1731
metadata : metadataWithBasicOnly ,
1733
1732
clientInformation : validClientInfo ,
1734
1733
refreshToken : "refresh123" ,
1735
- } , mockProvider ) ;
1734
+ } ) ;
1736
1735
1737
1736
expect ( tokens ) . toEqual ( validTokens ) ;
1738
1737
const request = mockFetch . mock . calls [ 0 ] [ 1 ] ;
@@ -1759,7 +1758,7 @@ describe("OAuth Authorization", () => {
1759
1758
metadata : metadataWithPostOnly ,
1760
1759
clientInformation : validClientInfo ,
1761
1760
refreshToken : "refresh123" ,
1762
- } , mockProvider ) ;
1761
+ } ) ;
1763
1762
1764
1763
expect ( tokens ) . toEqual ( validTokens ) ;
1765
1764
const request = mockFetch . mock . calls [ 0 ] [ 1 ] ;
0 commit comments