@@ -633,3 +633,186 @@ func TestSendFromModuleToAccount_InvalidRecipient(t *testing.T) {
633633 )
634634 require .ErrorContains (t , err , "Account address is invalid" )
635635}
636+
637+ func TestSendFromAccountToAccount (t * testing.T ) {
638+ testDenom := "TestSendFromAccountToAccount/Coin"
639+ testModuleName := "bridge"
640+ tests := map [string ]struct {
641+ // Setup.
642+ initialSenderBalance int64
643+ balanceToSend int64
644+ senderAddress string
645+ recipientAddress string
646+ // Expectations
647+ expectedErrContains string
648+ }{
649+ "Success - send between user accounts" : {
650+ initialSenderBalance : 1000 ,
651+ balanceToSend : 100 ,
652+ senderAddress : constants .AliceAccAddress .String (),
653+ recipientAddress : constants .BobAccAddress .String (),
654+ },
655+ "Success - send to module account" : {
656+ initialSenderBalance : 1000 ,
657+ balanceToSend : 100 ,
658+ senderAddress : constants .AliceAccAddress .String (),
659+ recipientAddress : authtypes .NewModuleAddress ("community_treasury" ).String (),
660+ },
661+ "Success - send to self" : {
662+ initialSenderBalance : 1000 ,
663+ balanceToSend : 100 ,
664+ senderAddress : constants .AliceAccAddress .String (),
665+ recipientAddress : constants .AliceAccAddress .String (),
666+ },
667+ "Success - send 0 amount" : {
668+ initialSenderBalance : 700 ,
669+ balanceToSend : 0 ,
670+ senderAddress : constants .AliceAccAddress .String (),
671+ recipientAddress : constants .BobAccAddress .String (),
672+ },
673+ "Error - insufficient funds" : {
674+ initialSenderBalance : 100 ,
675+ balanceToSend : 101 ,
676+ senderAddress : constants .AliceAccAddress .String (),
677+ recipientAddress : constants .BobAccAddress .String (),
678+ expectedErrContains : "insufficient funds" ,
679+ },
680+ }
681+
682+ for name , tc := range tests {
683+ t .Run (name , func (t * testing.T ) {
684+ // Initiate keepers and fund sender with initial balance.
685+ ks := keepertest .SendingKeepers (t )
686+ ctx , sendingKeeper , bankKeeper := ks .Ctx , ks .SendingKeeper , ks .BankKeeper
687+
688+ senderAddr := sdk .MustAccAddressFromBech32 (tc .senderAddress )
689+
690+ // Mint coins to bridging module and transfer to sender account
691+ err := bankKeeper .MintCoins (
692+ ctx ,
693+ testModuleName ,
694+ sdk .NewCoins (sdk .NewCoin (testDenom , sdkmath .NewInt (tc .initialSenderBalance ))),
695+ )
696+ require .NoError (t , err )
697+ err = bankKeeper .SendCoinsFromModuleToAccount (
698+ ctx ,
699+ testModuleName ,
700+ senderAddr ,
701+ sdk .NewCoins (sdk .NewCoin (testDenom , sdkmath .NewInt (tc .initialSenderBalance ))),
702+ )
703+ require .NoError (t , err )
704+
705+ startingSenderBalance := bankKeeper .GetBalance (
706+ ctx ,
707+ senderAddr ,
708+ testDenom ,
709+ )
710+ startingRecipientBalance := bankKeeper .GetBalance (
711+ ctx ,
712+ sdk .MustAccAddressFromBech32 (tc .recipientAddress ),
713+ testDenom ,
714+ )
715+
716+ // Send coins from account to account.
717+ err = sendingKeeper .SendFromAccountToAccount (
718+ ctx ,
719+ & types.MsgSendFromAccountToAccount {
720+ Authority : lib .GovModuleAddress .String (),
721+ Sender : tc .senderAddress ,
722+ Recipient : tc .recipientAddress ,
723+ Coin : sdk .NewCoin (testDenom , sdkmath .NewInt (tc .balanceToSend )),
724+ },
725+ )
726+
727+ // Verify ending balances and error.
728+ endingSenderBalance := bankKeeper .GetBalance (
729+ ctx ,
730+ senderAddr ,
731+ testDenom ,
732+ )
733+ endingRecipientBalance := bankKeeper .GetBalance (
734+ ctx ,
735+ sdk .MustAccAddressFromBech32 (tc .recipientAddress ),
736+ testDenom ,
737+ )
738+
739+ if tc .expectedErrContains != "" { // if error should occur.
740+ // Verify that error is as expected.
741+ require .ErrorContains (t , err , tc .expectedErrContains )
742+ // Verify that sender balance is unchanged.
743+ require .Equal (
744+ t ,
745+ startingSenderBalance .Amount .Int64 (),
746+ endingSenderBalance .Amount .Int64 (),
747+ )
748+ // Verify that recipient balance is unchanged.
749+ require .Equal (
750+ t ,
751+ startingRecipientBalance .Amount .Int64 (),
752+ endingRecipientBalance .Amount .Int64 (),
753+ )
754+ } else { // if send should succeed.
755+ // Verify that no error occurred.
756+ require .NoError (t , err )
757+ if tc .senderAddress == tc .recipientAddress {
758+ // If account sent to itself, verify that balance is unchanged.
759+ require .Equal (t , startingSenderBalance , endingSenderBalance )
760+ } else {
761+ // Otherwise, verify that sender balance is reduced by amount sent.
762+ require .Equal (
763+ t ,
764+ startingSenderBalance .Amount .Int64 ()- tc .balanceToSend ,
765+ endingSenderBalance .Amount .Int64 (),
766+ )
767+ // Verify that recipient balance is increased by amount sent.
768+ require .Equal (
769+ t ,
770+ startingRecipientBalance .Amount .Int64 ()+ tc .balanceToSend ,
771+ endingRecipientBalance .Amount .Int64 (),
772+ )
773+ }
774+ }
775+ })
776+ }
777+ }
778+
779+ func TestSendFromAccountToAccount_InvalidMsg (t * testing.T ) {
780+ msgEmptySender := & types.MsgSendFromAccountToAccount {
781+ Authority : lib .GovModuleAddress .String (),
782+ Sender : "" ,
783+ Recipient : constants .AliceAccAddress .String (),
784+ Coin : sdk .NewCoin ("adv4tnt" , sdkmath .NewInt (100 )),
785+ }
786+
787+ ks := keepertest .SendingKeepers (t )
788+ err := ks .SendingKeeper .SendFromAccountToAccount (ks .Ctx , msgEmptySender )
789+ require .ErrorContains (t , err , "Account address is invalid" )
790+ }
791+
792+ func TestSendFromAccountToAccount_InvalidRecipient (t * testing.T ) {
793+ ks := keepertest .SendingKeepers (t )
794+ err := ks .SendingKeeper .SendFromAccountToAccount (
795+ ks .Ctx ,
796+ & types.MsgSendFromAccountToAccount {
797+ Authority : lib .GovModuleAddress .String (),
798+ Sender : constants .AliceAccAddress .String (),
799+ Recipient : "dydx1abc" , // invalid recipient address
800+ Coin : sdk .NewCoin ("adv4tnt" , sdkmath .NewInt (1 )),
801+ },
802+ )
803+ require .ErrorContains (t , err , "Account address is invalid" )
804+ }
805+
806+ func TestSendFromAccountToAccount_InvalidSender (t * testing.T ) {
807+ ks := keepertest .SendingKeepers (t )
808+ err := ks .SendingKeeper .SendFromAccountToAccount (
809+ ks .Ctx ,
810+ & types.MsgSendFromAccountToAccount {
811+ Authority : lib .GovModuleAddress .String (),
812+ Sender : "dydx1abc" , // invalid sender address
813+ Recipient : constants .AliceAccAddress .String (),
814+ Coin : sdk .NewCoin ("adv4tnt" , sdkmath .NewInt (1 )),
815+ },
816+ )
817+ require .ErrorContains (t , err , "Account address is invalid" )
818+ }
0 commit comments