Skip to content

Commit

Permalink
Merge pull request #7 from bianjieai/yuandu/fix-json-encoding
Browse files Browse the repository at this point in the history
Fix: NFT package JSON encoding
  • Loading branch information
aofengli authored Jan 30, 2023
2 parents ca42430 + d2dd106 commit 3717108
Show file tree
Hide file tree
Showing 4 changed files with 134 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
build/
.idea/
2 changes: 1 addition & 1 deletion types/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func MustProtoMarshalJSON(msg proto.Message) []byte {
// ProtoMarshalJSON provides an auxiliary function to return Proto3 JSON encoded
// bytes of a message.
func ProtoMarshalJSON(msg proto.Message, resolver jsonpb.AnyResolver) ([]byte, error) {
jm := &jsonpb.Marshaler{OrigName: false, EmitDefaults: true, AnyResolver: resolver}
jm := &jsonpb.Marshaler{OrigName: false, EmitDefaults: false, AnyResolver: resolver}
err := codectypes.UnpackInterfaces(msg, codectypes.ProtoJSONPacker{JSONPBMarshaler: jm})
if err != nil {
return nil, err
Expand Down
36 changes: 36 additions & 0 deletions types/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,17 @@ func (nftpd NonFungibleTokenPacketData) ValidateBasic() error {

// GetBytes is a helper for serializing
func (nftpd NonFungibleTokenPacketData) GetBytes() []byte {
// Format will reshape tokenUris and tokenData in NonFungibleTokenPacketData:
// 1. if tokenUris/tokenData is ["","",""] or [], then set it to nil.
// 2. if tokenUris/tokenData is ["a","b","c"] or ["a", "", "c"], then keep it.
// NOTE: Only use this before sending pkg.
if requireShape(nftpd.TokenUris) {
nftpd.TokenUris = nil
}

if requireShape(nftpd.TokenData) {
nftpd.TokenData = nil
}
return sdk.MustSortJSON(MustProtoMarshalJSON(&nftpd))
}

Expand All @@ -89,3 +100,28 @@ func GetIfExist(i int, data []string) string {
}
return data[i]
}

// requireShape checks if TokenUris/TokenData needs to be set as nil
func requireShape(contents []string) bool {
if contents == nil {
return false
}

// empty slice of string
if len(contents) == 0 {
return true
}

emptyStringCount := 0
for _, v := range contents {
if len(v) == 0 {
emptyStringCount++
}
}
// slice of string with only empty string.
if emptyStringCount == len(contents) {
return true
}

return false
}
95 changes: 95 additions & 0 deletions types/packet_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package types

import (
"bytes"
"testing"
)

Expand Down Expand Up @@ -31,11 +32,21 @@ func TestNonFungibleTokenPacketData_ValidateBasic(t *testing.T) {
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, []string{}, tokenData, sender, receiver, "memo"},
wantErr: false,
},
{
name: "valid packet with nil tokenUris",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, nil, tokenData, sender, receiver, "memo"},
wantErr: false,
},
{
name: "valid packet with tokenUris",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, []string{"1"}, tokenData, sender, receiver, "memo"},
wantErr: false,
},
{
name: "valid packet with tokenUris of empty string entry",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty", "mary"}, []string{"1", ""}, tokenData, sender, receiver, "memo"},
wantErr: false,
},
{
name: "invalid packet with unmatched tokenUris number",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, []string{"1", "2"}, tokenData, sender, receiver, "memo"},
Expand All @@ -46,11 +57,21 @@ func TestNonFungibleTokenPacketData_ValidateBasic(t *testing.T) {
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, []string{}, []string{}, sender, receiver, "memo"},
wantErr: false,
},
{
name: "valid packet with nil tokenData",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, []string{}, nil, sender, receiver, "memo"},
wantErr: false,
},
{
name: "valid packet with tokenData",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, []string{}, []string{"1"}, sender, receiver, "memo"},
wantErr: false,
},
{
name: "valid packet with tokenData of empty string entry",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty", "mary"}, []string{}, []string{"1", ""}, sender, receiver, "memo"},
wantErr: false,
},
{
name: "invalid packet with unmatched tokenData number",
packet: NonFungibleTokenPacketData{"cryptoCat", "uri", "", []string{"kitty"}, []string{}, []string{"1", "2"}, sender, receiver, "memo"},
Expand All @@ -75,3 +96,77 @@ func TestNonFungibleTokenPacketData_ValidateBasic(t *testing.T) {
})
}
}

