361 lines
7.7 KiB
Go
361 lines
7.7 KiB
Go
package keeper_test
|
|
|
|
import (
|
|
"fmt"
|
|
"math/rand"
|
|
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
"github.com/cosmos/cosmos-sdk/x/nft"
|
|
)
|
|
|
|
func (s *TestSuite) TestBatchMint() {
|
|
receiver := s.addrs[0]
|
|
testCases := []struct {
|
|
msg string
|
|
malleate func([]nft.NFT)
|
|
tokens []nft.NFT
|
|
expPass bool
|
|
}{
|
|
{
|
|
"success with empty nft",
|
|
func(tokens []nft.NFT) {
|
|
s.saveClass(tokens)
|
|
},
|
|
[]nft.NFT{},
|
|
true,
|
|
},
|
|
{
|
|
"success with single nft",
|
|
func(tokens []nft.NFT) {
|
|
s.saveClass(tokens)
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"success with multiple nft",
|
|
func(tokens []nft.NFT) {
|
|
s.saveClass(tokens)
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID2"},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"success with multiple class and multiple nft",
|
|
func(tokens []nft.NFT) {
|
|
s.saveClass(tokens)
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID2"},
|
|
{ClassId: "classID2", Id: "nftID1"},
|
|
{ClassId: "classID2", Id: "nftID2"},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"faild with repeated nft",
|
|
func(tokens []nft.NFT) {
|
|
s.saveClass(tokens)
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID2", Id: "nftID2"},
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"faild with not exist class",
|
|
func(tokens []nft.NFT) {
|
|
// do nothing
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID2", Id: "nftID2"},
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"faild with exist nft",
|
|
func(tokens []nft.NFT) {
|
|
s.saveClass(tokens)
|
|
idx := rand.Intn(len(tokens))
|
|
s.nftKeeper.Mint(s.ctx, tokens[idx], receiver)
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID2"},
|
|
{ClassId: "classID2", Id: "nftID2"},
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
s.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
|
s.SetupTest() // reset
|
|
tc.malleate(tc.tokens)
|
|
|
|
err := s.nftKeeper.BatchMint(s.ctx, tc.tokens, receiver)
|
|
if tc.expPass {
|
|
s.Require().NoError(err)
|
|
|
|
classMap := groupByClassID(tc.tokens)
|
|
for classID, tokens := range classMap {
|
|
for _, token := range tokens {
|
|
actNFT, has := s.nftKeeper.GetNFT(s.ctx, token.ClassId, token.Id)
|
|
s.Require().True(has)
|
|
s.Require().EqualValues(token, actNFT)
|
|
|
|
owner := s.nftKeeper.GetOwner(s.ctx, token.ClassId, token.Id)
|
|
s.Require().True(receiver.Equals(owner))
|
|
}
|
|
|
|
actNFTs := s.nftKeeper.GetNFTsOfClass(s.ctx, classID)
|
|
s.Require().EqualValues(tokens, actNFTs)
|
|
|
|
actNFTs = s.nftKeeper.GetNFTsOfClassByOwner(s.ctx, classID, receiver)
|
|
s.Require().EqualValues(tokens, actNFTs)
|
|
|
|
balance := s.nftKeeper.GetBalance(s.ctx, classID, receiver)
|
|
s.Require().EqualValues(len(tokens), balance)
|
|
|
|
supply := s.nftKeeper.GetTotalSupply(s.ctx, classID)
|
|
s.Require().EqualValues(len(tokens), supply)
|
|
}
|
|
return
|
|
}
|
|
s.Require().Error(err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *TestSuite) TestBatchBurn() {
|
|
receiver := s.addrs[0]
|
|
tokens := []nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID2"},
|
|
{ClassId: "classID2", Id: "nftID1"},
|
|
{ClassId: "classID2", Id: "nftID2"},
|
|
}
|
|
|
|
testCases := []struct {
|
|
msg string
|
|
malleate func()
|
|
classID string
|
|
nftIDs []string
|
|
expPass bool
|
|
}{
|
|
{
|
|
"success",
|
|
func() {
|
|
s.saveClass(tokens)
|
|
s.nftKeeper.BatchMint(s.ctx, tokens, receiver)
|
|
},
|
|
"classID1",
|
|
[]string{"nftID1", "nftID2"},
|
|
true,
|
|
},
|
|
{
|
|
"failed with not exist classID",
|
|
func() {},
|
|
"classID1",
|
|
[]string{"nftID1", "nftID2"},
|
|
false,
|
|
},
|
|
{
|
|
"failed with not exist nftID",
|
|
func() {
|
|
s.saveClass(tokens)
|
|
},
|
|
"classID1",
|
|
[]string{"nftID1", "nftID2"},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
s.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
|
s.SetupTest() // reset
|
|
tc.malleate()
|
|
|
|
err := s.nftKeeper.BatchBurn(s.ctx, tc.classID, tc.nftIDs)
|
|
if tc.expPass {
|
|
s.Require().NoError(err)
|
|
for _, nftID := range tc.nftIDs {
|
|
s.Require().False(s.nftKeeper.HasNFT(s.ctx, tc.classID, nftID))
|
|
}
|
|
return
|
|
}
|
|
s.Require().Error(err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *TestSuite) TestBatchUpdate() {
|
|
receiver := s.addrs[0]
|
|
tokens := []nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID2"},
|
|
{ClassId: "classID2", Id: "nftID1"},
|
|
{ClassId: "classID2", Id: "nftID2"},
|
|
}
|
|
testCases := []struct {
|
|
msg string
|
|
malleate func()
|
|
tokens []nft.NFT
|
|
expPass bool
|
|
}{
|
|
{
|
|
"success",
|
|
func() {
|
|
s.saveClass(tokens)
|
|
s.nftKeeper.BatchMint(s.ctx, tokens, receiver)
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1", Uri: "nftID1_URI"},
|
|
{ClassId: "classID2", Id: "nftID2", Uri: "nftID2_URI"},
|
|
},
|
|
true,
|
|
},
|
|
{
|
|
"failed with not exist classID",
|
|
func() {},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1", Uri: "nftID1_URI"},
|
|
{ClassId: "classID2", Id: "nftID2", Uri: "nftID2_URI"},
|
|
},
|
|
false,
|
|
},
|
|
{
|
|
"failed with not exist nftID",
|
|
func() {
|
|
s.saveClass(tokens)
|
|
},
|
|
[]nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1", Uri: "nftID1_URI"},
|
|
{ClassId: "classID2", Id: "nftID2", Uri: "nftID2_URI"},
|
|
},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
s.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
|
s.SetupTest() // reset
|
|
tc.malleate()
|
|
|
|
err := s.nftKeeper.BatchUpdate(s.ctx, tc.tokens)
|
|
if tc.expPass {
|
|
s.Require().NoError(err)
|
|
for _, token := range tc.tokens {
|
|
actToken, found := s.nftKeeper.GetNFT(s.ctx, token.ClassId, token.Id)
|
|
s.Require().True(found)
|
|
s.Require().EqualValues(token, actToken)
|
|
}
|
|
return
|
|
}
|
|
s.Require().Error(err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (s *TestSuite) TestBatchTransfer() {
|
|
owner := s.addrs[0]
|
|
receiver := s.addrs[1]
|
|
tokens := []nft.NFT{
|
|
{ClassId: "classID1", Id: "nftID1"},
|
|
{ClassId: "classID1", Id: "nftID2"},
|
|
{ClassId: "classID2", Id: "nftID1"},
|
|
{ClassId: "classID2", Id: "nftID2"},
|
|
}
|
|
testCases := []struct {
|
|
msg string
|
|
malleate func()
|
|
classID string
|
|
nftIDs []string
|
|
expPass bool
|
|
}{
|
|
{
|
|
"success",
|
|
func() {
|
|
s.saveClass(tokens)
|
|
s.nftKeeper.BatchMint(s.ctx, tokens, owner)
|
|
},
|
|
"classID1",
|
|
[]string{"nftID1", "nftID2"},
|
|
true,
|
|
},
|
|
{
|
|
"failed with not exist classID",
|
|
func() {
|
|
s.saveClass(tokens)
|
|
s.nftKeeper.BatchMint(s.ctx, tokens, receiver)
|
|
},
|
|
"classID3",
|
|
[]string{"nftID1", "nftID2"},
|
|
false,
|
|
},
|
|
{
|
|
"failed with not exist nftID",
|
|
func() {
|
|
s.saveClass(tokens)
|
|
},
|
|
"classID1",
|
|
[]string{"nftID1", "nftID2"},
|
|
false,
|
|
},
|
|
}
|
|
|
|
for _, tc := range testCases {
|
|
s.Run(fmt.Sprintf("Case %s", tc.msg), func() {
|
|
s.SetupTest() // reset
|
|
tc.malleate()
|
|
|
|
err := s.nftKeeper.BatchTransfer(s.ctx, tc.classID, tc.nftIDs, receiver)
|
|
if tc.expPass {
|
|
s.Require().NoError(err)
|
|
for _, nftID := range tc.nftIDs {
|
|
actOwner := s.nftKeeper.GetOwner(s.ctx, tc.classID, nftID)
|
|
s.Require().EqualValues(receiver, actOwner)
|
|
}
|
|
return
|
|
}
|
|
s.Require().Error(err)
|
|
})
|
|
}
|
|
}
|
|
|
|
func groupByClassID(tokens []nft.NFT) map[string][]nft.NFT {
|
|
classMap := make(map[string][]nft.NFT, len(tokens))
|
|
for _, token := range tokens {
|
|
if _, ok := classMap[token.ClassId]; !ok {
|
|
classMap[token.ClassId] = make([]nft.NFT, 0)
|
|
}
|
|
classMap[token.ClassId] = append(classMap[token.ClassId], token)
|
|
}
|
|
return classMap
|
|
}
|
|
|
|
func (s *TestSuite) saveClass(tokens []nft.NFT) {
|
|
classMap := groupByClassID(tokens)
|
|
for classID := range classMap {
|
|
err := s.nftKeeper.SaveClass(s.ctx, nft.Class{Id: classID})
|
|
s.Require().NoError(err)
|
|
}
|
|
}
|
|
|
|
func (s *TestSuite) mintNFT(tokens []nft.NFT, receiver sdk.AccAddress) {
|
|
for _, token := range tokens {
|
|
err := s.nftKeeper.Mint(s.ctx, token, receiver)
|
|
s.Require().NoError(err)
|
|
}
|
|
}
|