github.com/Finschia/finschia-sdk@v0.48.1/x/collection/keeper/grpc_query_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"github.com/gogo/protobuf/proto"
     5  
     6  	sdk "github.com/Finschia/finschia-sdk/types"
     7  	"github.com/Finschia/finschia-sdk/types/query"
     8  	"github.com/Finschia/finschia-sdk/x/collection"
     9  )
    10  
    11  func (s *KeeperTestSuite) TestQueryBalance() {
    12  	// empty request
    13  	_, err := s.queryServer.Balance(s.goCtx, nil)
    14  	s.Require().Error(err)
    15  
    16  	tokenID := collection.NewFTID(s.ftClassID)
    17  	testCases := map[string]struct {
    18  		contractID string
    19  		address    sdk.AccAddress
    20  		tokenID    string
    21  		valid      bool
    22  		postTest   func(res *collection.QueryBalanceResponse)
    23  	}{
    24  		"valid request": {
    25  			contractID: s.contractID,
    26  			address:    s.vendor,
    27  			tokenID:    tokenID,
    28  			valid:      true,
    29  			postTest: func(res *collection.QueryBalanceResponse) {
    30  				expected := collection.Coin{
    31  					TokenId: tokenID,
    32  					Amount:  s.balance,
    33  				}
    34  				s.Require().Equal(expected, res.Balance)
    35  			},
    36  		},
    37  		"valid request with zero amount": {
    38  			contractID: s.contractID,
    39  			address:    s.stranger,
    40  			tokenID:    tokenID,
    41  			valid:      true,
    42  			postTest: func(res *collection.QueryBalanceResponse) {
    43  				expected := collection.Coin{
    44  					TokenId: tokenID,
    45  					Amount:  sdk.ZeroInt(),
    46  				}
    47  				s.Require().Equal(expected, res.Balance)
    48  			},
    49  		},
    50  		"invalid contract id": {
    51  			address: s.vendor,
    52  			tokenID: tokenID,
    53  		},
    54  		"invalid address": {
    55  			contractID: s.contractID,
    56  			tokenID:    tokenID,
    57  		},
    58  		"valid token id": {
    59  			contractID: s.contractID,
    60  			address:    s.vendor,
    61  		},
    62  	}
    63  
    64  	for name, tc := range testCases {
    65  		s.Run(name, func() {
    66  			req := &collection.QueryBalanceRequest{
    67  				ContractId: tc.contractID,
    68  				Address:    tc.address.String(),
    69  				TokenId:    tc.tokenID,
    70  			}
    71  			res, err := s.queryServer.Balance(s.goCtx, req)
    72  			if !tc.valid {
    73  				s.Require().Error(err)
    74  				return
    75  			}
    76  			s.Require().NoError(err)
    77  			s.Require().NotNil(res)
    78  			tc.postTest(res)
    79  		})
    80  	}
    81  }
    82  
    83  func (s *KeeperTestSuite) TestQueryAllBalances() {
    84  	// empty request
    85  	_, err := s.queryServer.AllBalances(s.goCtx, nil)
    86  	s.Require().Error(err)
    87  
    88  	testCases := map[string]struct {
    89  		contractID string
    90  		address    sdk.AccAddress
    91  		valid      bool
    92  		count      uint64
    93  		postTest   func(res *collection.QueryAllBalancesResponse)
    94  	}{
    95  		"valid request": {
    96  			contractID: s.contractID,
    97  			address:    s.customer,
    98  			valid:      true,
    99  			postTest: func(res *collection.QueryAllBalancesResponse) {
   100  				s.Require().Equal(s.numRoots+1, len(res.Balances))
   101  			},
   102  		},
   103  		"valid request with limit": {
   104  			contractID: s.contractID,
   105  			address:    s.customer,
   106  			valid:      true,
   107  			count:      1,
   108  			postTest: func(res *collection.QueryAllBalancesResponse) {
   109  				s.Require().Equal(1, len(res.Balances))
   110  			},
   111  		},
   112  		"invalid contract id": {
   113  			address: s.customer,
   114  		},
   115  		"invalid address": {
   116  			contractID: s.contractID,
   117  		},
   118  	}
   119  
   120  	for name, tc := range testCases {
   121  		s.Run(name, func() {
   122  			pageReq := &query.PageRequest{}
   123  			if tc.count != 0 {
   124  				pageReq.Limit = tc.count
   125  			}
   126  			req := &collection.QueryAllBalancesRequest{
   127  				ContractId: tc.contractID,
   128  				Address:    tc.address.String(),
   129  				Pagination: pageReq,
   130  			}
   131  			res, err := s.queryServer.AllBalances(s.goCtx, req)
   132  			if !tc.valid {
   133  				s.Require().Error(err)
   134  				return
   135  			}
   136  			s.Require().NoError(err)
   137  			s.Require().NotNil(res)
   138  			tc.postTest(res)
   139  		})
   140  	}
   141  }
   142  
   143  func (s *KeeperTestSuite) TestQueryFTSupply() {
   144  	// empty request
   145  	_, err := s.queryServer.FTSupply(s.goCtx, nil)
   146  	s.Require().Error(err)
   147  
   148  	tokenID := collection.NewFTID(s.ftClassID)
   149  	testCases := map[string]struct {
   150  		contractID string
   151  		tokenID    string
   152  		valid      bool
   153  		postTest   func(res *collection.QueryFTSupplyResponse)
   154  	}{
   155  		"valid request": {
   156  			contractID: s.contractID,
   157  			tokenID:    tokenID,
   158  			valid:      true,
   159  			postTest: func(res *collection.QueryFTSupplyResponse) {
   160  				s.Require().Equal(s.balance.Mul(sdk.NewInt(3)), res.Supply)
   161  			},
   162  		},
   163  		"collection not found": {
   164  			contractID: "deadbeef",
   165  			tokenID:    tokenID,
   166  			valid:      true,
   167  			postTest: func(res *collection.QueryFTSupplyResponse) {
   168  				s.Require().Equal(sdk.ZeroInt(), res.Supply)
   169  			},
   170  		},
   171  		"token not found": {
   172  			contractID: s.contractID,
   173  			tokenID:    collection.NewFTID("00bab10c"),
   174  			valid:      true,
   175  			postTest: func(res *collection.QueryFTSupplyResponse) {
   176  				s.Require().Equal(sdk.ZeroInt(), res.Supply)
   177  			},
   178  		},
   179  		"not a class of ft": {
   180  			contractID: s.contractID,
   181  			tokenID:    collection.NewFTID(s.nftClassID),
   182  			valid:      true,
   183  			postTest: func(res *collection.QueryFTSupplyResponse) {
   184  				s.Require().Equal(sdk.ZeroInt(), res.Supply)
   185  			},
   186  		},
   187  		"invalid contract id": {
   188  			tokenID: tokenID,
   189  		},
   190  		"invalid token id": {
   191  			contractID: s.contractID,
   192  		},
   193  	}
   194  
   195  	for name, tc := range testCases {
   196  		s.Run(name, func() {
   197  			req := &collection.QueryFTSupplyRequest{
   198  				ContractId: tc.contractID,
   199  				TokenId:    tc.tokenID,
   200  			}
   201  			res, err := s.queryServer.FTSupply(s.goCtx, req)
   202  			if !tc.valid {
   203  				s.Require().Error(err)
   204  				return
   205  			}
   206  			s.Require().NoError(err)
   207  			s.Require().NotNil(res)
   208  			tc.postTest(res)
   209  		})
   210  	}
   211  }
   212  
   213  func (s *KeeperTestSuite) TestQueryFTMinted() {
   214  	// empty request
   215  	_, err := s.queryServer.FTMinted(s.goCtx, nil)
   216  	s.Require().Error(err)
   217  
   218  	tokenID := collection.NewFTID(s.ftClassID)
   219  	testCases := map[string]struct {
   220  		contractID string
   221  		tokenID    string
   222  		valid      bool
   223  		postTest   func(res *collection.QueryFTMintedResponse)
   224  	}{
   225  		"valid request": {
   226  			contractID: s.contractID,
   227  			tokenID:    tokenID,
   228  			valid:      true,
   229  			postTest: func(res *collection.QueryFTMintedResponse) {
   230  				s.Require().Equal(s.balance.Mul(sdk.NewInt(6)), res.Minted)
   231  			},
   232  		},
   233  		"collection not found": {
   234  			contractID: "deadbeef",
   235  			tokenID:    tokenID,
   236  			valid:      true,
   237  			postTest: func(res *collection.QueryFTMintedResponse) {
   238  				s.Require().Equal(sdk.ZeroInt(), res.Minted)
   239  			},
   240  		},
   241  		"token not found": {
   242  			contractID: s.contractID,
   243  			tokenID:    collection.NewFTID("00bab10c"),
   244  			valid:      true,
   245  			postTest: func(res *collection.QueryFTMintedResponse) {
   246  				s.Require().Equal(sdk.ZeroInt(), res.Minted)
   247  			},
   248  		},
   249  		"not a class of ft": {
   250  			contractID: s.contractID,
   251  			tokenID:    collection.NewFTID(s.nftClassID),
   252  			valid:      true,
   253  			postTest: func(res *collection.QueryFTMintedResponse) {
   254  				s.Require().Equal(sdk.ZeroInt(), res.Minted)
   255  			},
   256  		},
   257  		"invalid contract id": {
   258  			tokenID: tokenID,
   259  		},
   260  		"invalid token id": {
   261  			contractID: s.contractID,
   262  		},
   263  	}
   264  
   265  	for name, tc := range testCases {
   266  		s.Run(name, func() {
   267  			req := &collection.QueryFTMintedRequest{
   268  				ContractId: tc.contractID,
   269  				TokenId:    tc.tokenID,
   270  			}
   271  			res, err := s.queryServer.FTMinted(s.goCtx, req)
   272  			if !tc.valid {
   273  				s.Require().Error(err)
   274  				return
   275  			}
   276  			s.Require().NoError(err)
   277  			s.Require().NotNil(res)
   278  			tc.postTest(res)
   279  		})
   280  	}
   281  }
   282  
   283  func (s *KeeperTestSuite) TestQueryFTBurnt() {
   284  	// empty request
   285  	_, err := s.queryServer.FTBurnt(s.goCtx, nil)
   286  	s.Require().Error(err)
   287  
   288  	tokenID := collection.NewFTID(s.ftClassID)
   289  	testCases := map[string]struct {
   290  		contractID string
   291  		tokenID    string
   292  		valid      bool
   293  		postTest   func(res *collection.QueryFTBurntResponse)
   294  	}{
   295  		"valid request": {
   296  			contractID: s.contractID,
   297  			tokenID:    tokenID,
   298  			valid:      true,
   299  			postTest: func(res *collection.QueryFTBurntResponse) {
   300  				s.Require().Equal(s.balance.Mul(sdk.NewInt(3)), res.Burnt)
   301  			},
   302  		},
   303  		"collection not found": {
   304  			contractID: "deadbeef",
   305  			tokenID:    tokenID,
   306  			valid:      true,
   307  			postTest: func(res *collection.QueryFTBurntResponse) {
   308  				s.Require().Equal(sdk.ZeroInt(), res.Burnt)
   309  			},
   310  		},
   311  		"token not found": {
   312  			contractID: s.contractID,
   313  			tokenID:    collection.NewFTID("00bab10c"),
   314  			valid:      true,
   315  			postTest: func(res *collection.QueryFTBurntResponse) {
   316  				s.Require().Equal(sdk.ZeroInt(), res.Burnt)
   317  			},
   318  		},
   319  		"not a class of ft": {
   320  			contractID: s.contractID,
   321  			tokenID:    collection.NewFTID(s.nftClassID),
   322  			valid:      true,
   323  			postTest: func(res *collection.QueryFTBurntResponse) {
   324  				s.Require().Equal(sdk.ZeroInt(), res.Burnt)
   325  			},
   326  		},
   327  		"invalid contract id": {
   328  			tokenID: tokenID,
   329  		},
   330  		"invalid token id": {
   331  			contractID: s.contractID,
   332  		},
   333  	}
   334  
   335  	for name, tc := range testCases {
   336  		s.Run(name, func() {
   337  			req := &collection.QueryFTBurntRequest{
   338  				ContractId: tc.contractID,
   339  				TokenId:    tc.tokenID,
   340  			}
   341  			res, err := s.queryServer.FTBurnt(s.goCtx, req)
   342  			if !tc.valid {
   343  				s.Require().Error(err)
   344  				return
   345  			}
   346  			s.Require().NoError(err)
   347  			s.Require().NotNil(res)
   348  			tc.postTest(res)
   349  		})
   350  	}
   351  }
   352  
   353  func (s *KeeperTestSuite) TestQueryNFTSupply() {
   354  	// empty request
   355  	_, err := s.queryServer.NFTSupply(s.goCtx, nil)
   356  	s.Require().Error(err)
   357  
   358  	testCases := map[string]struct {
   359  		contractID string
   360  		tokenType  string
   361  		valid      bool
   362  		postTest   func(res *collection.QueryNFTSupplyResponse)
   363  	}{
   364  		"valid request": {
   365  			contractID: s.contractID,
   366  			tokenType:  s.nftClassID,
   367  			valid:      true,
   368  			postTest: func(res *collection.QueryNFTSupplyResponse) {
   369  				s.Require().EqualValues(s.numNFTs*3, res.Supply.Int64())
   370  			},
   371  		},
   372  		"collection not found": {
   373  			contractID: "deadbeef",
   374  			tokenType:  s.nftClassID,
   375  			valid:      true,
   376  			postTest: func(res *collection.QueryNFTSupplyResponse) {
   377  				s.Require().Equal(sdk.ZeroInt(), res.Supply)
   378  			},
   379  		},
   380  		"token type not found": {
   381  			contractID: s.contractID,
   382  			tokenType:  "deadbeef",
   383  			valid:      true,
   384  			postTest: func(res *collection.QueryNFTSupplyResponse) {
   385  				s.Require().Equal(sdk.ZeroInt(), res.Supply)
   386  			},
   387  		},
   388  		"not a class of nft": {
   389  			contractID: s.contractID,
   390  			tokenType:  s.ftClassID,
   391  			valid:      true,
   392  			postTest: func(res *collection.QueryNFTSupplyResponse) {
   393  				s.Require().Equal(sdk.ZeroInt(), res.Supply)
   394  			},
   395  		},
   396  		"invalid contract id": {
   397  			tokenType: s.nftClassID,
   398  		},
   399  		"invalid token type": {
   400  			contractID: s.contractID,
   401  		},
   402  	}
   403  
   404  	for name, tc := range testCases {
   405  		s.Run(name, func() {
   406  			req := &collection.QueryNFTSupplyRequest{
   407  				ContractId: tc.contractID,
   408  				TokenType:  tc.tokenType,
   409  			}
   410  			res, err := s.queryServer.NFTSupply(s.goCtx, req)
   411  			if !tc.valid {
   412  				s.Require().Error(err)
   413  				return
   414  			}
   415  			s.Require().NoError(err)
   416  			s.Require().NotNil(res)
   417  			tc.postTest(res)
   418  		})
   419  	}
   420  }
   421  
   422  func (s *KeeperTestSuite) TestQueryNFTMinted() {
   423  	// empty request
   424  	_, err := s.queryServer.NFTMinted(s.goCtx, nil)
   425  	s.Require().Error(err)
   426  
   427  	testCases := map[string]struct {
   428  		contractID string
   429  		tokenType  string
   430  		valid      bool
   431  		postTest   func(res *collection.QueryNFTMintedResponse)
   432  	}{
   433  		"valid request": {
   434  			contractID: s.contractID,
   435  			tokenType:  s.nftClassID,
   436  			valid:      true,
   437  			postTest: func(res *collection.QueryNFTMintedResponse) {
   438  				s.Require().EqualValues(s.numNFTs*3, res.Minted.Int64())
   439  			},
   440  		},
   441  		"collection not found": {
   442  			contractID: "deadbeef",
   443  			tokenType:  s.nftClassID,
   444  			valid:      true,
   445  			postTest: func(res *collection.QueryNFTMintedResponse) {
   446  				s.Require().Equal(sdk.ZeroInt(), res.Minted)
   447  			},
   448  		},
   449  		"token type not found": {
   450  			contractID: s.contractID,
   451  			tokenType:  "deadbeef",
   452  			valid:      true,
   453  			postTest: func(res *collection.QueryNFTMintedResponse) {
   454  				s.Require().Equal(sdk.ZeroInt(), res.Minted)
   455  			},
   456  		},
   457  		"not a class of nft": {
   458  			contractID: s.contractID,
   459  			tokenType:  s.ftClassID,
   460  			valid:      true,
   461  			postTest: func(res *collection.QueryNFTMintedResponse) {
   462  				s.Require().Equal(sdk.ZeroInt(), res.Minted)
   463  			},
   464  		},
   465  		"invalid contract id": {
   466  			tokenType: s.nftClassID,
   467  		},
   468  		"invalid token type": {
   469  			contractID: s.contractID,
   470  		},
   471  	}
   472  
   473  	for name, tc := range testCases {
   474  		s.Run(name, func() {
   475  			req := &collection.QueryNFTMintedRequest{
   476  				ContractId: tc.contractID,
   477  				TokenType:  tc.tokenType,
   478  			}
   479  			res, err := s.queryServer.NFTMinted(s.goCtx, req)
   480  			if !tc.valid {
   481  				s.Require().Error(err)
   482  				return
   483  			}
   484  			s.Require().NoError(err)
   485  			s.Require().NotNil(res)
   486  			tc.postTest(res)
   487  		})
   488  	}
   489  }
   490  
   491  func (s *KeeperTestSuite) TestQueryNFTBurnt() {
   492  	// empty request
   493  	_, err := s.queryServer.NFTBurnt(s.goCtx, nil)
   494  	s.Require().Error(err)
   495  
   496  	testCases := map[string]struct {
   497  		contractID string
   498  		tokenType  string
   499  		valid      bool
   500  		postTest   func(res *collection.QueryNFTBurntResponse)
   501  	}{
   502  		"valid request": {
   503  			contractID: s.contractID,
   504  			tokenType:  s.nftClassID,
   505  			valid:      true,
   506  			postTest: func(res *collection.QueryNFTBurntResponse) {
   507  				s.Require().Equal(sdk.ZeroInt(), res.Burnt)
   508  			},
   509  		},
   510  		"collection not found": {
   511  			contractID: "deadbeef",
   512  			tokenType:  s.nftClassID,
   513  			valid:      true,
   514  			postTest: func(res *collection.QueryNFTBurntResponse) {
   515  				s.Require().Equal(sdk.ZeroInt(), res.Burnt)
   516  			},
   517  		},
   518  		"token type not found": {
   519  			contractID: s.contractID,
   520  			tokenType:  "deadbeef",
   521  			valid:      true,
   522  			postTest: func(res *collection.QueryNFTBurntResponse) {
   523  				s.Require().Equal(sdk.ZeroInt(), res.Burnt)
   524  			},
   525  		},
   526  		"not a class of nft": {
   527  			contractID: s.contractID,
   528  			tokenType:  s.ftClassID,
   529  			valid:      true,
   530  			postTest: func(res *collection.QueryNFTBurntResponse) {
   531  				s.Require().Equal(sdk.ZeroInt(), res.Burnt)
   532  			},
   533  		},
   534  		"invalid contract id": {
   535  			tokenType: s.nftClassID,
   536  		},
   537  		"invalid token type": {
   538  			contractID: s.contractID,
   539  		},
   540  	}
   541  
   542  	for name, tc := range testCases {
   543  		s.Run(name, func() {
   544  			req := &collection.QueryNFTBurntRequest{
   545  				ContractId: tc.contractID,
   546  				TokenType:  tc.tokenType,
   547  			}
   548  			res, err := s.queryServer.NFTBurnt(s.goCtx, req)
   549  			if !tc.valid {
   550  				s.Require().Error(err)
   551  				return
   552  			}
   553  			s.Require().NoError(err)
   554  			s.Require().NotNil(res)
   555  			tc.postTest(res)
   556  		})
   557  	}
   558  }
   559  
   560  func (s *KeeperTestSuite) TestQueryContract() {
   561  	// empty request
   562  	_, err := s.queryServer.Contract(s.goCtx, nil)
   563  	s.Require().Error(err)
   564  
   565  	testCases := map[string]struct {
   566  		contractID string
   567  		valid      bool
   568  		postTest   func(res *collection.QueryContractResponse)
   569  	}{
   570  		"valid request": {
   571  			contractID: s.contractID,
   572  			valid:      true,
   573  			postTest: func(res *collection.QueryContractResponse) {
   574  				s.Require().Equal(s.contractID, res.Contract.Id)
   575  			},
   576  		},
   577  		"invalid contract id": {},
   578  		"no such an id": {
   579  			contractID: "deadbeef",
   580  		},
   581  	}
   582  
   583  	for name, tc := range testCases {
   584  		s.Run(name, func() {
   585  			req := &collection.QueryContractRequest{
   586  				ContractId: tc.contractID,
   587  			}
   588  			res, err := s.queryServer.Contract(s.goCtx, req)
   589  			if !tc.valid {
   590  				s.Require().Error(err)
   591  				return
   592  			}
   593  			s.Require().NoError(err)
   594  			s.Require().NotNil(res)
   595  			tc.postTest(res)
   596  		})
   597  	}
   598  }
   599  
   600  func (s *KeeperTestSuite) TestQueryTokenClassTypeName() {
   601  	// empty request
   602  	_, err := s.queryServer.TokenClassTypeName(s.goCtx, nil)
   603  	s.Require().Error(err)
   604  
   605  	testCases := map[string]struct {
   606  		contractID string
   607  		classID    string
   608  		valid      bool
   609  		postTest   func(res *collection.QueryTokenClassTypeNameResponse)
   610  	}{
   611  		"valid request": {
   612  			contractID: s.contractID,
   613  			classID:    s.ftClassID,
   614  			valid:      true,
   615  			postTest: func(res *collection.QueryTokenClassTypeNameResponse) {
   616  				s.Require().Equal(proto.MessageName(&collection.FTClass{}), res.Name)
   617  			},
   618  		},
   619  		"invalid contract id": {
   620  			classID: s.ftClassID,
   621  		},
   622  		"invalid class id": {
   623  			contractID: s.contractID,
   624  		},
   625  		"collection not found": {
   626  			contractID: "deadbeef",
   627  			classID:    s.ftClassID,
   628  		},
   629  		"class not found": {
   630  			contractID: s.contractID,
   631  			classID:    "00bab10c",
   632  		},
   633  	}
   634  
   635  	for name, tc := range testCases {
   636  		s.Run(name, func() {
   637  			req := &collection.QueryTokenClassTypeNameRequest{
   638  				ContractId: tc.contractID,
   639  				ClassId:    tc.classID,
   640  			}
   641  			res, err := s.queryServer.TokenClassTypeName(s.goCtx, req)
   642  			if !tc.valid {
   643  				s.Require().Error(err)
   644  				return
   645  			}
   646  			s.Require().NoError(err)
   647  			s.Require().NotNil(res)
   648  			tc.postTest(res)
   649  		})
   650  	}
   651  }
   652  
   653  func (s *KeeperTestSuite) TestQueryTokenType() {
   654  	// empty request
   655  	_, err := s.queryServer.TokenType(s.goCtx, nil)
   656  	s.Require().Error(err)
   657  
   658  	testCases := map[string]struct {
   659  		contractID string
   660  		tokenType  string
   661  		valid      bool
   662  		postTest   func(res *collection.QueryTokenTypeResponse)
   663  	}{
   664  		"valid request": {
   665  			contractID: s.contractID,
   666  			tokenType:  s.nftClassID,
   667  			valid:      true,
   668  			postTest: func(res *collection.QueryTokenTypeResponse) {
   669  				s.Require().Equal(s.contractID, res.TokenType.ContractId)
   670  				s.Require().Equal(s.nftClassID, res.TokenType.TokenType)
   671  			},
   672  		},
   673  		"invalid contract id": {
   674  			tokenType: s.nftClassID,
   675  		},
   676  		"invalid token type": {
   677  			contractID: s.contractID,
   678  		},
   679  		"collection not found": {
   680  			contractID: "deadbeef",
   681  			tokenType:  s.nftClassID,
   682  		},
   683  		"token type not found": {
   684  			contractID: s.contractID,
   685  			tokenType:  "deadbeef",
   686  		},
   687  		"not a class of nft": {
   688  			contractID: s.contractID,
   689  			tokenType:  s.ftClassID,
   690  		},
   691  	}
   692  
   693  	for name, tc := range testCases {
   694  		s.Run(name, func() {
   695  			req := &collection.QueryTokenTypeRequest{
   696  				ContractId: tc.contractID,
   697  				TokenType:  tc.tokenType,
   698  			}
   699  			res, err := s.queryServer.TokenType(s.goCtx, req)
   700  			if !tc.valid {
   701  				s.Require().Error(err)
   702  				return
   703  			}
   704  			s.Require().NoError(err)
   705  			s.Require().NotNil(res)
   706  			tc.postTest(res)
   707  		})
   708  	}
   709  }
   710  
   711  func (s *KeeperTestSuite) TestQueryToken() {
   712  	// empty request
   713  	_, err := s.queryServer.Token(s.goCtx, nil)
   714  	s.Require().Error(err)
   715  
   716  	ftTokenID := collection.NewFTID(s.ftClassID)
   717  	nftTokenID := collection.NewNFTID(s.nftClassID, 1)
   718  	testCases := map[string]struct {
   719  		contractID string
   720  		tokenID    string
   721  		valid      bool
   722  		postTest   func(res *collection.QueryTokenResponse)
   723  	}{
   724  		"valid ft request": {
   725  			contractID: s.contractID,
   726  			tokenID:    ftTokenID,
   727  			valid:      true,
   728  			postTest: func(res *collection.QueryTokenResponse) {
   729  				s.Require().Equal("/lbm.collection.v1.FT", res.Token.TypeUrl)
   730  				token := collection.TokenFromAny(&res.Token)
   731  				ft, ok := token.(*collection.FT)
   732  				s.Require().True(ok)
   733  				s.Require().Equal(s.contractID, ft.ContractId)
   734  				s.Require().Equal(ftTokenID, ft.TokenId)
   735  			},
   736  		},
   737  		"valid nft request": {
   738  			contractID: s.contractID,
   739  			tokenID:    nftTokenID,
   740  			valid:      true,
   741  			postTest: func(res *collection.QueryTokenResponse) {
   742  				s.Require().Equal("/lbm.collection.v1.OwnerNFT", res.Token.TypeUrl)
   743  				token := collection.TokenFromAny(&res.Token)
   744  				nft, ok := token.(*collection.OwnerNFT)
   745  				s.Require().True(ok)
   746  				s.Require().Equal(s.contractID, nft.ContractId)
   747  				s.Require().Equal(nftTokenID, nft.TokenId)
   748  			},
   749  		},
   750  		"invalid contract id": {
   751  			tokenID: ftTokenID,
   752  		},
   753  		"invalid token id": {
   754  			contractID: s.contractID,
   755  		},
   756  		"collection not found": {
   757  			contractID: "deadbeef",
   758  			tokenID:    ftTokenID,
   759  		},
   760  		"no such a fungible token": {
   761  			contractID: s.contractID,
   762  			tokenID:    collection.NewFTID("00bab10c"),
   763  		},
   764  		"no such a non-fungible token": {
   765  			contractID: s.contractID,
   766  			tokenID:    collection.NewNFTID("deadbeef", 1),
   767  		},
   768  	}
   769  
   770  	for name, tc := range testCases {
   771  		s.Run(name, func() {
   772  			req := &collection.QueryTokenRequest{
   773  				ContractId: tc.contractID,
   774  				TokenId:    tc.tokenID,
   775  			}
   776  			res, err := s.queryServer.Token(s.goCtx, req)
   777  			if !tc.valid {
   778  				s.Require().Error(err)
   779  				return
   780  			}
   781  			s.Require().NoError(err)
   782  			s.Require().NotNil(res)
   783  			tc.postTest(res)
   784  		})
   785  	}
   786  }
   787  
   788  func (s *KeeperTestSuite) TestQueryRoot() {
   789  	// empty request
   790  	_, err := s.queryServer.Root(s.goCtx, nil)
   791  	s.Require().Error(err)
   792  
   793  	tokenID := collection.NewNFTID(s.nftClassID, 2)
   794  	testCases := map[string]struct {
   795  		contractID string
   796  		tokenID    string
   797  		valid      bool
   798  		postTest   func(res *collection.QueryRootResponse)
   799  	}{
   800  		"valid request": {
   801  			contractID: s.contractID,
   802  			tokenID:    tokenID,
   803  			valid:      true,
   804  			postTest: func(res *collection.QueryRootResponse) {
   805  				s.Require().Equal(collection.NewNFTID(s.nftClassID, 1), res.Root.TokenId)
   806  			},
   807  		},
   808  		"invalid contract id": {
   809  			tokenID: tokenID,
   810  		},
   811  		"invalid token id": {
   812  			contractID: s.contractID,
   813  		},
   814  		"collection not found": {
   815  			contractID: "deadbeef",
   816  			tokenID:    tokenID,
   817  		},
   818  		"token not found": {
   819  			contractID: s.contractID,
   820  			tokenID:    collection.NewNFTID("deadbeef", 1),
   821  		},
   822  	}
   823  
   824  	for name, tc := range testCases {
   825  		s.Run(name, func() {
   826  			req := &collection.QueryRootRequest{
   827  				ContractId: tc.contractID,
   828  				TokenId:    tc.tokenID,
   829  			}
   830  			res, err := s.queryServer.Root(s.goCtx, req)
   831  			if !tc.valid {
   832  				s.Require().Error(err)
   833  				return
   834  			}
   835  			s.Require().NoError(err)
   836  			s.Require().NotNil(res)
   837  			tc.postTest(res)
   838  		})
   839  	}
   840  }
   841  
   842  func (s *KeeperTestSuite) TestQueryHasParent() {
   843  	// empty request
   844  	_, err := s.queryServer.HasParent(s.goCtx, nil)
   845  	s.Require().Error(err)
   846  
   847  	tokenID := collection.NewNFTID(s.nftClassID, 2)
   848  	testCases := map[string]struct {
   849  		contractID string
   850  		tokenID    string
   851  		valid      bool
   852  		postTest   func(res *collection.QueryHasParentResponse)
   853  	}{
   854  		"valid request": {
   855  			contractID: s.contractID,
   856  			tokenID:    tokenID,
   857  			valid:      true,
   858  			postTest: func(res *collection.QueryHasParentResponse) {
   859  				s.Require().NotNil(res)
   860  				s.Require().Equal(true, res.HasParent)
   861  			},
   862  		},
   863  		"valid request with no parent": {
   864  			contractID: s.contractID,
   865  			tokenID:    collection.NewNFTID(s.nftClassID, 1),
   866  			valid:      true,
   867  			postTest: func(res *collection.QueryHasParentResponse) {
   868  				s.Require().NotNil(res)
   869  				s.Require().Equal(false, res.HasParent)
   870  			},
   871  		},
   872  		"collection not found": {
   873  			contractID: "deadbeef",
   874  			tokenID:    tokenID,
   875  			valid:      true,
   876  			postTest: func(res *collection.QueryHasParentResponse) {
   877  				s.Require().NotNil(res)
   878  				s.Require().Equal(false, res.HasParent)
   879  			},
   880  		},
   881  		"token not found": {
   882  			contractID: s.contractID,
   883  			tokenID:    collection.NewNFTID("deadbeef", 1),
   884  			valid:      true,
   885  			postTest: func(res *collection.QueryHasParentResponse) {
   886  				s.Require().NotNil(res)
   887  				s.Require().Equal(false, res.HasParent)
   888  			},
   889  		},
   890  		"invalid contract id": {
   891  			tokenID: tokenID,
   892  		},
   893  		"invalid token id": {
   894  			contractID: s.contractID,
   895  		},
   896  	}
   897  
   898  	for name, tc := range testCases {
   899  		s.Run(name, func() {
   900  			req := &collection.QueryHasParentRequest{
   901  				ContractId: tc.contractID,
   902  				TokenId:    tc.tokenID,
   903  			}
   904  			res, err := s.queryServer.HasParent(s.goCtx, req)
   905  			if !tc.valid {
   906  				s.Require().Error(err)
   907  				return
   908  			}
   909  			s.Require().NoError(err)
   910  			tc.postTest(res)
   911  		})
   912  	}
   913  }
   914  
   915  func (s *KeeperTestSuite) TestQueryParent() {
   916  	// empty request
   917  	_, err := s.queryServer.Parent(s.goCtx, nil)
   918  	s.Require().Error(err)
   919  
   920  	tokenID := collection.NewNFTID(s.nftClassID, 2)
   921  	testCases := map[string]struct {
   922  		contractID string
   923  		tokenID    string
   924  		valid      bool
   925  		postTest   func(res *collection.QueryParentResponse)
   926  	}{
   927  		"valid request": {
   928  			contractID: s.contractID,
   929  			tokenID:    tokenID,
   930  			valid:      true,
   931  			postTest: func(res *collection.QueryParentResponse) {
   932  				s.Require().Equal(collection.NewNFTID(s.nftClassID, 1), res.Parent.TokenId)
   933  			},
   934  		},
   935  		"invalid contract id": {
   936  			tokenID: tokenID,
   937  		},
   938  		"invalid token id": {
   939  			contractID: s.contractID,
   940  		},
   941  		"collection not found": {
   942  			contractID: "deadbeef",
   943  			tokenID:    tokenID,
   944  		},
   945  		"token not found": {
   946  			contractID: s.contractID,
   947  			tokenID:    collection.NewNFTID("deadbeef", 1),
   948  		},
   949  		"no parent": {
   950  			contractID: s.contractID,
   951  			tokenID:    collection.NewNFTID(s.nftClassID, 1),
   952  		},
   953  	}
   954  
   955  	for name, tc := range testCases {
   956  		s.Run(name, func() {
   957  			req := &collection.QueryParentRequest{
   958  				ContractId: tc.contractID,
   959  				TokenId:    tc.tokenID,
   960  			}
   961  			res, err := s.queryServer.Parent(s.goCtx, req)
   962  			if !tc.valid {
   963  				s.Require().Error(err)
   964  				return
   965  			}
   966  			s.Require().NoError(err)
   967  			s.Require().NotNil(res)
   968  			tc.postTest(res)
   969  		})
   970  	}
   971  }
   972  
   973  func (s *KeeperTestSuite) TestQueryChildren() {
   974  	// empty request
   975  	_, err := s.queryServer.Children(s.goCtx, nil)
   976  	s.Require().Error(err)
   977  
   978  	tokenID := collection.NewNFTID(s.nftClassID, 1)
   979  	testCases := map[string]struct {
   980  		contractID string
   981  		tokenID    string
   982  		valid      bool
   983  		count      uint64
   984  		postTest   func(res *collection.QueryChildrenResponse)
   985  	}{
   986  		"valid request": {
   987  			contractID: s.contractID,
   988  			tokenID:    tokenID,
   989  			valid:      true,
   990  			postTest: func(res *collection.QueryChildrenResponse) {
   991  				s.Require().Equal(1, len(res.Children))
   992  				s.Require().Equal(collection.NewNFTID(s.nftClassID, 2), res.Children[0].TokenId)
   993  			},
   994  		},
   995  		"valid request with limit": {
   996  			contractID: s.contractID,
   997  			tokenID:    tokenID,
   998  			valid:      true,
   999  			count:      1,
  1000  			postTest: func(res *collection.QueryChildrenResponse) {
  1001  				s.Require().Equal(1, len(res.Children))
  1002  				s.Require().Equal(collection.NewNFTID(s.nftClassID, 2), res.Children[0].TokenId)
  1003  			},
  1004  		},
  1005  		"collection not found": {
  1006  			contractID: "deadbeef",
  1007  			tokenID:    tokenID,
  1008  			valid:      true,
  1009  			postTest: func(res *collection.QueryChildrenResponse) {
  1010  				s.Require().Equal(0, len(res.Children))
  1011  			},
  1012  		},
  1013  		"token not found": {
  1014  			contractID: s.contractID,
  1015  			tokenID:    collection.NewNFTID("deadbeef", 1),
  1016  			valid:      true,
  1017  			postTest: func(res *collection.QueryChildrenResponse) {
  1018  				s.Require().Equal(0, len(res.Children))
  1019  			},
  1020  		},
  1021  		"invalid contract id": {
  1022  			tokenID: tokenID,
  1023  		},
  1024  		"invalid token id": {
  1025  			contractID: s.contractID,
  1026  		},
  1027  	}
  1028  
  1029  	for name, tc := range testCases {
  1030  		s.Run(name, func() {
  1031  			pageReq := &query.PageRequest{}
  1032  			if tc.count != 0 {
  1033  				pageReq.Limit = tc.count
  1034  			}
  1035  			req := &collection.QueryChildrenRequest{
  1036  				ContractId: tc.contractID,
  1037  				TokenId:    tc.tokenID,
  1038  				Pagination: pageReq,
  1039  			}
  1040  			res, err := s.queryServer.Children(s.goCtx, req)
  1041  			if !tc.valid {
  1042  				s.Require().Error(err)
  1043  				return
  1044  			}
  1045  			s.Require().NoError(err)
  1046  			s.Require().NotNil(res)
  1047  			tc.postTest(res)
  1048  		})
  1049  	}
  1050  }
  1051  
  1052  func (s *KeeperTestSuite) TestQueryGranteeGrants() {
  1053  	// empty request
  1054  	_, err := s.queryServer.GranteeGrants(s.goCtx, nil)
  1055  	s.Require().Error(err)
  1056  
  1057  	testCases := map[string]struct {
  1058  		contractID string
  1059  		grantee    sdk.AccAddress
  1060  		valid      bool
  1061  		postTest   func(res *collection.QueryGranteeGrantsResponse)
  1062  	}{
  1063  		"valid request": {
  1064  			contractID: s.contractID,
  1065  			grantee:    s.vendor,
  1066  			valid:      true,
  1067  			postTest: func(res *collection.QueryGranteeGrantsResponse) {
  1068  				s.Require().Equal(4, len(res.Grants))
  1069  			},
  1070  		},
  1071  		"collection not found": {
  1072  			contractID: "deadbeef",
  1073  			grantee:    s.vendor,
  1074  			valid:      true,
  1075  			postTest: func(res *collection.QueryGranteeGrantsResponse) {
  1076  				s.Require().Equal(0, len(res.Grants))
  1077  			},
  1078  		},
  1079  		"invalid contract id": {
  1080  			grantee: s.vendor,
  1081  		},
  1082  		"invalid grantee": {
  1083  			contractID: s.contractID,
  1084  		},
  1085  	}
  1086  
  1087  	for name, tc := range testCases {
  1088  		s.Run(name, func() {
  1089  			req := &collection.QueryGranteeGrantsRequest{
  1090  				ContractId: tc.contractID,
  1091  				Grantee:    tc.grantee.String(),
  1092  			}
  1093  			res, err := s.queryServer.GranteeGrants(s.goCtx, req)
  1094  			if !tc.valid {
  1095  				s.Require().Error(err)
  1096  				return
  1097  			}
  1098  			s.Require().NoError(err)
  1099  			s.Require().NotNil(res)
  1100  			tc.postTest(res)
  1101  		})
  1102  	}
  1103  }
  1104  
  1105  func (s *KeeperTestSuite) TestQueryIsOperatorFor() {
  1106  	// empty request
  1107  	_, err := s.queryServer.IsOperatorFor(s.goCtx, nil)
  1108  	s.Require().Error(err)
  1109  
  1110  	testCases := map[string]struct {
  1111  		contractID string
  1112  		operator   sdk.AccAddress
  1113  		holder     sdk.AccAddress
  1114  		valid      bool
  1115  		postTest   func(res *collection.QueryIsOperatorForResponse)
  1116  	}{
  1117  		"valid request": {
  1118  			contractID: s.contractID,
  1119  			operator:   s.operator,
  1120  			holder:     s.customer,
  1121  			valid:      true,
  1122  			postTest: func(res *collection.QueryIsOperatorForResponse) {
  1123  				s.Require().True(res.Authorized)
  1124  			},
  1125  		},
  1126  		"collection not found": {
  1127  			contractID: "deadbeef",
  1128  			operator:   s.operator,
  1129  			holder:     s.vendor,
  1130  			valid:      true,
  1131  			postTest: func(res *collection.QueryIsOperatorForResponse) {
  1132  				s.Require().False(res.Authorized)
  1133  			},
  1134  		},
  1135  		"invalid contract id": {
  1136  			operator: s.operator,
  1137  			holder:   s.customer,
  1138  		},
  1139  		"invalid operator": {
  1140  			contractID: s.contractID,
  1141  			holder:     s.customer,
  1142  		},
  1143  		"invalid holder": {
  1144  			contractID: s.contractID,
  1145  			operator:   s.operator,
  1146  		},
  1147  	}
  1148  
  1149  	for name, tc := range testCases {
  1150  		s.Run(name, func() {
  1151  			req := &collection.QueryIsOperatorForRequest{
  1152  				ContractId: tc.contractID,
  1153  				Operator:   tc.operator.String(),
  1154  				Holder:     tc.holder.String(),
  1155  			}
  1156  			res, err := s.queryServer.IsOperatorFor(s.goCtx, req)
  1157  			if !tc.valid {
  1158  				s.Require().Error(err)
  1159  				return
  1160  			}
  1161  			s.Require().NoError(err)
  1162  			s.Require().NotNil(res)
  1163  			tc.postTest(res)
  1164  		})
  1165  	}
  1166  }
  1167  
  1168  func (s *KeeperTestSuite) TestQueryHoldersByOperator() {
  1169  	// empty request
  1170  	_, err := s.queryServer.HoldersByOperator(s.goCtx, nil)
  1171  	s.Require().Error(err)
  1172  
  1173  	testCases := map[string]struct {
  1174  		contractID string
  1175  		operator   sdk.AccAddress
  1176  		valid      bool
  1177  		count      uint64
  1178  		postTest   func(res *collection.QueryHoldersByOperatorResponse)
  1179  	}{
  1180  		"valid request": {
  1181  			contractID: s.contractID,
  1182  			operator:   s.operator,
  1183  			valid:      true,
  1184  			postTest: func(res *collection.QueryHoldersByOperatorResponse) {
  1185  				s.Require().Equal(1, len(res.Holders))
  1186  			},
  1187  		},
  1188  		"valid request with limit": {
  1189  			contractID: s.contractID,
  1190  			operator:   s.operator,
  1191  			valid:      true,
  1192  			count:      1,
  1193  			postTest: func(res *collection.QueryHoldersByOperatorResponse) {
  1194  				s.Require().Equal(1, len(res.Holders))
  1195  			},
  1196  		},
  1197  		"collection not found": {
  1198  			contractID: "deadbeef",
  1199  			operator:   s.operator,
  1200  			valid:      true,
  1201  			postTest: func(res *collection.QueryHoldersByOperatorResponse) {
  1202  				s.Require().Equal(0, len(res.Holders))
  1203  			},
  1204  		},
  1205  		"invalid contract id": {
  1206  			operator: s.operator,
  1207  		},
  1208  		"invalid operator": {
  1209  			contractID: s.contractID,
  1210  		},
  1211  	}
  1212  
  1213  	for name, tc := range testCases {
  1214  		s.Run(name, func() {
  1215  			pageReq := &query.PageRequest{}
  1216  			if tc.count != 0 {
  1217  				pageReq.Limit = tc.count
  1218  			}
  1219  			req := &collection.QueryHoldersByOperatorRequest{
  1220  				ContractId: tc.contractID,
  1221  				Operator:   tc.operator.String(),
  1222  				Pagination: pageReq,
  1223  			}
  1224  			res, err := s.queryServer.HoldersByOperator(s.goCtx, req)
  1225  			if !tc.valid {
  1226  				s.Require().Error(err)
  1227  				return
  1228  			}
  1229  			s.Require().NoError(err)
  1230  			s.Require().NotNil(res)
  1231  			tc.postTest(res)
  1232  		})
  1233  	}
  1234  }