github.com/Finschia/finschia-sdk@v0.49.1/x/fswap/keeper/msg_server_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/stretchr/testify/require"
     7  	tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
     8  
     9  	"github.com/Finschia/finschia-sdk/simapp"
    10  	"github.com/Finschia/finschia-sdk/testutil/testdata"
    11  	sdk "github.com/Finschia/finschia-sdk/types"
    12  	sdkerrors "github.com/Finschia/finschia-sdk/types/errors"
    13  	authtypes "github.com/Finschia/finschia-sdk/x/auth/types"
    14  	bank "github.com/Finschia/finschia-sdk/x/bank/types"
    15  	"github.com/Finschia/finschia-sdk/x/foundation"
    16  	fkeeper "github.com/Finschia/finschia-sdk/x/fswap/keeper"
    17  	"github.com/Finschia/finschia-sdk/x/fswap/types"
    18  )
    19  
    20  func (s *KeeperTestSuite) TestMsgSwap() {
    21  	swap2ExpectedAmount, ok := sdk.NewIntFromString("296159312000000")
    22  	s.Require().True(ok)
    23  	swap100ExpectedAmount, ok := sdk.NewIntFromString("14807965600000000")
    24  	s.Require().True(ok)
    25  	swapAllExpectedBalance, ok := sdk.NewIntFromString("18281438845984584000000")
    26  	s.Require().True(ok)
    27  	testCases := map[string]struct {
    28  		request          *types.MsgSwap
    29  		expectedAmount   sdk.Int
    30  		shouldThrowError bool
    31  		expectedError    error
    32  	}{
    33  		"swap 2 from-denom": {
    34  			&types.MsgSwap{
    35  				FromAddress:    s.accWithFromCoin.String(),
    36  				FromCoinAmount: sdk.NewCoin(s.swap.GetFromDenom(), sdk.NewInt(2)),
    37  				ToDenom:        s.swap.GetToDenom(),
    38  			},
    39  			swap2ExpectedAmount,
    40  			false,
    41  			nil,
    42  		},
    43  		"swap some": {
    44  			&types.MsgSwap{
    45  				FromAddress:    s.accWithFromCoin.String(),
    46  				FromCoinAmount: sdk.NewCoin(s.swap.GetFromDenom(), sdk.NewInt(100)),
    47  				ToDenom:        s.swap.GetToDenom(),
    48  			},
    49  			swap100ExpectedAmount,
    50  			false,
    51  			nil,
    52  		},
    53  		"swap all the balance": {
    54  			&types.MsgSwap{
    55  				FromAddress:    s.accWithFromCoin.String(),
    56  				FromCoinAmount: sdk.NewCoin(s.swap.GetFromDenom(), s.initBalance),
    57  				ToDenom:        s.swap.GetToDenom(),
    58  			},
    59  			swapAllExpectedBalance,
    60  			false,
    61  			nil,
    62  		},
    63  		"account holding to-coin only": {
    64  			&types.MsgSwap{
    65  				FromAddress:    s.accWithToCoin.String(),
    66  				FromCoinAmount: sdk.NewCoin(s.swap.GetFromDenom(), sdk.NewInt(100)),
    67  				ToDenom:        s.swap.GetToDenom(),
    68  			},
    69  			sdk.ZeroInt(),
    70  			true,
    71  			sdkerrors.ErrInsufficientFunds,
    72  		},
    73  	}
    74  	for name, tc := range testCases {
    75  		s.Run(name, func() {
    76  			ctx, _ := s.ctx.CacheContext()
    77  			err := s.keeper.SetSwap(ctx, s.swap, s.toDenomMetadata)
    78  			s.Require().NoError(err)
    79  
    80  			swapResponse, err := s.msgServer.Swap(sdk.WrapSDKContext(ctx), tc.request)
    81  			if tc.shouldThrowError {
    82  				s.Require().ErrorIs(err, tc.expectedError)
    83  				return
    84  			}
    85  			s.Require().NotNil(swapResponse)
    86  			s.Require().NoError(err)
    87  
    88  			from, err := sdk.AccAddressFromBech32(tc.request.FromAddress)
    89  			s.Require().NoError(err)
    90  			actualAmount := s.keeper.GetBalance(ctx, from, tc.request.GetToDenom()).Amount
    91  			s.Require().Equal(tc.expectedAmount, actualAmount)
    92  		})
    93  	}
    94  }
    95  
    96  func (s *KeeperTestSuite) TestMsgSwapAll() {
    97  	swapAllExpectedBalance, ok := sdk.NewIntFromString("18281438845984584000000")
    98  	s.Require().True(ok)
    99  	testCases := map[string]struct {
   100  		request          *types.MsgSwapAll
   101  		expectedAmount   sdk.Int
   102  		shouldThrowError bool
   103  		expectedError    error
   104  	}{
   105  		"swapAll": {
   106  			&types.MsgSwapAll{
   107  				FromAddress: s.accWithFromCoin.String(),
   108  				FromDenom:   s.swap.GetFromDenom(),
   109  				ToDenom:     s.swap.GetToDenom(),
   110  			},
   111  			swapAllExpectedBalance,
   112  			false,
   113  			nil,
   114  		},
   115  		"account holding to-coin only": {
   116  			&types.MsgSwapAll{
   117  				FromAddress: s.accWithToCoin.String(),
   118  				FromDenom:   s.swap.GetFromDenom(),
   119  				ToDenom:     s.swap.GetToDenom(),
   120  			},
   121  			s.initBalance,
   122  			true,
   123  			sdkerrors.ErrInsufficientFunds,
   124  		},
   125  	}
   126  	for name, tc := range testCases {
   127  		s.Run(name, func() {
   128  			ctx, _ := s.ctx.CacheContext()
   129  			err := s.keeper.SetSwap(ctx, s.swap, s.toDenomMetadata)
   130  			s.Require().NoError(err)
   131  
   132  			swapResponse, err := s.msgServer.SwapAll(sdk.WrapSDKContext(ctx), tc.request)
   133  			if tc.shouldThrowError {
   134  				s.Require().ErrorIs(err, tc.expectedError)
   135  				return
   136  			}
   137  			s.Require().NotNil(swapResponse)
   138  			s.Require().NoError(err)
   139  
   140  			from, err := sdk.AccAddressFromBech32(tc.request.FromAddress)
   141  			s.Require().NoError(err)
   142  			actualAmount := s.keeper.GetBalance(ctx, from, tc.request.GetToDenom()).Amount
   143  			s.Require().Equal(tc.expectedAmount, actualAmount)
   144  		})
   145  	}
   146  }
   147  
   148  func TestMsgSetSwap(t *testing.T) {
   149  	authority := authtypes.NewModuleAddress(foundation.ModuleName)
   150  	checkTx := false
   151  	app := simapp.Setup(checkTx)
   152  	testdata.RegisterInterfaces(app.InterfaceRegistry())
   153  	testdata.RegisterMsgServer(app.MsgServiceRouter(), testdata.MsgServerImpl{})
   154  	ctx := app.BaseApp.NewContext(checkTx, tmproto.Header{})
   155  	keeper := app.FswapKeeper
   156  	msgServer := fkeeper.NewMsgServer(keeper)
   157  	fromDenomStr := "cony"
   158  	fromDenom := bank.Metadata{
   159  		Description: "This is metadata for from-coin",
   160  		DenomUnits: []*bank.DenomUnit{
   161  			{Denom: fromDenomStr, Exponent: 0},
   162  		},
   163  		Base:    fromDenomStr,
   164  		Display: fromDenomStr,
   165  		Name:    "FROM",
   166  		Symbol:  "FROM",
   167  	}
   168  	app.BankKeeper.SetDenomMetaData(ctx, fromDenom)
   169  
   170  	testCases := map[string]struct {
   171  		request       *types.MsgSetSwap
   172  		expectedError error
   173  	}{
   174  		"valid": {
   175  			request: &types.MsgSetSwap{
   176  				Authority: authority.String(),
   177  				Swap: types.Swap{
   178  					FromDenom:           fromDenomStr,
   179  					ToDenom:             "kei",
   180  					AmountCapForToDenom: sdk.OneInt(),
   181  					SwapRate:            sdk.NewDec(1),
   182  				},
   183  				ToDenomMetadata: bank.Metadata{
   184  					Description: "desc",
   185  					DenomUnits: []*bank.DenomUnit{
   186  						{
   187  							Denom:    "kei",
   188  							Exponent: 0,
   189  							Aliases:  nil,
   190  						},
   191  					},
   192  					Base:    "kei",
   193  					Display: "kei",
   194  					Name:    "kei",
   195  					Symbol:  "KAIA",
   196  				},
   197  			},
   198  			expectedError: nil,
   199  		},
   200  		"invalid: authority": {
   201  			request: &types.MsgSetSwap{
   202  				Authority: "invalid-authority",
   203  				Swap: types.Swap{
   204  					FromDenom:           fromDenomStr,
   205  					ToDenom:             "kei",
   206  					AmountCapForToDenom: sdk.OneInt(),
   207  					SwapRate:            sdk.NewDec(1),
   208  				},
   209  				ToDenomMetadata: bank.Metadata{
   210  					Description: "desc",
   211  					DenomUnits: []*bank.DenomUnit{
   212  						{
   213  							Denom:    "kei",
   214  							Exponent: 0,
   215  							Aliases:  nil,
   216  						},
   217  					},
   218  					Base:    "kei",
   219  					Display: "kei",
   220  					Name:    "kei",
   221  					Symbol:  "KAIA",
   222  				},
   223  			},
   224  			expectedError: sdkerrors.ErrUnauthorized,
   225  		},
   226  		"invalid: Swap.ToDenom": {
   227  			request: &types.MsgSetSwap{
   228  				Authority: authority.String(),
   229  				Swap: types.Swap{
   230  					FromDenom:           fromDenomStr,
   231  					ToDenom:             fromDenomStr,
   232  					AmountCapForToDenom: sdk.OneInt(),
   233  					SwapRate:            sdk.NewDec(1),
   234  				},
   235  				ToDenomMetadata: bank.Metadata{
   236  					Description: "desc",
   237  					DenomUnits: []*bank.DenomUnit{
   238  						{
   239  							Denom:    "kei",
   240  							Exponent: 0,
   241  							Aliases:  nil,
   242  						},
   243  					},
   244  					Base:    "kei",
   245  					Display: "kei",
   246  					Name:    "kei",
   247  					Symbol:  "KAIA",
   248  				},
   249  			},
   250  			expectedError: sdkerrors.ErrInvalidRequest,
   251  		},
   252  	}
   253  	for name, tc := range testCases {
   254  		t.Run(name, func(t *testing.T) {
   255  			context, _ := ctx.CacheContext()
   256  			_, err := msgServer.SetSwap(sdk.WrapSDKContext(context), tc.request)
   257  			require.ErrorIs(t, err, tc.expectedError)
   258  		})
   259  	}
   260  }