@@ -48,6 +48,7 @@ import {
48
48
registerClient ,
49
49
startAuthorization ,
50
50
exchangeAuthorization ,
51
+ auth ,
51
52
} from "@modelcontextprotocol/sdk/client/auth.js" ;
52
53
import { OAuthMetadata } from "@modelcontextprotocol/sdk/shared/auth.js" ;
53
54
@@ -64,6 +65,7 @@ const mockStartAuthorization = startAuthorization as jest.MockedFunction<
64
65
const mockExchangeAuthorization = exchangeAuthorization as jest . MockedFunction <
65
66
typeof exchangeAuthorization
66
67
> ;
68
+ const mockAuth = auth as jest . MockedFunction < typeof auth > ;
67
69
68
70
const sessionStorageMock = {
69
71
getItem : jest . fn ( ) ,
@@ -186,6 +188,63 @@ describe("AuthDebugger", () => {
186
188
} ,
187
189
} ) ;
188
190
} ) ;
191
+
192
+ it ( "should start quick OAuth flow and properly fetch and save metadata" , async ( ) => {
193
+ // Setup the auth mock
194
+ mockAuth . mockResolvedValue ( "AUTHORIZED" ) ;
195
+
196
+ const updateAuthState = jest . fn ( ) ;
197
+ await act ( async ( ) => {
198
+ renderAuthDebugger ( { updateAuthState } ) ;
199
+ } ) ;
200
+
201
+ await act ( async ( ) => {
202
+ fireEvent . click ( screen . getByText ( "Quick OAuth Flow" ) ) ;
203
+ } ) ;
204
+
205
+ // Should first discover and save OAuth metadata
206
+ expect ( mockDiscoverOAuthMetadata ) . toHaveBeenCalledWith (
207
+ "https://example.com" ,
208
+ ) ;
209
+
210
+ // Then should call auth with the server provider
211
+ expect ( mockAuth ) . toHaveBeenCalled ( ) ;
212
+
213
+ // Check that updateAuthState was called with the right info message
214
+ expect ( updateAuthState ) . toHaveBeenCalledWith (
215
+ expect . objectContaining ( {
216
+ statusMessage : {
217
+ type : "info" ,
218
+ message : "Starting OAuth authentication process..." ,
219
+ } ,
220
+ } ) ,
221
+ ) ;
222
+ } ) ;
223
+
224
+ it ( "should show error when quick OAuth flow fails to discover metadata" , async ( ) => {
225
+ mockDiscoverOAuthMetadata . mockRejectedValue (
226
+ new Error ( "Metadata discovery failed" ) ,
227
+ ) ;
228
+
229
+ const updateAuthState = jest . fn ( ) ;
230
+ await act ( async ( ) => {
231
+ renderAuthDebugger ( { updateAuthState } ) ;
232
+ } ) ;
233
+
234
+ await act ( async ( ) => {
235
+ fireEvent . click ( screen . getByText ( "Quick OAuth Flow" ) ) ;
236
+ } ) ;
237
+
238
+ // Check that updateAuthState was called with an error message
239
+ expect ( updateAuthState ) . toHaveBeenCalledWith (
240
+ expect . objectContaining ( {
241
+ statusMessage : {
242
+ type : "error" ,
243
+ message : expect . stringContaining ( "Failed to start OAuth flow" ) ,
244
+ } ,
245
+ } ) ,
246
+ ) ;
247
+ } ) ;
189
248
} ) ;
190
249
191
250
describe ( "Session Storage Integration" , ( ) => {
0 commit comments