From 08a4586300d1cd5588dcf31ce56097c13e41c278 Mon Sep 17 00:00:00 2001 From: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> Date: Mon, 16 Oct 2023 14:30:18 +0900 Subject: [PATCH 1/2] test(collection): refactor overall unittests of `x/collection` (#1139) * modify MsgOperatorBurnFT * clarify events * remove deterministic flag, always test for non-deterministic * add CHANGELOG * chore: refactor * chore: encoding unittest --- CHANGELOG.md | 1 + testutil/encoding.go | 19 + testutil/encoding_test.go | 33 + x/collection/keeper/keeper_test.go | 42 +- x/collection/keeper/msg_server_test.go | 899 +++++++++++++++---------- 5 files changed, 616 insertions(+), 378 deletions(-) create mode 100644 testutil/encoding.go create mode 100644 testutil/encoding_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index ceb4002f8b..5d8bc7f573 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -58,6 +58,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/collection) [\#1131](https://github.com/Finschia/finschia-sdk/pull/1131) add additional unittest of x/collection(`MsgIssueFT`, `MsgMintFT`, `MsgBurnFT`) * (x/collection) [\#1133](https://github.com/Finschia/finschia-sdk/pull/1133) Refactor unittest for `SendFT`, `OperatorSendFT`, `AuthorizeOperator`, and `RevokeOperator` to check more states * (x/token) [\#1137](https://github.com/Finschia/finschia-sdk/pull/1137) Add test for event compatibility +* (x/collection) [\#1139](https://github.com/Finschia/finschia-sdk/pull/1139) refactor overall unittests of `x/collection` ### Bug Fixes * (ledger) [\#1040](https://github.com/Finschia/finschia-sdk/pull/1040) Fix a bug(unable to connect nano S plus ledger on ubuntu) diff --git a/testutil/encoding.go b/testutil/encoding.go new file mode 100644 index 0000000000..02b0e1e533 --- /dev/null +++ b/testutil/encoding.go @@ -0,0 +1,19 @@ +package testutil + +import ( + "encoding/json" + "fmt" +) + +func MustJSONMarshal(v any) []byte { + b, err := json.Marshal(v) + if err != nil { + panic(err) + } + + return b +} + +func W(input string) []byte { + return []byte(fmt.Sprintf("\"%s\"", input)) +} diff --git a/testutil/encoding_test.go b/testutil/encoding_test.go new file mode 100644 index 0000000000..d07ef1b6b4 --- /dev/null +++ b/testutil/encoding_test.go @@ -0,0 +1,33 @@ +package testutil_test + +import ( + "encoding/json" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/Finschia/finschia-sdk/testutil" +) + +func TestMustJSONMarshal(t *testing.T) { + type tc struct { + Name string `json:"myName"` + Order string `json:"myOrder"` + } + + a := tc{ + Name: "test", + Order: "first", + } + b := new(tc) + + marshaled := testutil.MustJSONMarshal(a) + err := json.Unmarshal(marshaled, b) + require.NoError(t, err) + require.Equal(t, a, *b) + require.Panics(t, func() { testutil.MustJSONMarshal(make(chan int)) }) +} + +func TestW(t *testing.T) { + require.Equal(t, []byte(`"test"`), testutil.W("test")) +} diff --git a/x/collection/keeper/keeper_test.go b/x/collection/keeper/keeper_test.go index e7a42c92ed..65b1305e82 100644 --- a/x/collection/keeper/keeper_test.go +++ b/x/collection/keeper/keeper_test.go @@ -2,7 +2,6 @@ package keeper_test import ( "context" - "fmt" "testing" "github.com/stretchr/testify/suite" @@ -18,8 +17,6 @@ import ( type KeeperTestSuite struct { suite.Suite - deterministic bool - ctx sdk.Context goCtx context.Context keeper keeper.Keeper @@ -44,29 +41,21 @@ type KeeperTestSuite struct { } func (s *KeeperTestSuite) createRandomAccounts(accNum int) []sdk.AccAddress { - if s.deterministic { - addresses := make([]sdk.AccAddress, accNum) - for i := range addresses { - addresses[i] = sdk.AccAddress(fmt.Sprintf("address%d", i)) - } - return addresses - } else { - seenAddresses := make(map[string]bool, accNum) - addresses := make([]sdk.AccAddress, accNum) - for i := range addresses { - var address sdk.AccAddress - for { - pk := secp256k1.GenPrivKey().PubKey() - address = sdk.AccAddress(pk.Address()) - if !seenAddresses[address.String()] { - seenAddresses[address.String()] = true - break - } + seenAddresses := make(map[string]bool, accNum) + addresses := make([]sdk.AccAddress, accNum) + for i := range addresses { + var address sdk.AccAddress + for { + pk := secp256k1.GenPrivKey().PubKey() + address = sdk.AccAddress(pk.Address()) + if !seenAddresses[address.String()] { + seenAddresses[address.String()] = true + break } - addresses[i] = address } - return addresses + addresses[i] = address } + return addresses } func (s *KeeperTestSuite) SetupTest() { @@ -188,10 +177,5 @@ func (s *KeeperTestSuite) SetupTest() { } func TestKeeperTestSuite(t *testing.T) { - for _, deterministic := range []bool{ - false, - true, - } { - suite.Run(t, &KeeperTestSuite{deterministic: deterministic}) - } + suite.Run(t, new(KeeperTestSuite)) } diff --git a/x/collection/keeper/msg_server_test.go b/x/collection/keeper/msg_server_test.go index 7be0619d07..e1ce0c2b61 100644 --- a/x/collection/keeper/msg_server_test.go +++ b/x/collection/keeper/msg_server_test.go @@ -1,15 +1,11 @@ package keeper_test import ( - "encoding/json" - "fmt" - "strings" - "testing" - - "github.com/stretchr/testify/assert" abci "github.com/tendermint/tendermint/abci/types" + "github.com/Finschia/finschia-sdk/testutil" sdk "github.com/Finschia/finschia-sdk/types" + "github.com/Finschia/finschia-sdk/types/query" "github.com/Finschia/finschia-sdk/x/collection" "github.com/Finschia/finschia-sdk/x/token/class" ) @@ -31,8 +27,16 @@ func (s *KeeperTestSuite) TestMsgSendFT() { }, ftID: collection.NewFTID(s.ftClassID), expectedEvents: sdk.Events{ - helperBuildEventSent(s.contractID, s.vendor, s.customer, s.vendor, collection.NewCoins(collection.NewFTCoin(s.ftClassID, s.balance))), - }, + sdk.Event{ + Type: "lbm.collection.v1.EventSent", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(collection.NewCoins(collection.NewFTCoin(s.ftClassID, s.balance))), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer.String()), Index: false}, + }, + }}, }, "contract not found": { isNegativeCase: true, @@ -108,7 +112,16 @@ func (s *KeeperTestSuite) TestMsgOperatorSendFT() { }, ftID: collection.NewFTID(s.ftClassID), expectedEvents: sdk.Events{ - helperBuildEventSent(s.contractID, s.customer, s.vendor, s.operator, collection.NewCoins(collection.NewFTCoin(s.ftClassID, s.balance))), + sdk.Event{ + Type: "lbm.collection.v1.EventSent", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(collection.NewCoins(collection.NewFTCoin(s.ftClassID, s.balance))), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + }, + }, }, }, "contract not found": { @@ -183,59 +196,10 @@ func (s *KeeperTestSuite) TestMsgOperatorSendFT() { } } -func helperBuildEventSent(contractID string, from, to, operator sdk.AccAddress, amount collection.Coins) sdk.Event { - return sdk.Event{ - Type: "lbm.collection.v1.EventSent", - Attributes: []abci.EventAttribute{ - {Key: []byte("amount"), Value: []byte(asJsonStr(amount)), Index: false}, - {Key: []byte("contract_id"), Value: []byte(wrapQuot(contractID)), Index: false}, - {Key: []byte("from"), Value: []byte(wrapQuot(from.String())), Index: false}, - {Key: []byte("operator"), Value: []byte(wrapQuot(operator.String())), Index: false}, - {Key: []byte("to"), Value: []byte(wrapQuot(to.String())), Index: false}, - }, - } -} - -func TestHelperBuildEventSent(t *testing.T) { - testCases := map[string]struct { - expectedEvent sdk.Event - contractID string - from string - to string - operator string - amount collection.Coins - }{ - "helper function should keep event compatibility": { - expectedEvent: sdk.Event{Type: "lbm.collection.v1.EventSent", Attributes: []abci.EventAttribute{ - {Key: []byte("amount"), Value: []byte(`[{"token_id":"0000000100000000","amount":"1000000"}]`), Index: false}, - {Key: []byte("contract_id"), Value: []byte(`"9be17165"`), Index: false}, - {Key: []byte("from"), Value: []byte(`"link1v9jxgun9wdenqa2xzfx"`), Index: false}, - {Key: []byte("operator"), Value: []byte(`"link1v9jxgun9wdenqa2xzfx"`), Index: false}, - {Key: []byte("to"), Value: []byte(`"link1v9jxgun9wdenyjqyyxu"`), Index: false}, - }}, - contractID: "9be17165", - from: "link1v9jxgun9wdenqa2xzfx", - to: "link1v9jxgun9wdenyjqyyxu", - operator: "link1v9jxgun9wdenqa2xzfx", - amount: collection.NewCoins(collection.NewFTCoin("00000001", sdk.NewInt(1000000))), - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - // Act - from, err := sdk.AccAddressFromBech32(tc.from) - assert.NoError(t, err) - to, err := sdk.AccAddressFromBech32(tc.to) - assert.NoError(t, err) - event := helperBuildEventSent(tc.contractID, from, to, from, tc.amount) - - // Assert - assert.Equal(t, tc.expectedEvent, event) - }) - } -} - func (s *KeeperTestSuite) TestMsgSendNFT() { + rootNFTID := collection.NewNFTID(s.nftClassID, 1) + issuedTokenIDs := s.extractChainedNFTIDs(rootNFTID) + testCases := map[string]struct { contractID string tokenID string @@ -244,8 +208,46 @@ func (s *KeeperTestSuite) TestMsgSendNFT() { }{ "valid request": { contractID: s.contractID, - tokenID: collection.NewNFTID(s.nftClassID, 1), - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventOwnerChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventOwnerChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventOwnerChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventSent", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74}, Value: []uint8{0x5b, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x5d}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}}}}, + tokenID: rootNFTID, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventOwnerChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedTokenIDs[1]), Index: false}, + }, + }, + sdk.Event{ + Type: "lbm.collection.v1.EventOwnerChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedTokenIDs[2]), Index: false}, + }, + }, + sdk.Event{ + Type: "lbm.collection.v1.EventOwnerChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedTokenIDs[3]), Index: false}, + }, + }, + sdk.Event{ + Type: "lbm.collection.v1.EventSent", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(collection.NewCoins(collection.Coin{TokenId: issuedTokenIDs[0], Amount: sdk.OneInt()})), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + }, + }, + }, }, "contract not found": { contractID: "deadbeef", @@ -286,16 +288,15 @@ func (s *KeeperTestSuite) TestMsgSendNFT() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgOperatorSendNFT() { - tokenID := collection.NewNFTID(s.nftClassID, 1) + rootNFTID := collection.NewNFTID(s.nftClassID, 1) + issuedTokenIDs := s.extractChainedNFTIDs(rootNFTID) + testCases := map[string]struct { contractID string operator sdk.AccAddress @@ -308,21 +309,58 @@ func (s *KeeperTestSuite) TestMsgOperatorSendNFT() { contractID: s.contractID, operator: s.operator, from: s.customer, - tokenID: tokenID, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventOwnerChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventOwnerChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventOwnerChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventSent", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74}, Value: []uint8{0x5b, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x5d}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}}}}, - }, + tokenID: rootNFTID, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventOwnerChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedTokenIDs[1]), Index: false}, + }, + }, + sdk.Event{ + Type: "lbm.collection.v1.EventOwnerChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedTokenIDs[2]), Index: false}, + }, + }, + sdk.Event{ + Type: "lbm.collection.v1.EventOwnerChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedTokenIDs[3]), Index: false}, + }, + }, + sdk.Event{ + Type: "lbm.collection.v1.EventSent", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(collection.NewCoins(collection.Coin{TokenId: issuedTokenIDs[0], Amount: sdk.OneInt()})), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor.String()), Index: false}, + }, + }, + }}, "contract not found": { contractID: "deadbeef", operator: s.operator, from: s.customer, - tokenID: tokenID, + tokenID: rootNFTID, err: class.ErrContractNotExist, }, "not approved": { contractID: s.contractID, operator: s.vendor, from: s.customer, - tokenID: tokenID, + tokenID: rootNFTID, err: collection.ErrCollectionNotApproved, }, "not found": { @@ -366,20 +404,16 @@ func (s *KeeperTestSuite) TestMsgOperatorSendNFT() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgAuthorizeOperator() { - const authorizedOperatorEventType = "lbm.collection.v1.EventAuthorizedOperator" testCases := map[string]struct { isNegativeCase bool req *collection.MsgAuthorizeOperator - expectedEvents sdk.Events + events sdk.Events expectedError error }{ "valid request": { @@ -388,9 +422,14 @@ func (s *KeeperTestSuite) TestMsgAuthorizeOperator() { Holder: s.customer.String(), Operator: s.vendor.String(), }, - expectedEvents: sdk.Events{ - helperBuildEventAuthRelated(authorizedOperatorEventType, s.contractID, s.customer, s.vendor), - }, + events: sdk.Events{sdk.Event{ + Type: "lbm.collection.v1.EventAuthorizedOperator", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + }, + }}, }, "contract not found": { isNegativeCase: true, @@ -431,10 +470,7 @@ func (s *KeeperTestSuite) TestMsgAuthorizeOperator() { } s.Require().NoError(err) s.Require().NotNil(res) - - // Assert - events := ctx.EventManager().Events() - s.Require().Equal(tc.expectedEvents, events) + s.Require().Equal(tc.events, ctx.EventManager().Events()) curAuth, err := s.keeper.GetAuthorization(ctx, tc.req.ContractId, holder, operator) s.Require().NoError(err) s.Require().Nil(prevAuth) @@ -445,11 +481,10 @@ func (s *KeeperTestSuite) TestMsgAuthorizeOperator() { } func (s *KeeperTestSuite) TestMsgRevokeOperator() { - const revokedOperatorEventType = "lbm.collection.v1.EventRevokedOperator" testCases := map[string]struct { isNegativeCase bool req *collection.MsgRevokeOperator - expectedEvents sdk.Events + events sdk.Events expectedError error }{ "valid request": { @@ -458,9 +493,14 @@ func (s *KeeperTestSuite) TestMsgRevokeOperator() { Holder: s.customer.String(), Operator: s.operator.String(), }, - expectedEvents: sdk.Events{ - helperBuildEventAuthRelated(revokedOperatorEventType, s.contractID, s.customer, s.operator), - }, + events: sdk.Events{sdk.Event{ + Type: "lbm.collection.v1.EventRevokedOperator", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator.String()), Index: false}, + }, + }}, }, "contract not found": { isNegativeCase: true, @@ -502,9 +542,7 @@ func (s *KeeperTestSuite) TestMsgRevokeOperator() { s.Require().NoError(err) s.Require().NotNil(res) - // Assert - events := ctx.EventManager().Events() - s.Require().Equal(tc.expectedEvents, events) + s.Require().Equal(tc.events, ctx.EventManager().Events()) s.Require().NotNil(prevAuth) s.Require().Equal(tc.req.Holder, prevAuth.Holder) s.Require().Equal(tc.req.Operator, prevAuth.Operator) @@ -515,70 +553,59 @@ func (s *KeeperTestSuite) TestMsgRevokeOperator() { } } -func helperBuildEventAuthRelated(evtType, contractID string, holder, operator sdk.AccAddress) sdk.Event { - return sdk.Event{ - Type: evtType, - Attributes: []abci.EventAttribute{ - {Key: []byte("contract_id"), Value: []byte(wrapQuot(contractID)), Index: false}, - {Key: []byte("holder"), Value: []byte(wrapQuot(holder.String())), Index: false}, - {Key: []byte("operator"), Value: []byte(wrapQuot(operator.String())), Index: false}, - }, - } -} - -func TestHelperBuildAuthRelatedEvent(t *testing.T) { - testCases := map[string]struct { - expectedEvent sdk.Event - contractID string - holder string - operator string - }{ - "helper function should keep event compatibility for approve": { - expectedEvent: sdk.Event{Type: "lbm.collection.v1.EventSent", Attributes: []abci.EventAttribute{ - {Key: []byte("contract_id"), Value: []byte(`"9be17165"`), Index: false}, - {Key: []byte("holder"), Value: []byte(`"link1v9jxgun9wdenyjqyyxu"`), Index: false}, - {Key: []byte("operator"), Value: []byte(`"link1v9jxgun9wdenqa2xzfx"`), Index: false}, - }}, - contractID: "9be17165", - holder: "link1v9jxgun9wdenyjqyyxu", - operator: "link1v9jxgun9wdenqa2xzfx", - }, - "helper function should keep event compatibility for revoke": { - expectedEvent: sdk.Event{Type: "lbm.collection.v1.EventSent", Attributes: []abci.EventAttribute{ - {Key: []byte("contract_id"), Value: []byte(`"9be17165"`), Index: false}, - {Key: []byte("holder"), Value: []byte(`"link1v9jxgun9wdenyjqyyxu"`), Index: false}, - {Key: []byte("operator"), Value: []byte(`"link1v9jxgun9wdenzw08p6t"`), Index: false}, - }}, - contractID: "9be17165", - holder: "link1v9jxgun9wdenyjqyyxu", - operator: "link1v9jxgun9wdenzw08p6t", - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - // Act - holder, err := sdk.AccAddressFromBech32(tc.holder) - assert.NoError(t, err) - operator, err := sdk.AccAddressFromBech32(tc.operator) - assert.NoError(t, err) - event := helperBuildEventAuthRelated(tc.expectedEvent.Type, tc.contractID, holder, operator) - - // Assert - assert.Equal(t, tc.expectedEvent, event) - }) - } -} - func (s *KeeperTestSuite) TestMsgCreateContract() { + expectedNewContractID := "3336b76f" testCases := map[string]struct { owner sdk.AccAddress err error events sdk.Events }{ "valid request": { - owner: s.vendor, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventCreatedContract", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x33, 0x33, 0x33, 0x36, 0x62, 0x37, 0x36, 0x66, 0x22}, Index: false}, {Key: []uint8{0x63, 0x72, 0x65, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x6d, 0x65, 0x74, 0x61}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x6e, 0x61, 0x6d, 0x65}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x75, 0x72, 0x69}, Value: []uint8{0x22, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventGranted", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x33, 0x33, 0x33, 0x36, 0x62, 0x37, 0x36, 0x66, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x49, 0x53, 0x53, 0x55, 0x45, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventGranted", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x33, 0x33, 0x33, 0x36, 0x62, 0x37, 0x36, 0x66, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x59, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventGranted", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x33, 0x33, 0x33, 0x36, 0x62, 0x37, 0x36, 0x66, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x54, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventGranted", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x33, 0x33, 0x33, 0x36, 0x62, 0x37, 0x36, 0x66, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x52, 0x4e, 0x22}, Index: false}}}}, - }, + owner: s.vendor, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventCreatedContract", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(expectedNewContractID), Index: false}, + {Key: []byte("creator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("meta"), Value: testutil.W(""), Index: false}, + {Key: []byte("name"), Value: testutil.W(""), Index: false}, + {Key: []byte("uri"), Value: testutil.W(""), Index: false}, + }, + }, + sdk.Event{ + Type: "lbm.collection.v1.EventGranted", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(expectedNewContractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("granter"), Value: testutil.W(""), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionIssue).String()), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventGranted", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(expectedNewContractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("granter"), Value: testutil.W(""), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionModify).String()), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventGranted", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(expectedNewContractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("granter"), Value: testutil.W(""), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionMint).String()), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventGranted", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(expectedNewContractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("granter"), Value: testutil.W(""), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionBurn).String()), Index: false}, + }}, + }}, } for name, tc := range testCases { @@ -589,21 +616,23 @@ func (s *KeeperTestSuite) TestMsgCreateContract() { Owner: tc.owner.String(), } res, err := s.msgServer.CreateContract(sdk.WrapSDKContext(ctx), req) + s.Require().Equal(expectedNewContractID, res.ContractId) s.Require().ErrorIs(err, tc.err) if tc.err != nil { return } s.Require().NotNil(res) + s.Require().Equal(tc.events, ctx.EventManager().Events()) - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } }) } } func (s *KeeperTestSuite) TestMsgIssueFT() { + expectedClassID := "00000002" + expectedTokenID := collection.NewFTID(expectedClassID) + testCases := map[string]struct { contractID string owner sdk.AccAddress @@ -619,13 +648,13 @@ func (s *KeeperTestSuite) TestMsgIssueFT() { sdk.Event{ Type: "lbm.collection.v1.EventCreatedFTClass", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("decimals"), Value: []uint8("0"), Index: false}, - {Key: []uint8("meta"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("mintable"), Value: []uint8("false"), Index: false}, - {Key: []uint8("name"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("token_id"), Value: []uint8("\"0000000200000000\""), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("decimals"), Value: []byte("0"), Index: false}, + {Key: []byte("meta"), Value: testutil.W(""), Index: false}, + {Key: []byte("mintable"), Value: []byte("false"), Index: false}, + {Key: []byte("name"), Value: testutil.W(""), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(expectedTokenID), Index: false}, }, }, }, @@ -638,22 +667,22 @@ func (s *KeeperTestSuite) TestMsgIssueFT() { sdk.Event{ Type: "lbm.collection.v1.EventCreatedFTClass", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("decimals"), Value: []uint8("0"), Index: false}, - {Key: []uint8("meta"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("mintable"), Value: []uint8("false"), Index: false}, - {Key: []uint8("name"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("token_id"), Value: []uint8("\"0000000200000000\""), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("decimals"), Value: []byte("0"), Index: false}, + {Key: []byte("meta"), Value: testutil.W(""), Index: false}, + {Key: []byte("mintable"), Value: []byte("false"), Index: false}, + {Key: []byte("name"), Value: testutil.W(""), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(expectedTokenID), Index: false}, }, }, sdk.Event{ Type: "lbm.collection.v1.EventMintedFT", Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("[{\"token_id\":\"0000000200000000\",\"amount\":\"1\"}]"), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("to"), Value: []uint8(fmt.Sprintf("\"%s\"", s.customer)), Index: false}, + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(collection.NewCoins(collection.Coin{TokenId: expectedTokenID, Amount: sdk.OneInt()})), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer.String()), Index: false}, }, }, }, @@ -709,6 +738,8 @@ func (s *KeeperTestSuite) TestMsgIssueFT() { } func (s *KeeperTestSuite) TestMsgIssueNFT() { + expectedTokenType := "10000002" + testCases := map[string]struct { contractID string owner sdk.AccAddress @@ -718,7 +749,33 @@ func (s *KeeperTestSuite) TestMsgIssueNFT() { "valid request": { contractID: s.contractID, owner: s.vendor, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventCreatedNFTClass", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x6d, 0x65, 0x74, 0x61}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x6e, 0x61, 0x6d, 0x65}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x74, 0x79, 0x70, 0x65}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventGranted", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x54, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventGranted", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72}, Value: []uint8{0x22, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x42, 0x55, 0x52, 0x4e, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventCreatedNFTClass", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("meta"), Value: testutil.W(""), Index: false}, + {Key: []byte("name"), Value: testutil.W(""), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("token_type"), Value: testutil.W(expectedTokenType), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventGranted", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("granter"), Value: testutil.W(""), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionMint).String()), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventGranted", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("granter"), Value: testutil.W(""), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionBurn).String()), Index: false}, + }}, + }, }, "contract not found": { contractID: "deadbeef", @@ -747,10 +804,8 @@ func (s *KeeperTestSuite) TestMsgIssueNFT() { } s.Require().NotNil(res) + s.Require().Equal(tc.events, ctx.EventManager().Events()) - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } }) } } @@ -774,6 +829,10 @@ func (s *KeeperTestSuite) TestMsgMintFT() { amount := collection.NewCoins( collection.NewFTCoin(s.ftClassID, sdk.NewInt(100000)), ) + amounts := collection.NewCoins( + collection.NewFTCoin(s.ftClassID, sdk.NewInt(100000)), + collection.NewFTCoin(*mintableFTClassID, sdk.NewInt(200000)), + ) testCases := map[string]struct { contractID string @@ -782,7 +841,7 @@ func (s *KeeperTestSuite) TestMsgMintFT() { err error events sdk.Events }{ - "valid request": { + "valid request - single token": { contractID: s.contractID, from: s.vendor, amount: amount, @@ -790,10 +849,41 @@ func (s *KeeperTestSuite) TestMsgMintFT() { sdk.Event{ Type: "lbm.collection.v1.EventMintedFT", Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("[{\"token_id\":\"0000000100000000\",\"amount\":\"100000\"}]"), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("to"), Value: []uint8(fmt.Sprintf("\"%s\"", s.customer)), Index: false}, + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(amount), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer.String()), Index: false}, + }, + }, + }, + }, + "valid request - multi tokens": { + contractID: s.contractID, + from: s.vendor, + amount: amounts, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventMintedFT", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(amounts), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer.String()), Index: false}, + }, + }, + }, + }, + "valid request - empty amount": { + contractID: s.contractID, + from: s.vendor, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventMintedFT", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: []byte("[]"), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer.String()), Index: false}, }, }, }, @@ -818,21 +908,6 @@ func (s *KeeperTestSuite) TestMsgMintFT() { ), err: collection.ErrTokenNotExist, }, - "valid request - empty amount": { - contractID: s.contractID, - from: s.vendor, - events: sdk.Events{ - sdk.Event{ - Type: "lbm.collection.v1.EventMintedFT", - Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("[]"), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("to"), Value: []uint8(fmt.Sprintf("\"%s\"", s.customer)), Index: false}, - }, - }, - }, - }, "include invalid tokenId among 2 tokens": { contractID: s.contractID, from: s.vendor, @@ -857,25 +932,6 @@ func (s *KeeperTestSuite) TestMsgMintFT() { ), err: collection.ErrTokenNotMintable, }, - "valid request - multi tokens": { - contractID: s.contractID, - from: s.vendor, - amount: collection.NewCoins( - collection.NewFTCoin(s.ftClassID, sdk.NewInt(100000)), - collection.NewFTCoin(*mintableFTClassID, sdk.NewInt(200000)), - ), - events: sdk.Events{ - sdk.Event{ - Type: "lbm.collection.v1.EventMintedFT", - Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("[{\"token_id\":\"0000000100000000\",\"amount\":\"100000\"},{\"token_id\":\"0000000200000000\",\"amount\":\"200000\"}]"), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("to"), Value: []uint8(fmt.Sprintf("\"%s\"", s.customer)), Index: false}, - }, - }, - }, - }, } // query the values to be effected by MintFT @@ -956,7 +1012,17 @@ func (s *KeeperTestSuite) TestMsgMintFT() { func (s *KeeperTestSuite) TestMsgMintNFT() { params := []collection.MintNFTParam{{ TokenType: s.nftClassID, + Name: "tester", + Meta: "Mint NFT", }} + expectedTokens := []collection.NFT{ + { + TokenId: "1000000100000016", + Name: params[0].Name, + Meta: params[0].Meta, + }, + } + testCases := map[string]struct { contractID string from sdk.AccAddress @@ -968,8 +1034,17 @@ func (s *KeeperTestSuite) TestMsgMintNFT() { contractID: s.contractID, from: s.vendor, params: params, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventMintedNFT", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x73}, Value: []uint8{0x5b, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x36, 0x22, 0x2c, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x3a, 0x22, 0x22, 0x2c, 0x22, 0x6d, 0x65, 0x74, 0x61, 0x22, 0x3a, 0x22, 0x22, 0x7d, 0x5d}, Index: false}}}}, - }, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventMintedNFT", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("tokens"), Value: testutil.MustJSONMarshal(expectedTokens), Index: false}, + }, + }, + }}, "contract not found": { contractID: "deadbeef", from: s.vendor, @@ -1009,18 +1084,15 @@ func (s *KeeperTestSuite) TestMsgMintNFT() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgBurnFT() { // prepare mutli token burn test - amount := collection.NewCoins( - collection.NewFTCoin(s.ftClassID, s.balance), + singleAmount := collection.NewCoins( + collection.NewFTCoin(s.ftClassID, sdk.NewInt(50000)), ) // create a fungible token class @@ -1029,6 +1101,11 @@ func (s *KeeperTestSuite) TestMsgBurnFT() { Mintable: true, }) s.Require().NoError(err) + multiAmounts := collection.NewCoins( + collection.NewFTCoin(s.ftClassID, sdk.NewInt(50000)), + collection.NewFTCoin(*mintableFTClassID, sdk.NewInt(60000)), + ) + // mintft mintedCoin := collection.NewFTCoin(*mintableFTClassID, sdk.NewInt(1000000)) err = s.keeper.MintFT(s.ctx, s.contractID, s.vendor, []collection.Coin{mintedCoin}) @@ -1044,75 +1121,72 @@ func (s *KeeperTestSuite) TestMsgBurnFT() { "valid request": { contractID: s.contractID, from: s.vendor, - amount: collection.NewCoins( - collection.NewFTCoin(s.ftClassID, sdk.NewInt(50000)), - ), + amount: singleAmount, events: sdk.Events{ sdk.Event{ Type: "lbm.collection.v1.EventBurned", Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("[{\"token_id\":\"0000000100000000\",\"amount\":\"50000\"}]"), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("from"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(collection.NewCoins( + collection.NewFTCoin(s.ftClassID, sdk.NewInt(50000)), + )), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, }, }, }, }, - "contract not found": { - contractID: "deadbeef", - from: s.vendor, - amount: amount, - err: class.ErrContractNotExist, - }, - "no permission": { - contractID: s.contractID, - from: s.customer, - amount: amount, - err: collection.ErrTokenNoPermission, - }, - "insufficient funds": { - contractID: s.contractID, - from: s.vendor, - amount: collection.NewCoins( - collection.NewFTCoin("00bab10c", sdk.OneInt()), - ), - err: collection.ErrInsufficientToken, - }, - "no amount - valid": { + "valid multi amount burn": { contractID: s.contractID, from: s.vendor, + amount: multiAmounts, events: sdk.Events{ sdk.Event{ Type: "lbm.collection.v1.EventBurned", Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("[]"), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("from"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(multiAmounts), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, }, }, }, }, - "valid multi amount burn": { + "no amount - valid": { contractID: s.contractID, from: s.vendor, - amount: collection.NewCoins( - collection.NewFTCoin(s.ftClassID, sdk.NewInt(50000)), - collection.NewFTCoin(*mintableFTClassID, sdk.NewInt(60000)), - ), events: sdk.Events{ sdk.Event{ Type: "lbm.collection.v1.EventBurned", Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("[{\"token_id\":\"0000000100000000\",\"amount\":\"50000\"},{\"token_id\":\"0000000200000000\",\"amount\":\"60000\"}]"), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("from"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, + {Key: []byte("amount"), Value: []byte("[]"), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, }, }, }, }, + "contract not found": { + contractID: "deadbeef", + from: s.vendor, + amount: singleAmount, + err: class.ErrContractNotExist, + }, + "no permission": { + contractID: s.contractID, + from: s.customer, + amount: singleAmount, + err: collection.ErrTokenNoPermission, + }, + "insufficient funds": { + contractID: s.contractID, + from: s.vendor, + amount: collection.NewCoins( + collection.NewFTCoin("00bab10c", sdk.OneInt()), + ), + err: collection.ErrInsufficientToken, + }, "include insufficient funds amount 2 amounts": { contractID: s.contractID, from: s.vendor, @@ -1196,9 +1270,10 @@ func (s *KeeperTestSuite) TestMsgBurnFT() { } func (s *KeeperTestSuite) TestMsgOperatorBurnFT() { - amount := collection.NewCoins( + singleAmount := collection.NewCoins( collection.NewFTCoin(s.ftClassID, s.balance), ) + testCases := map[string]struct { contractID string operator sdk.AccAddress @@ -1211,31 +1286,48 @@ func (s *KeeperTestSuite) TestMsgOperatorBurnFT() { contractID: s.contractID, operator: s.operator, from: s.customer, - amount: amount, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventBurned", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74}, Value: []uint8{0x5b, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x22, 0x7d, 0x5d}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}}}}, + amount: singleAmount, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventBurned", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(singleAmount), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator.String()), Index: false}, + }}}, }, "contract not found": { contractID: "deadbeef", operator: s.operator, from: s.customer, - amount: amount, + amount: singleAmount, err: class.ErrContractNotExist, }, "no authorization": { contractID: s.contractID, operator: s.vendor, from: s.customer, - amount: amount, + amount: singleAmount, err: collection.ErrCollectionNotApproved, }, "no permission": { contractID: s.contractID, operator: s.stranger, from: s.customer, - amount: amount, + amount: singleAmount, err: collection.ErrTokenNoPermission, }, - "insufficient funds": { + "insufficient funds - exist token": { + contractID: s.contractID, + operator: s.operator, + from: s.customer, + amount: collection.NewCoins( + collection.NewFTCoin(s.ftClassID, s.balance.Add(sdk.OneInt())), + ), + err: collection.ErrInsufficientToken, + }, + "insufficient funds - non-exist token": { contractID: s.contractID, operator: s.operator, from: s.customer, @@ -1263,18 +1355,19 @@ func (s *KeeperTestSuite) TestMsgOperatorBurnFT() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgBurnNFT() { - tokenIDs := []string{ - collection.NewNFTID(s.nftClassID, s.numNFTs*2+1), + rootNFTID := collection.NewNFTID(s.nftClassID, s.numNFTs*2+1) + issuedTokenIDs := s.extractChainedNFTIDs(rootNFTID) + coins := make([]collection.Coin, 0) + for _, id := range issuedTokenIDs { + coins = append(coins, collection.NewCoin(id, sdk.NewInt(1))) } + testCases := map[string]struct { contractID string from sdk.AccAddress @@ -1285,19 +1378,27 @@ func (s *KeeperTestSuite) TestMsgBurnNFT() { "valid request": { contractID: s.contractID, from: s.vendor, - tokenIDs: tokenIDs, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventBurned", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74}, Value: []uint8{0x5b, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x66, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x31, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x32, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x5d}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}}}}, + tokenIDs: []string{rootNFTID}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventBurned", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(coins), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + }}}, }, "contract not found": { contractID: "deadbeef", from: s.vendor, - tokenIDs: tokenIDs, + tokenIDs: []string{rootNFTID}, err: class.ErrContractNotExist, }, "no permission": { contractID: s.contractID, from: s.customer, - tokenIDs: tokenIDs, + tokenIDs: []string{rootNFTID}, err: collection.ErrTokenNoPermission, }, "not found": { @@ -1342,18 +1443,19 @@ func (s *KeeperTestSuite) TestMsgBurnNFT() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgOperatorBurnNFT() { - tokenIDs := []string{ - collection.NewNFTID(s.nftClassID, 1), + rootNFTID := collection.NewNFTID(s.nftClassID, 1) + issuedTokenIDs := s.extractChainedNFTIDs(rootNFTID) + coins := make([]collection.Coin, 0) + for _, id := range issuedTokenIDs { + coins = append(coins, collection.NewCoin(id, sdk.NewInt(1))) } + testCases := map[string]struct { contractID string operator sdk.AccAddress @@ -1366,28 +1468,36 @@ func (s *KeeperTestSuite) TestMsgOperatorBurnNFT() { contractID: s.contractID, operator: s.operator, from: s.customer, - tokenIDs: tokenIDs, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventBurned", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74}, Value: []uint8{0x5b, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x2c, 0x7b, 0x22, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x22, 0x3a, 0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x22, 0x2c, 0x22, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x22, 0x31, 0x22, 0x7d, 0x5d}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}}}}, + tokenIDs: []string{rootNFTID}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventBurned", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.MustJSONMarshal(coins), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator.String()), Index: false}, + }}}, }, "contract not found": { contractID: "deadbeef", operator: s.operator, from: s.customer, - tokenIDs: tokenIDs, + tokenIDs: []string{rootNFTID}, err: class.ErrContractNotExist, }, "no authorization": { contractID: s.contractID, operator: s.vendor, from: s.customer, - tokenIDs: tokenIDs, + tokenIDs: []string{rootNFTID}, err: collection.ErrCollectionNotApproved, }, "no permission": { contractID: s.contractID, operator: s.stranger, from: s.customer, - tokenIDs: tokenIDs, + tokenIDs: []string{rootNFTID}, err: collection.ErrTokenNoPermission, }, "not found": { @@ -1436,16 +1546,19 @@ func (s *KeeperTestSuite) TestMsgOperatorBurnNFT() { } s.Require().NotNil(res) + s.Require().Equal(tc.events, ctx.EventManager().Events()) - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } }) } } func (s *KeeperTestSuite) TestMsgModify() { - tokenIndex := collection.NewNFTID(s.nftClassID, 1)[8:] + expectedTokenIndex := collection.NewNFTID(s.nftClassID, 1)[8:] + changes := []collection.Attribute{{ + Key: collection.AttributeKeyName.String(), + Value: "test", + }} + testCases := map[string]struct { contractID string operator sdk.AccAddress @@ -1457,8 +1570,14 @@ func (s *KeeperTestSuite) TestMsgModify() { "valid request": { contractID: s.contractID, operator: s.vendor, - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventModifiedContract", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x73}, Value: []uint8{0x5b, 0x7b, 0x22, 0x6b, 0x65, 0x79, 0x22, 0x3a, 0x22, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x2c, 0x22, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x22, 0x3a, 0x22, 0x74, 0x65, 0x73, 0x74, 0x22, 0x7d, 0x5d}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}}}}, - }, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventModifiedContract", + Attributes: []abci.EventAttribute{ + {Key: []byte("changes"), Value: testutil.MustJSONMarshal(changes), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor.String()), Index: false}, + }}}}, "contract not found": { contractID: "deadbeef", operator: s.vendor, @@ -1468,7 +1587,7 @@ func (s *KeeperTestSuite) TestMsgModify() { contractID: s.contractID, operator: s.customer, tokenType: s.nftClassID, - tokenIndex: tokenIndex, + tokenIndex: expectedTokenIndex, err: collection.ErrTokenNoPermission, }, "nft not found": { @@ -1496,11 +1615,6 @@ func (s *KeeperTestSuite) TestMsgModify() { for name, tc := range testCases { s.Run(name, func() { ctx, _ := s.ctx.CacheContext() - - changes := []collection.Attribute{{ - Key: collection.AttributeKeyName.String(), - Value: "test", - }} req := &collection.MsgModify{ ContractId: tc.contractID, Owner: tc.operator.String(), @@ -1515,10 +1629,7 @@ func (s *KeeperTestSuite) TestMsgModify() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } @@ -1537,7 +1648,16 @@ func (s *KeeperTestSuite) TestMsgGrantPermission() { granter: s.vendor, grantee: s.operator, permission: collection.LegacyPermissionModify.String(), - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventGranted", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x4f, 0x44, 0x49, 0x46, 0x59, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventGranted", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.operator.String()), Index: false}, + {Key: []byte("granter"), Value: testutil.W(s.vendor.String()), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionModify).String()), Index: false}, + }}, + }, }, "contract not found": { contractID: "deadbeef", @@ -1572,10 +1692,7 @@ func (s *KeeperTestSuite) TestMsgGrantPermission() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } @@ -1592,7 +1709,15 @@ func (s *KeeperTestSuite) TestMsgRevokePermission() { contractID: s.contractID, from: s.operator, permission: collection.LegacyPermissionMint.String(), - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventRenounced", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x65}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}, {Key: []uint8{0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e}, Value: []uint8{0x22, 0x50, 0x45, 0x52, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4f, 0x4e, 0x5f, 0x4d, 0x49, 0x4e, 0x54, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventRenounced", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("grantee"), Value: testutil.W(s.operator.String()), Index: false}, + {Key: []byte("permission"), Value: testutil.W(collection.Permission(collection.LegacyPermissionMint).String()), Index: false}, + }}, + }, }, "contract not found": { contractID: "deadbeef", @@ -1624,10 +1749,7 @@ func (s *KeeperTestSuite) TestMsgRevokePermission() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } @@ -1644,7 +1766,17 @@ func (s *KeeperTestSuite) TestMsgAttach() { contractID: s.contractID, subjectID: collection.NewNFTID(s.nftClassID, s.depthLimit+1), targetID: collection.NewNFTID(s.nftClassID, 1), - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventAttached", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x22}, Index: false}, {Key: []uint8{0x74, 0x61, 0x72, 0x67, 0x65, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventAttached", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("subject"), Value: testutil.W(collection.NewNFTID(s.nftClassID, s.depthLimit+1)), Index: false}, + {Key: []byte("target"), Value: testutil.W(collection.NewNFTID(s.nftClassID, 1)), Index: false}, + }}, + }, }, "contract not found": { contractID: "deadbeef", @@ -1677,15 +1809,17 @@ func (s *KeeperTestSuite) TestMsgAttach() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgDetach() { + issuedNfts := make([]string, s.depthLimit) + for i := 1; i <= s.depthLimit; i++ { + issuedNfts[i-1] = collection.NewNFTID(s.nftClassID, i) + } + testCases := map[string]struct { contractID string subjectID string @@ -1694,8 +1828,34 @@ func (s *KeeperTestSuite) TestMsgDetach() { }{ "valid request": { contractID: s.contractID, - subjectID: collection.NewNFTID(s.nftClassID, 2), - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventDetached", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}, {Key: []uint8{0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventRootChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventRootChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x22}, Index: false}}}}, + subjectID: issuedNfts[1], + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventDetached", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("previous_parent"), Value: testutil.W(issuedNfts[0]), Index: false}, + {Key: []byte("subject"), Value: testutil.W(issuedNfts[1]), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventRootChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(issuedNfts[0]), Index: false}, + {Key: []byte("to"), Value: testutil.W(issuedNfts[1]), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedNfts[2]), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventRootChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(issuedNfts[0]), Index: false}, + {Key: []byte("to"), Value: testutil.W(issuedNfts[1]), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(issuedNfts[3]), Index: false}, + }}, + }, }, "contract not found": { contractID: "deadbeef", @@ -1730,10 +1890,8 @@ func (s *KeeperTestSuite) TestMsgDetach() { } s.Require().NotNil(res) + s.Require().Equal(tc.events, ctx.EventManager().Events()) - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } }) } } @@ -1752,8 +1910,17 @@ func (s *KeeperTestSuite) TestMsgOperatorAttach() { operator: s.operator, subjectID: collection.NewNFTID(s.nftClassID, s.depthLimit+1), targetID: collection.NewNFTID(s.nftClassID, 1), - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventAttached", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}, {Key: []uint8{0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x35, 0x22}, Index: false}, {Key: []uint8{0x74, 0x61, 0x72, 0x67, 0x65, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}}}}, - }, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventAttached", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator.String()), Index: false}, + {Key: []byte("subject"), Value: testutil.W(collection.NewNFTID(s.nftClassID, s.depthLimit+1)), Index: false}, + {Key: []byte("target"), Value: testutil.W(collection.NewNFTID(s.nftClassID, 1)), Index: false}, + }}, + }}, "contract not found": { contractID: "deadbeef", operator: s.operator, @@ -1795,15 +1962,17 @@ func (s *KeeperTestSuite) TestMsgOperatorAttach() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgOperatorDetach() { + nfts := make([]string, s.depthLimit) + for i := 1; i <= s.depthLimit; i++ { + nfts[i-1] = collection.NewNFTID(s.nftClassID, i) + } + testCases := map[string]struct { contractID string operator sdk.AccAddress @@ -1815,8 +1984,33 @@ func (s *KeeperTestSuite) TestMsgOperatorDetach() { contractID: s.contractID, operator: s.operator, subjectID: collection.NewNFTID(s.nftClassID, 2), - events: sdk.Events{sdk.Event{Type: "lbm.collection.v1.EventDetached", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}, {Key: []uint8{0x70, 0x72, 0x65, 0x76, 0x69, 0x6f, 0x75, 0x73, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}, {Key: []uint8{0x73, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventRootChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x33, 0x22}, Index: false}}}, sdk.Event{Type: "lbm.collection.v1.EventRootChanged", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x32, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x34, 0x22}, Index: false}}}}, - }, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.collection.v1.EventDetached", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer.String()), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator.String()), Index: false}, + {Key: []byte("previous_parent"), Value: testutil.W(nfts[0]), Index: false}, + {Key: []byte("subject"), Value: testutil.W(nfts[1]), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventRootChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(nfts[0]), Index: false}, + {Key: []byte("to"), Value: testutil.W(nfts[1]), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(nfts[2]), Index: false}, + }}, + sdk.Event{ + Type: "lbm.collection.v1.EventRootChanged", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(nfts[0]), Index: false}, + {Key: []byte("to"), Value: testutil.W(nfts[1]), Index: false}, + {Key: []byte("token_id"), Value: testutil.W(nfts[3]), Index: false}, + }}, + }}, "contract not found": { contractID: "deadbeef", operator: s.operator, @@ -1854,22 +2048,29 @@ func (s *KeeperTestSuite) TestMsgOperatorDetach() { } s.Require().NotNil(res) + s.Require().Equal(tc.events, ctx.EventManager().Events()) - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } }) } } -func asJsonStr(attrs collection.Coins) string { - var buf strings.Builder - enc := json.NewEncoder(&buf) - enc.Encode(attrs) - return strings.TrimSpace(buf.String()) -} - -// wrapQuot ("text") -> `"text"` -func wrapQuot(s string) string { - return `"` + strings.TrimSpace(s) + `"` +func (s *KeeperTestSuite) extractChainedNFTIDs(root string) []string { + allTokenIDs := make([]string, 0) + allTokenIDs = append(allTokenIDs, root) + cursor := allTokenIDs[0] + for { + ctx, _ := s.ctx.CacheContext() + res, err := s.queryServer.Children(sdk.WrapSDKContext(ctx), &collection.QueryChildrenRequest{ + ContractId: s.contractID, + TokenId: cursor, + Pagination: &query.PageRequest{}, + }) + s.Require().NoError(err) + if res.Children == nil { + break + } + allTokenIDs = append(allTokenIDs, res.Children[0].TokenId) + cursor = allTokenIDs[len(allTokenIDs)-1] + } + return allTokenIDs } From ca32838da51c0ade754fc29735f997347e9c4bdd Mon Sep 17 00:00:00 2001 From: jaeseung-bae <119839167+jaeseung-bae@users.noreply.github.com> Date: Tue, 17 Oct 2023 14:27:37 +0900 Subject: [PATCH 2/2] test(token): refactoring testcase for token (#1140) * test: refactoring testcase for token * chore: update CHANGELOG * Update testutil/encoding.go Co-authored-by: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> * chore: accept suggestion and add additional testcase * chore: add case for panic --------- Co-authored-by: Jayden Lee <41176085+tkxkd0159@users.noreply.github.com> --- CHANGELOG.md | 1 + testutil/encoding.go | 10 +- testutil/encoding_test.go | 32 ++- x/token/keeper/keeper_test.go | 42 +-- x/token/keeper/msg_server_test.go | 440 +++++++++++------------------- 5 files changed, 219 insertions(+), 306 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5d8bc7f573..f15b9b5d69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ * (x/collection) [\#1133](https://github.com/Finschia/finschia-sdk/pull/1133) Refactor unittest for `SendFT`, `OperatorSendFT`, `AuthorizeOperator`, and `RevokeOperator` to check more states * (x/token) [\#1137](https://github.com/Finschia/finschia-sdk/pull/1137) Add test for event compatibility * (x/collection) [\#1139](https://github.com/Finschia/finschia-sdk/pull/1139) refactor overall unittests of `x/collection` +* (x/token) [\#1140](https://github.com/Finschia/finschia-sdk/pull/1140) Refactor unittest for `x/token` ### Bug Fixes * (ledger) [\#1040](https://github.com/Finschia/finschia-sdk/pull/1040) Fix a bug(unable to connect nano S plus ledger on ubuntu) diff --git a/testutil/encoding.go b/testutil/encoding.go index 02b0e1e533..c62a0680b2 100644 --- a/testutil/encoding.go +++ b/testutil/encoding.go @@ -14,6 +14,12 @@ func MustJSONMarshal(v any) []byte { return b } -func W(input string) []byte { - return []byte(fmt.Sprintf("\"%s\"", input)) +// W wraps input with double quotes if it is a string or fmt.Stringer. +func W(input any) []byte { + switch input.(type) { + case string, fmt.Stringer: + return []byte(fmt.Sprintf("\"%s\"", input)) + default: + panic("unsupported type") + } } diff --git a/testutil/encoding_test.go b/testutil/encoding_test.go index d07ef1b6b4..c542dfc77e 100644 --- a/testutil/encoding_test.go +++ b/testutil/encoding_test.go @@ -2,11 +2,13 @@ package testutil_test import ( "encoding/json" + "fmt" "testing" "github.com/stretchr/testify/require" "github.com/Finschia/finschia-sdk/testutil" + sdk "github.com/Finschia/finschia-sdk/types" ) func TestMustJSONMarshal(t *testing.T) { @@ -29,5 +31,33 @@ func TestMustJSONMarshal(t *testing.T) { } func TestW(t *testing.T) { - require.Equal(t, []byte(`"test"`), testutil.W("test")) + testCases := map[string]struct { + acceptedType any + }{ + "string": { + acceptedType: "test", + }, + "sdk.AccAddress": { + acceptedType: sdk.AccAddress("address"), + }, + "sdk.Coin": { + acceptedType: sdk.NewInt(1), + }, + "should panic for unsupported types": { + acceptedType: 1, + }, + } + + for name, tc := range testCases { + t.Run(name, func(t *testing.T) { + switch v := tc.acceptedType.(type) { + case string, fmt.Stringer: + require.Equal(t, []byte(fmt.Sprintf(`"%s"`, v)), testutil.W(v)) + default: + require.Panics(t, func() { + testutil.W(tc.acceptedType) + }) + } + }) + } } diff --git a/x/token/keeper/keeper_test.go b/x/token/keeper/keeper_test.go index 3277239410..35e259ba0d 100644 --- a/x/token/keeper/keeper_test.go +++ b/x/token/keeper/keeper_test.go @@ -2,7 +2,6 @@ package keeper_test import ( "context" - "fmt" "testing" "github.com/stretchr/testify/suite" @@ -18,8 +17,6 @@ import ( type KeeperTestSuite struct { suite.Suite - deterministic bool - ctx sdk.Context goCtx context.Context keeper keeper.Keeper @@ -38,29 +35,21 @@ type KeeperTestSuite struct { } func (s *KeeperTestSuite) createRandomAccounts(accNum int) []sdk.AccAddress { - if s.deterministic { - addresses := make([]sdk.AccAddress, accNum) - for i := range addresses { - addresses[i] = sdk.AccAddress(fmt.Sprintf("address%d", i)) - } - return addresses - } else { - seenAddresses := make(map[string]bool, accNum) - addresses := make([]sdk.AccAddress, accNum) - for i := range addresses { - var address sdk.AccAddress - for { - pk := secp256k1.GenPrivKey().PubKey() - address = sdk.AccAddress(pk.Address()) - if !seenAddresses[address.String()] { - seenAddresses[address.String()] = true - break - } + seenAddresses := make(map[string]bool, accNum) + addresses := make([]sdk.AccAddress, accNum) + for i := range addresses { + var address sdk.AccAddress + for { + pk := secp256k1.GenPrivKey().PubKey() + address = sdk.AccAddress(pk.Address()) + if !seenAddresses[address.String()] { + seenAddresses[address.String()] = true + break } - addresses[i] = address } - return addresses + addresses[i] = address } + return addresses } func (s *KeeperTestSuite) SetupTest() { @@ -132,10 +121,5 @@ func (s *KeeperTestSuite) SetupTest() { } func TestKeeperTestSuite(t *testing.T) { - for _, deterministic := range []bool{ - false, - true, - } { - suite.Run(t, &KeeperTestSuite{deterministic: deterministic}) - } + suite.Run(t, &KeeperTestSuite{}) } diff --git a/x/token/keeper/msg_server_test.go b/x/token/keeper/msg_server_test.go index 2ecff8cb77..6ca2caeb00 100644 --- a/x/token/keeper/msg_server_test.go +++ b/x/token/keeper/msg_server_test.go @@ -1,14 +1,9 @@ package keeper_test import ( - "encoding/json" - "fmt" - "strings" - "testing" - - "github.com/stretchr/testify/assert" abci "github.com/tendermint/tendermint/abci/types" + "github.com/Finschia/finschia-sdk/testutil" sdk "github.com/Finschia/finschia-sdk/types" sdkerrors "github.com/Finschia/finschia-sdk/types/errors" "github.com/Finschia/finschia-sdk/x/token" @@ -25,7 +20,18 @@ func (s *KeeperTestSuite) TestMsgSend() { "valid request": { contractID: s.contractID, amount: s.balance, - events: sdk.Events{sdk.Event{Type: "lbm.token.v1.EventSent", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x22}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.token.v1.EventSent", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.W(s.balance), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.vendor), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer), Index: false}, + }, + }, + }, }, "contract not found": { contractID: "fee1dead", @@ -56,10 +62,7 @@ func (s *KeeperTestSuite) TestMsgSend() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } @@ -78,7 +81,18 @@ func (s *KeeperTestSuite) TestMsgOperatorSend() { operator: s.operator, from: s.customer, amount: s.balance, - events: sdk.Events{sdk.Event{Type: "lbm.token.v1.EventSent", Attributes: []abci.EventAttribute{{Key: []uint8{0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74}, Value: []uint8{0x22, 0x31, 0x30, 0x30, 0x30, 0x22}, Index: false}, {Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x66, 0x72, 0x6f, 0x6d}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}, {Key: []uint8{0x74, 0x6f}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.token.v1.EventSent", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.W(s.balance), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.vendor), Index: false}, + }, + }, + }, }, "contract not found": { contractID: "fee1dead", @@ -121,10 +135,7 @@ func (s *KeeperTestSuite) TestMsgOperatorSend() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } @@ -141,7 +152,16 @@ func (s *KeeperTestSuite) TestMsgRevokeOperator() { contractID: s.contractID, holder: s.customer, operator: s.operator, - events: sdk.Events{sdk.Event{Type: "lbm.token.v1.EventRevokedOperator", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x7a, 0x77, 0x30, 0x38, 0x70, 0x36, 0x74, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.token.v1.EventRevokedOperator", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator), Index: false}, + }, + }, + }, }, "contract not found": { contractID: "fee1dead", @@ -173,10 +193,7 @@ func (s *KeeperTestSuite) TestMsgRevokeOperator() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } @@ -193,7 +210,16 @@ func (s *KeeperTestSuite) TestMsgAuthorizeOperator() { contractID: s.contractID, holder: s.customer, operator: s.vendor, - events: sdk.Events{sdk.Event{Type: "lbm.token.v1.EventAuthorizedOperator", Attributes: []abci.EventAttribute{{Key: []uint8{0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x5f, 0x69, 0x64}, Value: []uint8{0x22, 0x39, 0x62, 0x65, 0x31, 0x37, 0x31, 0x36, 0x35, 0x22}, Index: false}, {Key: []uint8{0x68, 0x6f, 0x6c, 0x64, 0x65, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x79, 0x6a, 0x71, 0x79, 0x79, 0x78, 0x75, 0x22}, Index: false}, {Key: []uint8{0x6f, 0x70, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72}, Value: []uint8{0x22, 0x6c, 0x69, 0x6e, 0x6b, 0x31, 0x76, 0x39, 0x6a, 0x78, 0x67, 0x75, 0x6e, 0x39, 0x77, 0x64, 0x65, 0x6e, 0x71, 0x61, 0x32, 0x78, 0x7a, 0x66, 0x78, 0x22}, Index: false}}}}, + events: sdk.Events{ + sdk.Event{ + Type: "lbm.token.v1.EventAuthorizedOperator", + Attributes: []abci.EventAttribute{ + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("holder"), Value: testutil.W(s.customer), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor), Index: false}, + }, + }, + }, }, "contract not found": { contractID: "fee1dead", @@ -225,18 +251,12 @@ func (s *KeeperTestSuite) TestMsgAuthorizeOperator() { } s.Require().NotNil(res) - - if s.deterministic { - s.Require().Equal(tc.events, ctx.EventManager().Events()) - } + s.Require().Equal(tc.events, ctx.EventManager().Events()) }) } } func (s *KeeperTestSuite) TestMsgIssue() { - ownerAddr := s.vendor.String() - toAddr := s.vendor.String() - testCases := map[string]struct { mintable bool amount sdk.Int @@ -250,50 +270,50 @@ func (s *KeeperTestSuite) TestMsgIssue() { sdk.Event{ Type: "lbm.token.v1.EventIssued", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("creator"), Value: []uint8(fmt.Sprintf("\"%s\"", ownerAddr)), Index: false}, - {Key: []uint8("decimals"), Value: []uint8("0"), Index: false}, - {Key: []uint8("meta"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("mintable"), Value: []uint8("true"), Index: false}, - {Key: []uint8("name"), Value: []uint8("\"test\""), Index: false}, - {Key: []uint8("symbol"), Value: []uint8("\"TT\""), Index: false}, - {Key: []uint8("uri"), Value: []uint8("\"\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("creator"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("decimals"), Value: []byte("0"), Index: false}, + {Key: []uint8("meta"), Value: testutil.W(""), Index: false}, + {Key: []uint8("mintable"), Value: []byte("true"), Index: false}, + {Key: []uint8("name"), Value: testutil.W("test"), Index: false}, + {Key: []uint8("symbol"), Value: testutil.W("TT"), Index: false}, + {Key: []uint8("uri"), Value: testutil.W(""), Index: false}, }, }, sdk.Event{ Type: "lbm.token.v1.EventGranted", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", toAddr)), Index: false}, - {Key: []uint8("granter"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_MODIFY\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("granter"), Value: testutil.W(""), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_MODIFY"), Index: false}, }, }, sdk.Event{ Type: "lbm.token.v1.EventGranted", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", toAddr)), Index: false}, - {Key: []uint8("granter"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_MINT\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("granter"), Value: testutil.W(""), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_MINT"), Index: false}, }, }, sdk.Event{ Type: "lbm.token.v1.EventGranted", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", toAddr)), Index: false}, - {Key: []uint8("granter"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_BURN\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("granter"), Value: testutil.W(""), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_BURN"), Index: false}, }, }, sdk.Event{ Type: "lbm.token.v1.EventMinted", Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("\"10\""), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", ownerAddr)), Index: false}, - {Key: []uint8("to"), Value: []uint8(fmt.Sprintf("\"%s\"", toAddr)), Index: false}, + {Key: []uint8("amount"), Value: testutil.W("10"), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("operator"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("to"), Value: testutil.W(s.vendor), Index: false}, }, }, }, @@ -305,32 +325,32 @@ func (s *KeeperTestSuite) TestMsgIssue() { sdk.Event{ Type: "lbm.token.v1.EventIssued", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("creator"), Value: []uint8(fmt.Sprintf("\"%s\"", ownerAddr)), Index: false}, - {Key: []uint8("decimals"), Value: []uint8("0"), Index: false}, - {Key: []uint8("meta"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("mintable"), Value: []uint8("false"), Index: false}, - {Key: []uint8("name"), Value: []uint8("\"test\""), Index: false}, - {Key: []uint8("symbol"), Value: []uint8("\"TT\""), Index: false}, - {Key: []uint8("uri"), Value: []uint8("\"\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("creator"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("decimals"), Value: []byte("0"), Index: false}, + {Key: []uint8("meta"), Value: testutil.W(""), Index: false}, + {Key: []uint8("mintable"), Value: []byte("false"), Index: false}, + {Key: []uint8("name"), Value: testutil.W("test"), Index: false}, + {Key: []uint8("symbol"), Value: testutil.W("TT"), Index: false}, + {Key: []uint8("uri"), Value: testutil.W(""), Index: false}, }, }, sdk.Event{ Type: "lbm.token.v1.EventGranted", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", ownerAddr)), Index: false}, - {Key: []uint8("granter"), Value: []uint8("\"\""), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_MODIFY\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("granter"), Value: testutil.W(""), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_MODIFY"), Index: false}, }, }, sdk.Event{ Type: "lbm.token.v1.EventMinted", Attributes: []abci.EventAttribute{ - {Key: []uint8("amount"), Value: []uint8("\"10\""), Index: false}, - {Key: []uint8("contract_id"), Value: []uint8("\"ca8bfd79\""), Index: false}, - {Key: []uint8("operator"), Value: []uint8(fmt.Sprintf("\"%s\"", ownerAddr)), Index: false}, - {Key: []uint8("to"), Value: []uint8(fmt.Sprintf("\"%s\"", toAddr)), Index: false}, + {Key: []uint8("amount"), Value: testutil.W(sdk.NewInt(10)), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("ca8bfd79"), Index: false}, + {Key: []uint8("operator"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("to"), Value: testutil.W(s.vendor), Index: false}, }, }, }, @@ -465,10 +485,10 @@ func (s *KeeperTestSuite) TestMsgGrantPermission() { sdk.Event{ Type: "lbm.token.v1.EventGranted", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", s.operator.String())), Index: false}, - {Key: []uint8("granter"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor.String())), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_MINT\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("9be17165"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.operator), Index: false}, + {Key: []uint8("granter"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_MINT"), Index: false}, }, }, }, @@ -482,10 +502,10 @@ func (s *KeeperTestSuite) TestMsgGrantPermission() { sdk.Event{ Type: "lbm.token.v1.EventGranted", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", s.operator.String())), Index: false}, - {Key: []uint8("granter"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor.String())), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_BURN\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("9be17165"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.operator), Index: false}, + {Key: []uint8("granter"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_BURN"), Index: false}, }, }, }, @@ -499,10 +519,10 @@ func (s *KeeperTestSuite) TestMsgGrantPermission() { sdk.Event{ Type: "lbm.token.v1.EventGranted", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", s.operator.String())), Index: false}, - {Key: []uint8("granter"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor.String())), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_MODIFY\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("9be17165"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.operator), Index: false}, + {Key: []uint8("granter"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_MODIFY"), Index: false}, }, }, }, @@ -597,9 +617,9 @@ func (s *KeeperTestSuite) TestMsgRevokePermission() { sdk.Event{ Type: "lbm.token.v1.EventRenounced", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", s.operator)), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_MINT\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("9be17165"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.operator), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_MINT"), Index: false}, }, }}, }, @@ -611,9 +631,9 @@ func (s *KeeperTestSuite) TestMsgRevokePermission() { sdk.Event{ Type: "lbm.token.v1.EventRenounced", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", s.operator)), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_BURN\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("9be17165"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.operator), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_BURN"), Index: false}, }, }}, }, @@ -625,9 +645,9 @@ func (s *KeeperTestSuite) TestMsgRevokePermission() { sdk.Event{ Type: "lbm.token.v1.EventRenounced", Attributes: []abci.EventAttribute{ - {Key: []uint8("contract_id"), Value: []uint8("\"9be17165\""), Index: false}, - {Key: []uint8("grantee"), Value: []uint8(fmt.Sprintf("\"%s\"", s.vendor)), Index: false}, - {Key: []uint8("permission"), Value: []uint8("\"PERMISSION_MODIFY\""), Index: false}, + {Key: []uint8("contract_id"), Value: testutil.W("9be17165"), Index: false}, + {Key: []uint8("grantee"), Value: testutil.W(s.vendor), Index: false}, + {Key: []uint8("permission"), Value: testutil.W("PERMISSION_MODIFY"), Index: false}, }, }}, }, @@ -683,7 +703,15 @@ func (s *KeeperTestSuite) TestMsgMint() { Amount: sdk.NewInt(10), }, expectedEvents: sdk.Events{ - helperBuildMintedEvent(s.contractID, s.vendor, s.customer, sdk.NewInt(10)), + sdk.Event{ + Type: "lbm.token.v1.EventMinted", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.W(sdk.NewInt(10)), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer), Index: false}, + }, + }, }, }, "mint(contractID, from, from, 10)": { @@ -694,7 +722,15 @@ func (s *KeeperTestSuite) TestMsgMint() { Amount: sdk.NewInt(10), }, expectedEvents: sdk.Events{ - helperBuildMintedEvent(s.contractID, s.vendor, s.customer, sdk.NewInt(10)), + sdk.Event{ + Type: "lbm.token.v1.EventMinted", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.W(sdk.NewInt(10)), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor), Index: false}, + {Key: []byte("to"), Value: testutil.W(s.customer), Index: false}, + }, + }, }, }, "mint(contractID, vendor, customer, 1) -> error": { @@ -772,56 +808,6 @@ func (s *KeeperTestSuite) TestMsgMint() { } } -func helperBuildMintedEvent(contractID string, operator, to sdk.AccAddress, amount sdk.Int) sdk.Event { - return sdk.Event{ - Type: "lbm.token.v1.EventMinted", - Attributes: []abci.EventAttribute{ - {Key: []byte("amount"), Value: []byte(wrapQuot(amount.String())), Index: false}, - {Key: []byte("contract_id"), Value: []byte(wrapQuot(contractID)), Index: false}, - {Key: []byte("operator"), Value: []byte(wrapQuot(operator.String())), Index: false}, - {Key: []byte("to"), Value: []byte(wrapQuot(to.String())), Index: false}, - }, - } -} - -func TestHelperBuildMintedEvent(t *testing.T) { - testCases := map[string]struct { - expectedEvent sdk.Event - contractID string - from string - to string - amount sdk.Int - }{ - "helper function should keep event compatibility for EventMinted": { - expectedEvent: sdk.Event{Type: "lbm.token.v1.EventMinted", Attributes: []abci.EventAttribute{ - {Key: []byte("amount"), Value: []byte(`"1"`), Index: false}, - {Key: []byte("contract_id"), Value: []byte(`"9be17165"`), Index: false}, - {Key: []byte("operator"), Value: []byte(`"link1v9jxgun9wdenzw08p6t"`), Index: false}, - {Key: []byte("to"), Value: []byte(`"link1v9jxgun9wdenyjqyyxu"`), Index: false}, - }}, - contractID: "9be17165", - from: "link1v9jxgun9wdenzw08p6t", - to: "link1v9jxgun9wdenyjqyyxu", - amount: sdk.OneInt(), - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - // Arrange - from, err := sdk.AccAddressFromBech32(tc.from) - assert.NoError(t, err) - to, err := sdk.AccAddressFromBech32(tc.to) - assert.NoError(t, err) - - // Act - event := helperBuildMintedEvent(tc.contractID, from, to, tc.amount) - - // Assert - assert.Equal(t, tc.expectedEvent, event) - }) - } -} - func (s *KeeperTestSuite) TestMsgBurn() { testCases := map[string]struct { isNegativeCase bool @@ -836,7 +822,15 @@ func (s *KeeperTestSuite) TestMsgBurn() { Amount: sdk.OneInt(), }, expectedEvents: sdk.Events{ - helperBuildBurnedEvt(s.contractID, s.vendor, s.vendor, sdk.OneInt()), + sdk.Event{ + Type: "lbm.token.v1.EventBurned", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.W(sdk.OneInt()), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.vendor), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.vendor), Index: false}, + }, + }, }, }, "burn(nonExistingContractId, from, 1) -> error": { @@ -910,7 +904,15 @@ func (s *KeeperTestSuite) TestMsgOperatorBurn() { From: s.customer.String(), Amount: sdk.OneInt(), }, - expectedEvent: helperBuildBurnedEvt(s.contractID, s.customer, s.operator, sdk.OneInt()), + expectedEvent: sdk.Event{ + Type: "lbm.token.v1.EventBurned", + Attributes: []abci.EventAttribute{ + {Key: []byte("amount"), Value: testutil.W(sdk.OneInt()), Index: false}, + {Key: []byte("contract_id"), Value: testutil.W(s.contractID), Index: false}, + {Key: []byte("from"), Value: testutil.W(s.customer), Index: false}, + {Key: []byte("operator"), Value: testutil.W(s.operator), Index: false}, + }, + }, }, "operatorBurn(nonExistingContractId, operator, from, 1) -> error": { isNegativeCase: true, @@ -979,76 +981,7 @@ func (s *KeeperTestSuite) TestMsgOperatorBurn() { } } -func helperBuildBurnedEvt(contractID string, from, operator sdk.AccAddress, amount sdk.Int) sdk.Event { - return sdk.Event{ - Type: "lbm.token.v1.EventBurned", - Attributes: []abci.EventAttribute{ - {Key: []byte("amount"), Value: []byte(wrapQuot(amount.String())), Index: false}, - {Key: []byte("contract_id"), Value: []byte(wrapQuot(contractID)), Index: false}, - {Key: []byte("from"), Value: []byte(wrapQuot(from.String())), Index: false}, - {Key: []byte("operator"), Value: []byte(wrapQuot(operator.String())), Index: false}, - }, - } -} - -func TestHelperBuildBurnedEvent(t *testing.T) { - testCases := map[string]struct { - expectedEvent sdk.Event - contractID string - from string - operator string - amount sdk.Int - }{ - "should keep event compatibility for EventBurned": { - expectedEvent: sdk.Event{Type: "lbm.token.v1.EventBurned", Attributes: []abci.EventAttribute{ - {Key: []byte("amount"), Value: []byte(`"1000"`), Index: false}, - {Key: []byte("contract_id"), Value: []byte(`"9be17165"`), Index: false}, - {Key: []byte("from"), Value: []byte(`"link1v9jxgun9wdenqa2xzfx"`), Index: false}, - {Key: []byte("operator"), Value: []byte(`"link1v9jxgun9wdenqa2xzfx"`), Index: false}, - }}, - contractID: "9be17165", - from: "link1v9jxgun9wdenqa2xzfx", - operator: "link1v9jxgun9wdenqa2xzfx", - amount: sdk.NewInt(1000), - }, - "should keep event compatibility for EventBurned(operatorBurn)": { - expectedEvent: sdk.Event{Type: "lbm.token.v1.EventBurned", Attributes: []abci.EventAttribute{ - {Key: []byte("amount"), Value: []byte(`"1000"`), Index: false}, - {Key: []byte("contract_id"), Value: []byte(`"9be17165"`), Index: false}, - {Key: []byte("from"), Value: []byte(`"link1v9jxgun9wdenyjqyyxu"`), Index: false}, - {Key: []byte("operator"), Value: []byte(`"link1v9jxgun9wdenzw08p6t"`), Index: false}, - }}, - contractID: "9be17165", - from: "link1v9jxgun9wdenyjqyyxu", - operator: "link1v9jxgun9wdenzw08p6t", - amount: sdk.NewInt(1000), - }, - } - - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - // Arrange - from, err := sdk.AccAddressFromBech32(tc.from) - assert.NoError(t, err) - operator, err := sdk.AccAddressFromBech32(tc.operator) - assert.NoError(t, err) - - // Act - event := helperBuildBurnedEvt(tc.contractID, from, operator, tc.amount) - - // Assert - assert.Equal(t, tc.expectedEvent, event) - }) - } -} - func (s *KeeperTestSuite) TestMsgModify() { - changesUriAndName := []token.Attribute{ - {Key: token.AttributeKeyURI.String(), Value: "uri"}, - {Key: token.AttributeKeyName.String(), Value: "NA error": { @@ -1118,59 +1066,3 @@ func (s *KeeperTestSuite) TestMsgModify() { }) } } - -func helperBuildModifiedEvt(contractID string, operator sdk.AccAddress, changes []token.Attribute) sdk.Event { - return sdk.Event{ - Type: "lbm.token.v1.EventModified", - Attributes: []abci.EventAttribute{ - {Key: []byte("changes"), Value: []byte(asJsonStr(changes)), Index: false}, - {Key: []byte("contract_id"), Value: []byte(wrapQuot(contractID)), Index: false}, - {Key: []byte("operator"), Value: []byte(wrapQuot(operator.String())), Index: false}, - }, - } -} - -func TestHelperBuildModifiedEvent(t *testing.T) { - testCases := map[string]struct { - expectedEvent sdk.Event - contractID string - owner string - changes []token.Attribute - }{ - "should keep event compatibility for EventModified": { - expectedEvent: sdk.Event{Type: "lbm.token.v1.EventModified", Attributes: []abci.EventAttribute{ - {Key: []byte("changes"), Value: []byte(`[{"key":"uri","value":"uri"}]`), Index: false}, - {Key: []byte("contract_id"), Value: []byte(`"9be17165"`), Index: false}, - {Key: []byte("operator"), Value: []byte(`"link1v9jxgun9wdenqa2xzfx"`), Index: false}, - }}, - contractID: "9be17165", - owner: "link1v9jxgun9wdenqa2xzfx", - changes: []token.Attribute{{Key: token.AttributeKeyURI.String(), Value: "uri"}}, - }, - } - for name, tc := range testCases { - t.Run(name, func(t *testing.T) { - // Arrange - owner, err := sdk.AccAddressFromBech32(tc.owner) - assert.NoError(t, err) - - // Act - event := helperBuildModifiedEvt(tc.contractID, owner, tc.changes) - - // Assert - assert.Equal(t, tc.expectedEvent, event) - }) - } -} - -func asJsonStr(attrs []token.Attribute) string { - var buf strings.Builder - enc := json.NewEncoder(&buf) - enc.Encode(attrs) - return strings.TrimSpace(buf.String()) -} - -// wrapQuot ("text") -> `"text"` -func wrapQuot(s string) string { - return `"` + strings.TrimSpace(s) + `"` -}