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