cosmos-sdk/x/bank/client/testutil/grpc.go

286 lines
7.3 KiB
Go

package testutil
import (
"fmt"
"github.com/gogo/protobuf/proto"
"github.com/cosmos/cosmos-sdk/testutil"
"github.com/cosmos/cosmos-sdk/testutil/rest"
sdk "github.com/cosmos/cosmos-sdk/types"
grpctypes "github.com/cosmos/cosmos-sdk/types/grpc"
"github.com/cosmos/cosmos-sdk/types/query"
"github.com/cosmos/cosmos-sdk/x/bank/types"
)
func (s *IntegrationTestSuite) TestTotalSupplyGRPCHandler() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
headers map[string]string
respType proto.Message
expected proto.Message
}{
{
"test GRPC total supply",
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply", baseURL),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
&types.QueryTotalSupplyResponse{},
&types.QueryTotalSupplyResponse{
Supply: sdk.NewCoins(
sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens),
sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(10))),
),
Pagination: &query.PageResponse{
Total: 2,
},
},
},
{
"GRPC total supply of a specific denom",
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/%s", baseURL, s.cfg.BondDenom),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
&types.QuerySupplyOfResponse{},
&types.QuerySupplyOfResponse{
Amount: sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(10))),
},
},
{
"Query for `height` > 1",
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/%s", baseURL, s.cfg.BondDenom),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "2",
},
&types.QuerySupplyOfResponse{},
&types.QuerySupplyOfResponse{
Amount: sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(20))),
},
},
{
"Query params shouldn't be considered as height",
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/%s?height=2", baseURL, s.cfg.BondDenom),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
&types.QuerySupplyOfResponse{},
&types.QuerySupplyOfResponse{
Amount: sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Add(sdk.NewInt(10))),
},
},
{
"GRPC total supply of a bogus denom",
fmt.Sprintf("%s/cosmos/bank/v1beta1/supply/foobar", baseURL),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
&types.QuerySupplyOfResponse{},
&types.QuerySupplyOfResponse{
Amount: sdk.NewCoin("foobar", sdk.ZeroInt()),
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
s.Require().Equal(tc.expected.String(), tc.respType.String())
})
}
}
func (s *IntegrationTestSuite) TestDenomMetadataGRPCHandler() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
headers map[string]string
expErr bool
respType proto.Message
expected proto.Message
}{
{
"test GRPC client metadata",
fmt.Sprintf("%s/cosmos/bank/v1beta1/denoms_metadata", baseURL),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
false,
&types.QueryDenomsMetadataResponse{},
&types.QueryDenomsMetadataResponse{
Metadatas: []types.Metadata{
{
Name: "Cosmos Hub Atom",
Symbol: "ATOM",
Description: "The native staking token of the Cosmos Hub.",
DenomUnits: []*types.DenomUnit{
{
Denom: "uatom",
Exponent: 0,
Aliases: []string{"microatom"},
},
{
Denom: "atom",
Exponent: 6,
Aliases: []string{"ATOM"},
},
},
Base: "uatom",
Display: "atom",
},
{
Name: "Ethereum",
Symbol: "ETH",
Description: "Ethereum mainnet token",
DenomUnits: []*types.DenomUnit{
{
Denom: "wei",
Exponent: 0,
},
{
Denom: "eth",
Exponent: 6,
Aliases: []string{"ETH"},
},
},
Base: "wei",
Display: "eth",
},
},
Pagination: &query.PageResponse{Total: 2},
},
},
{
"GRPC client metadata of a specific denom",
fmt.Sprintf("%s/cosmos/bank/v1beta1/denoms_metadata/uatom", baseURL),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
false,
&types.QueryDenomMetadataResponse{},
&types.QueryDenomMetadataResponse{
Metadata: types.Metadata{
Name: "Cosmos Hub Atom",
Symbol: "ATOM",
Description: "The native staking token of the Cosmos Hub.",
DenomUnits: []*types.DenomUnit{
{
Denom: "uatom",
Exponent: 0,
Aliases: []string{"microatom"},
},
{
Denom: "atom",
Exponent: 6,
Aliases: []string{"ATOM"},
},
},
Base: "uatom",
Display: "atom",
},
},
},
{
"GRPC client metadata of a bogus denom",
fmt.Sprintf("%s/cosmos/bank/v1beta1/denoms_metadata/foobar", baseURL),
map[string]string{
grpctypes.GRPCBlockHeightHeader: "1",
},
true,
&types.QueryDenomMetadataResponse{},
&types.QueryDenomMetadataResponse{
Metadata: types.Metadata{
DenomUnits: []*types.DenomUnit{},
},
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := testutil.GetRequestWithHeaders(tc.url, tc.headers)
s.Require().NoError(err)
if tc.expErr {
s.Require().Error(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
} else {
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
s.Require().Equal(tc.expected.String(), tc.respType.String())
}
})
}
}
func (s *IntegrationTestSuite) TestBalancesGRPCHandler() {
val := s.network.Validators[0]
baseURL := val.APIAddress
testCases := []struct {
name string
url string
respType proto.Message
expected proto.Message
}{
{
"gRPC total account balance",
fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s", baseURL, val.Address.String()),
&types.QueryAllBalancesResponse{},
&types.QueryAllBalancesResponse{
Balances: sdk.NewCoins(
sdk.NewCoin(fmt.Sprintf("%stoken", val.Moniker), s.cfg.AccountTokens),
sdk.NewCoin(s.cfg.BondDenom, s.cfg.StakingTokens.Sub(s.cfg.BondedTokens)),
),
Pagination: &query.PageResponse{
Total: 2,
},
},
},
{
"gPRC account balance of a denom",
fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s/by_denom?denom=%s", baseURL, val.Address.String(), s.cfg.BondDenom),
&types.QueryBalanceResponse{},
&types.QueryBalanceResponse{
Balance: &sdk.Coin{
Denom: s.cfg.BondDenom,
Amount: s.cfg.StakingTokens.Sub(s.cfg.BondedTokens),
},
},
},
{
"gPRC account balance of a bogus denom",
fmt.Sprintf("%s/cosmos/bank/v1beta1/balances/%s/by_denom?denom=foobar", baseURL, val.Address.String()),
&types.QueryBalanceResponse{},
&types.QueryBalanceResponse{
Balance: &sdk.Coin{
Denom: "foobar",
Amount: sdk.NewInt(0),
},
},
},
}
for _, tc := range testCases {
tc := tc
s.Run(tc.name, func() {
resp, err := rest.GetRequest(tc.url)
s.Require().NoError(err)
s.Require().NoError(val.ClientCtx.Codec.UnmarshalJSON(resp, tc.respType))
s.Require().Equal(tc.expected.String(), tc.respType.String())
})
}
}