func TestNonFungibleTokenPacketData_GetBytes(t *testing.T) {
type fields struct {
ClassId string
ClassUri string
ClassData string
TokenIds []string
TokenUris []string
TokenData []string
Sender string
Receiver string
Memo string
}
tests := []struct {
name string
fields fields
want []byte
}{
{
"success",
fields{"classId", "classUri", "classData", []string{"id1", "id2"}, []string{"uri1", "uri2"}, []string{"data1"}, sender, receiver, "memo"},
[]byte(`{"classData":"classData","classId":"classId","classUri":"classUri","memo":"memo","receiver":"cosmos15mn87gny58ptfpzq0du6t398gle50xphkw2pkt","sender":"cosmos1eshqg3adwvnuqng0eqfr6ppj35j9hh6zyd9qss","tokenData":["data1"],"tokenIds":["id1","id2"],"tokenUris":["uri1","uri2"]}`),
},
{
"success with missing classUri",
fields{"classId", "", "classData", []string{"id1", "id2"}, []string{"uri1", "uri2"}, []string{"data1"}, sender, receiver, "memo"},
[]byte(`{"classData":"classData","classId":"classId","memo":"memo","receiver":"cosmos15mn87gny58ptfpzq0du6t398gle50xphkw2pkt","sender":"cosmos1eshqg3adwvnuqng0eqfr6ppj35j9hh6zyd9qss","tokenData":["data1"],"tokenIds":["id1","id2"],"tokenUris":["uri1","uri2"]}`),
},
{
"success with missing classData",
fields{"classId", "classUri", "", []string{"id1", "id2"}, []string{"uri1", "uri2"}, []string{"data1"}, sender, receiver, "memo"},
[]byte(`{"classId":"classId","classUri":"classUri","memo":"memo","receiver":"cosmos15mn87gny58ptfpzq0du6t398gle50xphkw2pkt","sender":"cosmos1eshqg3adwvnuqng0eqfr6ppj35j9hh6zyd9qss","tokenData":["data1"],"tokenIds":["id1","id2"],"tokenUris":["uri1","uri2"]}`),
},
{
"success with empty tokenUris",
fields{"classId", "classUri", "classData", []string{"id1", "id2"}, []string{"", ""}, []string{"data1"}, sender, receiver, "memo"},
[]byte(`{"classData":"classData","classId":"classId","classUri":"classUri","memo":"memo","receiver":"cosmos15mn87gny58ptfpzq0du6t398gle50xphkw2pkt","sender":"cosmos1eshqg3adwvnuqng0eqfr6ppj35j9hh6zyd9qss","tokenData":["data1"],"tokenIds":["id1","id2"`),
},
{
"success with nil tokenUris",
fields{"classId", "classUri", "classData", []string{"id1", "id2"}, nil, []string{"data1"}, sender, receiver, "memo"},
[]byte(`{"classData":"classData","classId":"classId","classUri":"classUri","memo":"memo","receiver":"cosmos15mn87gny58ptfpzq0du6t398gle50xphkw2pkt","sender":"cosmos1eshqg3adwvnuqng0eqfr6ppj35j9hh6zyd9qss","tokenData":["data1"],"tokenIds":["id1","id2"`),
},
{
"success with empty tokenData",
fields{"classId", "classUri", "classData", []string{"id1", "id2"}, []string{"uri1", "uri2"}, []string{"", ""}, sender, receiver, "memo"},
[]byte(`{"classData":"classData","classId":"classId","classUri":"classUri","memo":"memo","receiver":"cosmos15mn87gny58ptfpzq0du6t398gle50xphkw2pkt","sender":"cosmos1eshqg3adwvnuqng0eqfr6ppj35j9hh6zyd9qss","tokenData":["data1"],"tokenIds":["id1","id2"`),
},
{
"success with nil tokenData",
fields{"classId", "classUri", "classData", []string{"id1", "id2"}, []string{"uri1", "uri2"}, nil, sender, receiver, "memo"},
[]byte(`{"classData":"classData","classId":"classId","classUri":"classUri","memo":"memo","receiver":"cosmos15mn87gny58ptfpzq0du6t398gle50xphkw2pkt","sender":"cosmos1eshqg3adwvnuqng0eqfr6ppj35j9hh6zyd9qss","tokenData":["data1"],"tokenIds":["id1","id2"`),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
nftpd := NonFungibleTokenPacketData{
ClassId: tt.fields.ClassId,
ClassUri: tt.fields.ClassUri,
ClassData: tt.fields.ClassData,
TokenIds: tt.fields.TokenIds,
TokenUris: tt.fields.TokenUris,
TokenData: tt.fields.TokenData,
Sender: tt.fields.Sender,
Receiver: tt.fields.Receiver,
Memo: tt.fields.Memo,
}
t.Logf("%s\n", nftpd.GetBytes())
if got := nftpd.GetBytes(); bytes.Equal(got, tt.want) {
t.Errorf("NonFungibleTokenPacketData.GetBytes() = %v, want %v", got, tt.want)
}
})
}
}

0 comments on commit 3717108

Please sign in to comment.