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  }