@@ -680,6 +680,28 @@ func Test_PasskeyHandler_RefreshToken(t *testing.T) {
680680 Return (credentialID , contractAddress , nil ).
681681 Once ()
682682
683+ embeddedWallet := & data.EmbeddedWallet {
684+ ContractAddress : contractAddress ,
685+ CredentialID : credentialID ,
686+ RequiresVerification : true ,
687+ ReceiverWalletID : "rw-1" ,
688+ }
689+ mockEmbeddedWalletService .
690+ On ("GetWalletByCredentialID" , mock .Anything , credentialID ).
691+ Return (embeddedWallet , nil ).
692+ Once ()
693+
694+ mockEmbeddedWalletService .
695+ On ("GetReceiverWalletByID" , mock .Anything , "rw-1" ).
696+ Return (& data.ReceiverWallet {ID : "rw-1" , Status : data .ReadyReceiversWalletStatus }, nil ).
697+ Once ()
698+
699+ pendingAsset := & data.Asset {ID : "asset-1" , Code : "USDC" , Issuer : "GDUKMGUGDZQK6YH6Q7" }
700+ mockEmbeddedWalletService .
701+ On ("GetPendingDisbursementAsset" , mock .Anything , contractAddress ).
702+ Return (pendingAsset , nil ).
703+ Once ()
704+
683705 var capturedExpiresAt time.Time
684706 mockJWTManager .
685707 On ("GenerateToken" , mock .Anything , credentialID , contractAddress , mock .AnythingOfType ("time.Time" )).
@@ -700,11 +722,131 @@ func Test_PasskeyHandler_RefreshToken(t *testing.T) {
700722 err = json .Unmarshal (rr .Body .Bytes (), & respBody )
701723 require .NoError (t , err )
702724 assert .Equal (t , "refreshed-token" , respBody .Token )
725+ assert .True (t , respBody .IsVerificationPending )
726+ require .NotNil (t , respBody .PendingAsset )
727+ assert .Equal (t , pendingAsset .Code , respBody .PendingAsset .Code )
728+ assert .Equal (t , pendingAsset .Issuer , respBody .PendingAsset .Issuer )
703729
704730 expectedExpiry := time .Now ().Add (WalletTokenExpiration )
705731 assert .WithinDuration (t , expectedExpiry , capturedExpiresAt , 5 * time .Second )
706732}
707733
734+ func Test_PasskeyHandler_RefreshToken_ReceiverAlreadyRegistered (t * testing.T ) {
735+ mockWebAuthnService := walletMocks .NewMockWebAuthnService (t )
736+ mockEmbeddedWalletService := servicesMocks .NewMockEmbeddedWalletService (t )
737+ mockJWTManager := walletMocks .NewMockWalletJWTManager (t )
738+ handler := PasskeyHandler {
739+ WebAuthnService : mockWebAuthnService ,
740+ WalletJWTManager : mockJWTManager ,
741+ EmbeddedWalletService : mockEmbeddedWalletService ,
742+ }
743+
744+ rr := httptest .NewRecorder ()
745+ requestBody , err := json .Marshal (RefreshTokenRequest {
746+ Token : "valid-token" ,
747+ })
748+ require .NoError (t , err )
749+ ctx := context .Background ()
750+
751+ contractAddress := "CBGTG3VGUMVDZE6O4CRZ2LBCFP7O5XY2VQQQU7AVXLVDQHZLVQFRMHKX"
752+ credentialID := "test-credential-id"
753+
754+ mockJWTManager .
755+ On ("ValidateToken" , mock .Anything , "valid-token" ).
756+ Return (credentialID , contractAddress , nil ).
757+ Once ()
758+
759+ embeddedWallet := & data.EmbeddedWallet {
760+ ContractAddress : contractAddress ,
761+ CredentialID : credentialID ,
762+ RequiresVerification : true ,
763+ ReceiverWalletID : "rw-registered" ,
764+ }
765+ mockEmbeddedWalletService .
766+ On ("GetWalletByCredentialID" , mock .Anything , credentialID ).
767+ Return (embeddedWallet , nil ).
768+ Once ()
769+
770+ mockEmbeddedWalletService .
771+ On ("GetReceiverWalletByID" , mock .Anything , "rw-registered" ).
772+ Return (& data.ReceiverWallet {ID : "rw-registered" , Status : data .RegisteredReceiversWalletStatus }, nil ).
773+ Once ()
774+ mockEmbeddedWalletService .
775+ On ("GetPendingDisbursementAsset" , mock .Anything , contractAddress ).
776+ Return ((* data .Asset )(nil ), nil ).
777+ Once ()
778+
779+ mockJWTManager .
780+ On ("GenerateToken" , mock .Anything , credentialID , contractAddress , mock .AnythingOfType ("time.Time" )).
781+ Return ("refreshed-token" , nil ).
782+ Once ()
783+
784+ req , err := http .NewRequestWithContext (ctx , http .MethodPost , "/embedded-wallets/passkey/authentication/refresh" , strings .NewReader (string (requestBody )))
785+ require .NoError (t , err )
786+ req .Header .Set ("Content-Type" , "application/json" )
787+ http .HandlerFunc (handler .RefreshToken ).ServeHTTP (rr , req )
788+
789+ assert .Equal (t , http .StatusOK , rr .Result ().StatusCode )
790+
791+ var respBody RefreshTokenResponse
792+ err = json .Unmarshal (rr .Body .Bytes (), & respBody )
793+ require .NoError (t , err )
794+ assert .Equal (t , "refreshed-token" , respBody .Token )
795+ assert .False (t , respBody .IsVerificationPending )
796+ assert .Nil (t , respBody .PendingAsset )
797+ }
798+
799+ func Test_PasskeyHandler_RefreshToken_AssetLookupError (t * testing.T ) {
800+ mockWebAuthnService := walletMocks .NewMockWebAuthnService (t )
801+ mockEmbeddedWalletService := servicesMocks .NewMockEmbeddedWalletService (t )
802+ mockJWTManager := walletMocks .NewMockWalletJWTManager (t )
803+ handler := PasskeyHandler {
804+ WebAuthnService : mockWebAuthnService ,
805+ WalletJWTManager : mockJWTManager ,
806+ EmbeddedWalletService : mockEmbeddedWalletService ,
807+ }
808+
809+ rr := httptest .NewRecorder ()
810+ requestBody , err := json .Marshal (RefreshTokenRequest {Token : "valid-token" })
811+ require .NoError (t , err )
812+ ctx := context .Background ()
813+
814+ contractAddress := "CBGTG3VGUMVDZE6O4CRZ2LBCFP7O5XY2VQQQU7AVXLVDQHZLVQFRMHKX"
815+ credentialID := "test-credential-id"
816+ assetErr := errors .New ("asset lookup failed" )
817+
818+ mockJWTManager .
819+ On ("ValidateToken" , mock .Anything , "valid-token" ).
820+ Return (credentialID , contractAddress , nil ).
821+ Once ()
822+
823+ embeddedWallet := & data.EmbeddedWallet {
824+ ContractAddress : contractAddress ,
825+ CredentialID : credentialID ,
826+ RequiresVerification : true ,
827+ ReceiverWalletID : "rw-asset" ,
828+ }
829+ mockEmbeddedWalletService .
830+ On ("GetWalletByCredentialID" , mock .Anything , credentialID ).
831+ Return (embeddedWallet , nil ).
832+ Once ()
833+ mockEmbeddedWalletService .
834+ On ("GetReceiverWalletByID" , mock .Anything , "rw-asset" ).
835+ Return (& data.ReceiverWallet {ID : "rw-asset" , Status : data .ReadyReceiversWalletStatus }, nil ).
836+ Once ()
837+ mockEmbeddedWalletService .
838+ On ("GetPendingDisbursementAsset" , mock .Anything , contractAddress ).
839+ Return ((* data .Asset )(nil ), assetErr ).
840+ Once ()
841+
842+ req , err := http .NewRequestWithContext (ctx , http .MethodPost , "/embedded-wallets/passkey/authentication/refresh" , strings .NewReader (string (requestBody )))
843+ require .NoError (t , err )
844+ req .Header .Set ("Content-Type" , "application/json" )
845+ http .HandlerFunc (handler .RefreshToken ).ServeHTTP (rr , req )
846+
847+ assert .Equal (t , http .StatusInternalServerError , rr .Result ().StatusCode )
848+ }
849+
708850func Test_PasskeyHandler_RefreshToken_InvalidRequestBody (t * testing.T ) {
709851 mockWebAuthnService := walletMocks .NewMockWebAuthnService (t )
710852 mockEmbeddedWalletService := servicesMocks .NewMockEmbeddedWalletService (t )
@@ -851,6 +993,27 @@ func Test_PasskeyHandler_RefreshToken_GenerateTokenErrors(t *testing.T) {
851993 Return (credentialID , contractAddress , nil ).
852994 Once ()
853995
996+ embeddedWallet := & data.EmbeddedWallet {
997+ ContractAddress : contractAddress ,
998+ CredentialID : credentialID ,
999+ RequiresVerification : true ,
1000+ ReceiverWalletID : "rw-2" ,
1001+ }
1002+ mockEmbeddedWalletService .
1003+ On ("GetWalletByCredentialID" , mock .Anything , credentialID ).
1004+ Return (embeddedWallet , nil ).
1005+ Once ()
1006+
1007+ mockEmbeddedWalletService .
1008+ On ("GetReceiverWalletByID" , mock .Anything , "rw-2" ).
1009+ Return (& data.ReceiverWallet {ID : "rw-2" , Status : data .ReadyReceiversWalletStatus }, nil ).
1010+ Once ()
1011+
1012+ mockEmbeddedWalletService .
1013+ On ("GetPendingDisbursementAsset" , mock .Anything , contractAddress ).
1014+ Return ((* data .Asset )(nil ), nil ).
1015+ Once ()
1016+
8541017 mockJWTManager .
8551018 On ("GenerateToken" , mock .Anything , credentialID , contractAddress , mock .AnythingOfType ("time.Time" )).
8561019 Return ("" , tc .generateError ).
@@ -892,12 +1055,23 @@ func Test_PasskeyHandler_RefreshToken_UpdatesContractAddress(t *testing.T) {
8921055 Return (credentialID , oldContractAddress , nil ).
8931056 Once ()
8941057
1058+ embeddedWallet := & data.EmbeddedWallet {
1059+ CredentialID : credentialID ,
1060+ ContractAddress : newContractAddress ,
1061+ RequiresVerification : true ,
1062+ ReceiverWalletID : "rw-3" ,
1063+ }
8951064 mockEmbeddedWalletService .
8961065 On ("GetWalletByCredentialID" , mock .Anything , credentialID ).
897- Return (& data.EmbeddedWallet {
898- CredentialID : credentialID ,
899- ContractAddress : newContractAddress ,
900- }, nil ).
1066+ Return (embeddedWallet , nil ).
1067+ Once ()
1068+ mockEmbeddedWalletService .
1069+ On ("GetReceiverWalletByID" , mock .Anything , "rw-3" ).
1070+ Return (& data.ReceiverWallet {ID : "rw-3" , Status : data .ReadyReceiversWalletStatus }, nil ).
1071+ Once ()
1072+ mockEmbeddedWalletService .
1073+ On ("GetPendingDisbursementAsset" , mock .Anything , newContractAddress ).
1074+ Return ((* data .Asset )(nil ), nil ).
9011075 Once ()
9021076
9031077 mockJWTManager .
@@ -916,6 +1090,7 @@ func Test_PasskeyHandler_RefreshToken_UpdatesContractAddress(t *testing.T) {
9161090 err = json .Unmarshal (rr .Body .Bytes (), & respBody )
9171091 require .NoError (t , err )
9181092 assert .Equal (t , "refreshed-token-with-address" , respBody .Token )
1093+ assert .True (t , respBody .IsVerificationPending )
9191094}
9201095
9211096func Test_PasskeyHandler_RefreshToken_WalletLookupError (t * testing.T ) {
0 commit comments