github.com/Finschia/finschia-sdk@v0.48.1/x/collection/keeper/migrations/v2/store_test.go (about) 1 package v2_test 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 9 simappparams "github.com/Finschia/finschia-sdk/simapp/params" 10 "github.com/Finschia/finschia-sdk/testutil" 11 sdk "github.com/Finschia/finschia-sdk/types" 12 "github.com/Finschia/finschia-sdk/x/collection" 13 14 "github.com/Finschia/finschia-sdk/x/collection/keeper/migrations/v2" 15 ) 16 17 func TestMigrateStore(t *testing.T) { 18 collectionKey := sdk.NewKVStoreKey(collection.StoreKey) 19 newKey := sdk.NewTransientStoreKey("transient_test") 20 encCfg := simappparams.MakeTestEncodingConfig() 21 ctx := testutil.DefaultContext(collectionKey, newKey) 22 23 // set state 24 store := ctx.KVStore(collectionKey) 25 26 contractID := "deadbeef" 27 store.Set(v2.ContractKey(contractID), encCfg.Marshaler.MustMarshal(&collection.Contract{Id: contractID})) 28 nextClassIDs := collection.DefaultNextClassIDs(contractID) 29 classID := fmt.Sprintf("%08x", nextClassIDs.Fungible.Uint64()) 30 nextClassIDs.Fungible = nextClassIDs.Fungible.Incr() 31 store.Set(v2.NextClassIDKey(contractID), encCfg.Marshaler.MustMarshal(&nextClassIDs)) 32 33 tokenID := collection.NewFTID(classID) 34 oneIntBz, err := sdk.OneInt().Marshal() 35 require.NoError(t, err) 36 addresses := []sdk.AccAddress{ 37 sdk.AccAddress("fennec"), 38 sdk.AccAddress("penguin"), 39 sdk.AccAddress("cheetah"), 40 } 41 for _, addr := range addresses { 42 store.Set(v2.BalanceKey(contractID, addr, tokenID), oneIntBz) 43 } 44 store.Set(v2.StatisticKey(v2.SupplyKeyPrefix, contractID, classID), oneIntBz) 45 store.Set(v2.StatisticKey(v2.MintedKeyPrefix, contractID, classID), oneIntBz) 46 store.Set(v2.StatisticKey(v2.BurntKeyPrefix, contractID, classID), oneIntBz) 47 48 for name, tc := range map[string]struct { 49 malleate func(ctx sdk.Context) 50 valid bool 51 supply int 52 minted int 53 }{ 54 "valid": { 55 valid: true, 56 supply: len(addresses), 57 minted: len(addresses) + 1, 58 }, 59 "valid (nil supply)": { 60 malleate: func(ctx sdk.Context) { 61 store := ctx.KVStore(collectionKey) 62 store.Delete(v2.StatisticKey(v2.SupplyKeyPrefix, contractID, classID)) 63 }, 64 valid: true, 65 supply: len(addresses), 66 minted: len(addresses) + 1, 67 }, 68 "valid (nil minted)": { 69 malleate: func(ctx sdk.Context) { 70 store := ctx.KVStore(collectionKey) 71 store.Delete(v2.StatisticKey(v2.MintedKeyPrefix, contractID, classID)) 72 }, 73 valid: true, 74 supply: len(addresses), 75 minted: len(addresses) + 1, 76 }, 77 "valid (nil burnt)": { 78 malleate: func(ctx sdk.Context) { 79 store := ctx.KVStore(collectionKey) 80 store.Delete(v2.StatisticKey(v2.BurntKeyPrefix, contractID, classID)) 81 }, 82 valid: true, 83 supply: len(addresses), 84 minted: len(addresses), 85 }, 86 "contract unmarshal failed": { 87 malleate: func(ctx sdk.Context) { 88 store := ctx.KVStore(collectionKey) 89 store.Set(v2.ContractKey(contractID), encCfg.Marshaler.MustMarshal(&collection.GenesisState{})) 90 }, 91 }, 92 "balance unmarshal failed": { 93 malleate: func(ctx sdk.Context) { 94 store := ctx.KVStore(collectionKey) 95 store.Set(v2.BalanceKey(contractID, sdk.AccAddress("hyena"), tokenID), encCfg.Marshaler.MustMarshal(&collection.GenesisState{})) 96 }, 97 }, 98 "no next class id": { 99 malleate: func(ctx sdk.Context) { 100 store := ctx.KVStore(collectionKey) 101 store.Delete(v2.NextClassIDKey(contractID)) 102 }, 103 }, 104 "next class id unmarshal failed": { 105 malleate: func(ctx sdk.Context) { 106 store := ctx.KVStore(collectionKey) 107 store.Set(v2.NextClassIDKey(contractID), []byte("invalid")) 108 }, 109 }, 110 "burnt unmarshal failed": { 111 malleate: func(ctx sdk.Context) { 112 store := ctx.KVStore(collectionKey) 113 store.Set(v2.StatisticKey(v2.BurntKeyPrefix, contractID, classID), encCfg.Marshaler.MustMarshal(&collection.GenesisState{})) 114 }, 115 }, 116 } { 117 t.Run(name, func(t *testing.T) { 118 ctx, _ := ctx.CacheContext() 119 if tc.malleate != nil { 120 tc.malleate(ctx) 121 } 122 123 // migrate 124 err := v2.MigrateStore(ctx, collectionKey, encCfg.Marshaler) 125 if !tc.valid { 126 require.Error(t, err) 127 return 128 } 129 require.NoError(t, err) 130 131 store := ctx.KVStore(collectionKey) 132 133 // supply 134 supplyKey := v2.StatisticKey(v2.SupplyKeyPrefix, contractID, classID) 135 supply := sdk.ZeroInt() 136 if bz := store.Get(supplyKey); bz != nil { 137 err := supply.Unmarshal(bz) 138 require.NoError(t, err) 139 } 140 require.Equal(t, int64(tc.supply), supply.Int64()) 141 142 // minted 143 mintedKey := v2.StatisticKey(v2.MintedKeyPrefix, contractID, classID) 144 minted := sdk.ZeroInt() 145 if bz := store.Get(mintedKey); bz != nil { 146 err := minted.Unmarshal(bz) 147 require.NoError(t, err) 148 } 149 require.Equal(t, int64(tc.minted), minted.Int64()) 150 }) 151 } 152 }