@@ -439,6 +439,103 @@ describe("AuthDebugger", () => {
439
439
} ) ;
440
440
} ) ;
441
441
442
+ describe ( "Client Registration behavior" , ( ) => {
443
+ it ( "uses preregistered (static) client information without calling DCR" , async ( ) => {
444
+ const preregClientInfo = {
445
+ client_id : "static_client_id" ,
446
+ client_secret : "static_client_secret" ,
447
+ redirect_uris : [ "http://localhost:3000/oauth/callback/debug" ] ,
448
+ } ;
449
+
450
+ // Return preregistered client info for the server-specific key
451
+ sessionStorageMock . getItem . mockImplementation ( ( key ) => {
452
+ if (
453
+ key ===
454
+ `[${ defaultProps . serverUrl } ] ${ SESSION_KEYS . PREREGISTERED_CLIENT_INFORMATION } `
455
+ ) {
456
+ return JSON . stringify ( preregClientInfo ) ;
457
+ }
458
+ return null ;
459
+ } ) ;
460
+
461
+ const updateAuthState = jest . fn ( ) ;
462
+
463
+ await act ( async ( ) => {
464
+ renderAuthDebugger ( {
465
+ updateAuthState,
466
+ authState : {
467
+ ...defaultAuthState ,
468
+ isInitiatingAuth : false ,
469
+ oauthStep : "client_registration" ,
470
+ oauthMetadata : mockOAuthMetadata as unknown as OAuthMetadata ,
471
+ } ,
472
+ } ) ;
473
+ } ) ;
474
+
475
+ // Proceed from client_registration → authorization_redirect
476
+ await act ( async ( ) => {
477
+ fireEvent . click ( screen . getByText ( "Continue" ) ) ;
478
+ } ) ;
479
+
480
+ // Should NOT attempt dynamic client registration
481
+ expect ( mockRegisterClient ) . not . toHaveBeenCalled ( ) ;
482
+
483
+ // Should advance with the preregistered client info
484
+ expect ( updateAuthState ) . toHaveBeenCalledWith (
485
+ expect . objectContaining ( {
486
+ oauthClientInfo : expect . objectContaining ( {
487
+ client_id : "static_client_id" ,
488
+ } ) ,
489
+ oauthStep : "authorization_redirect" ,
490
+ } ) ,
491
+ ) ;
492
+ } ) ;
493
+
494
+ it ( "falls back to DCR when no static client information is available" , async ( ) => {
495
+ // No preregistered or dynamic client info present in session storage
496
+ sessionStorageMock . getItem . mockImplementation ( ( ) => null ) ;
497
+
498
+ // DCR returns a new client
499
+ mockRegisterClient . mockResolvedValueOnce ( mockOAuthClientInfo ) ;
500
+
501
+ const updateAuthState = jest . fn ( ) ;
502
+
503
+ await act ( async ( ) => {
504
+ renderAuthDebugger ( {
505
+ updateAuthState,
506
+ authState : {
507
+ ...defaultAuthState ,
508
+ isInitiatingAuth : false ,
509
+ oauthStep : "client_registration" ,
510
+ oauthMetadata : mockOAuthMetadata as unknown as OAuthMetadata ,
511
+ } ,
512
+ } ) ;
513
+ } ) ;
514
+
515
+ await act ( async ( ) => {
516
+ fireEvent . click ( screen . getByText ( "Continue" ) ) ;
517
+ } ) ;
518
+
519
+ expect ( mockRegisterClient ) . toHaveBeenCalledTimes ( 1 ) ;
520
+
521
+ // Should save and advance with the DCR client info
522
+ expect ( updateAuthState ) . toHaveBeenCalledWith (
523
+ expect . objectContaining ( {
524
+ oauthClientInfo : expect . objectContaining ( {
525
+ client_id : "test_client_id" ,
526
+ } ) ,
527
+ oauthStep : "authorization_redirect" ,
528
+ } ) ,
529
+ ) ;
530
+
531
+ // Verify the dynamically registered client info was persisted
532
+ expect ( sessionStorage . setItem ) . toHaveBeenCalledWith (
533
+ `[${ defaultProps . serverUrl } ] ${ SESSION_KEYS . CLIENT_INFORMATION } ` ,
534
+ expect . any ( String ) ,
535
+ ) ;
536
+ } ) ;
537
+ } ) ;
538
+
442
539
describe ( "OAuth State Persistence" , ( ) => {
443
540
it ( "should store auth state to sessionStorage before redirect in Quick OAuth Flow" , async ( ) => {
444
541
const updateAuthState = jest . fn ( ) ;
0 commit comments