@@ -627,4 +627,99 @@ describe('Passkey API', () => {
627627 ) . rejects . toThrow ( 'User cancelled' ) ;
628628 } ) ;
629629 } ) ;
630+
631+ describe ( 'passkey granular flow' , ( ) => {
632+ const credential = { } as PublicKeyCredential ;
633+
634+ it ( 'should forward getSignupChallenge to the underlying client' , async ( ) => {
635+ const wrapper = createWrapper ( ) ;
636+ const { result } = renderHook ( ( ) => useAuth0 ( ) , { wrapper } ) ;
637+
638+ await waitFor ( ( ) => expect ( result . current . isLoading ) . toBe ( false ) ) ;
639+
640+ const challenge = await result . current . passkey . getSignupChallenge ( {
641+ email : 'user@example.com' ,
642+ } ) ;
643+
644+ expect ( clientMock . passkey . getSignupChallenge ) . toHaveBeenCalledWith ( {
645+ email : 'user@example.com' ,
646+ } ) ;
647+ expect ( challenge . authSession ) . toBe ( 'signup-auth-session' ) ;
648+ } ) ;
649+
650+ it ( 'should forward getLoginChallenge to the underlying client' , async ( ) => {
651+ const wrapper = createWrapper ( ) ;
652+ const { result } = renderHook ( ( ) => useAuth0 ( ) , { wrapper } ) ;
653+
654+ await waitFor ( ( ) => expect ( result . current . isLoading ) . toBe ( false ) ) ;
655+
656+ const challenge = await result . current . passkey . getLoginChallenge ( {
657+ realm : 'Username-Password-Authentication' ,
658+ } ) ;
659+
660+ expect ( clientMock . passkey . getLoginChallenge ) . toHaveBeenCalledWith ( {
661+ realm : 'Username-Password-Authentication' ,
662+ } ) ;
663+ expect ( challenge . authSession ) . toBe ( 'login-auth-session' ) ;
664+ } ) ;
665+
666+ it ( 'should update isAuthenticated and user after getTokenWithPasskey' , async ( ) => {
667+ const wrapper = createWrapper ( ) ;
668+ const { result } = renderHook ( ( ) => useAuth0 ( ) , { wrapper } ) ;
669+
670+ await waitFor ( ( ) => expect ( result . current . isLoading ) . toBe ( false ) ) ;
671+ expect ( result . current . isAuthenticated ) . toBe ( false ) ;
672+
673+ clientMock . getUser . mockResolvedValue ( user ) ;
674+ let tokenResponse : TokenEndpointResponse | undefined ;
675+ await act ( async ( ) => {
676+ tokenResponse = await result . current . passkey . getTokenWithPasskey ( {
677+ authSession : 'login-auth-session' ,
678+ credential,
679+ } ) ;
680+ } ) ;
681+
682+ expect ( clientMock . passkey . getTokenWithPasskey ) . toHaveBeenCalledWith ( {
683+ authSession : 'login-auth-session' ,
684+ credential,
685+ } ) ;
686+ expect ( tokenResponse ?. access_token ) . toBe ( 'passkey-token' ) ;
687+ expect ( result . current . isAuthenticated ) . toBe ( true ) ;
688+ expect ( result . current . user ) . toEqual ( user ) ;
689+ } ) ;
690+
691+ it ( 'should rethrow errors from getTokenWithPasskey' , async ( ) => {
692+ clientMock . passkey . getTokenWithPasskey . mockRejectedValueOnce (
693+ new PasskeyError ( 'passkey_invalid_credential' , 'Invalid credential' )
694+ ) ;
695+
696+ const wrapper = createWrapper ( ) ;
697+ const { result } = renderHook ( ( ) => useAuth0 ( ) , { wrapper } ) ;
698+
699+ await waitFor ( ( ) => expect ( result . current . isLoading ) . toBe ( false ) ) ;
700+
701+ await expect (
702+ act ( async ( ) => {
703+ await result . current . passkey . getTokenWithPasskey ( {
704+ authSession : 'login-auth-session' ,
705+ credential,
706+ } ) ;
707+ } )
708+ ) . rejects . toThrow ( 'Invalid credential' ) ;
709+ } ) ;
710+
711+ it ( 'should throw when the granular methods are used outside Auth0Provider' , ( ) => {
712+ const { result } = renderHook ( ( ) => useAuth0 ( ) ) ;
713+
714+ expect ( result . current . passkey . getSignupChallenge ) . toThrow (
715+ 'You forgot to wrap your component in <Auth0Provider>.'
716+ ) ;
717+ expect ( result . current . passkey . getLoginChallenge ) . toThrow (
718+ 'You forgot to wrap your component in <Auth0Provider>.'
719+ ) ;
720+ expect ( result . current . passkey . getTokenWithPasskey ) . toThrow (
721+ 'You forgot to wrap your component in <Auth0Provider>.'
722+ ) ;
723+ } ) ;
724+ } ) ;
630725} ) ;
0 commit comments