github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/keeper/events_test.go (about)

     1  package keeper
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  
     7  	wasmvmtypes "github.com/CosmWasm/wasmvm/types"
     8  	sdk "github.com/fibonacci-chain/fbc/libs/cosmos-sdk/types"
     9  	"github.com/stretchr/testify/assert"
    10  
    11  	"github.com/fibonacci-chain/fbc/x/wasm/types"
    12  )
    13  
    14  func TestHasWasmModuleEvent(t *testing.T) {
    15  	myContractAddr := RandomAccountAddress(t)
    16  	specs := map[string]struct {
    17  		srcEvents []sdk.Event
    18  		exp       bool
    19  	}{
    20  		"event found": {
    21  			srcEvents: []sdk.Event{
    22  				sdk.NewEvent(types.WasmModuleEventType, sdk.NewAttribute("_contract_address", myContractAddr.String())),
    23  			},
    24  			exp: true,
    25  		},
    26  		"different event: not found": {
    27  			srcEvents: []sdk.Event{
    28  				sdk.NewEvent(types.CustomContractEventPrefix, sdk.NewAttribute("_contract_address", myContractAddr.String())),
    29  			},
    30  			exp: false,
    31  		},
    32  		"event with different address: not found": {
    33  			srcEvents: []sdk.Event{
    34  				sdk.NewEvent(types.WasmModuleEventType, sdk.NewAttribute("_contract_address", RandomBech32AccountAddress(t))),
    35  			},
    36  			exp: false,
    37  		},
    38  		"no event": {
    39  			srcEvents: []sdk.Event{},
    40  			exp:       false,
    41  		},
    42  	}
    43  	for name, spec := range specs {
    44  		t.Run(name, func(t *testing.T) {
    45  			em := sdk.NewEventManager()
    46  			em.EmitEvents(spec.srcEvents)
    47  			ctx := sdk.Context{}
    48  			ctx.SetContext(context.Background())
    49  			ctx.SetEventManager(em)
    50  
    51  			got := hasWasmModuleEvent(ctx, myContractAddr)
    52  			assert.Equal(t, spec.exp, got)
    53  		})
    54  	}
    55  }
    56  
    57  func TestNewCustomEvents(t *testing.T) {
    58  	myContract := RandomAccountAddress(t)
    59  	specs := map[string]struct {
    60  		src     wasmvmtypes.Events
    61  		exp     sdk.Events
    62  		isError bool
    63  	}{
    64  		"all good": {
    65  			src: wasmvmtypes.Events{{
    66  				Type:       "foo",
    67  				Attributes: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"}},
    68  			}},
    69  			exp: sdk.Events{sdk.NewEvent("wasm-foo",
    70  				sdk.NewAttribute("_contract_address", myContract.String()),
    71  				sdk.NewAttribute("myKey", "myVal"))},
    72  		},
    73  		"multiple attributes": {
    74  			src: wasmvmtypes.Events{{
    75  				Type: "foo",
    76  				Attributes: []wasmvmtypes.EventAttribute{
    77  					{Key: "myKey", Value: "myVal"},
    78  					{Key: "myOtherKey", Value: "myOtherVal"},
    79  				},
    80  			}},
    81  			exp: sdk.Events{sdk.NewEvent("wasm-foo",
    82  				sdk.NewAttribute("_contract_address", myContract.String()),
    83  				sdk.NewAttribute("myKey", "myVal"),
    84  				sdk.NewAttribute("myOtherKey", "myOtherVal"))},
    85  		},
    86  		"multiple events": {
    87  			src: wasmvmtypes.Events{{
    88  				Type:       "foo",
    89  				Attributes: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"}},
    90  			}, {
    91  				Type:       "bar",
    92  				Attributes: []wasmvmtypes.EventAttribute{{Key: "otherKey", Value: "otherVal"}},
    93  			}},
    94  			exp: sdk.Events{
    95  				sdk.NewEvent("wasm-foo",
    96  					sdk.NewAttribute("_contract_address", myContract.String()),
    97  					sdk.NewAttribute("myKey", "myVal")),
    98  				sdk.NewEvent("wasm-bar",
    99  					sdk.NewAttribute("_contract_address", myContract.String()),
   100  					sdk.NewAttribute("otherKey", "otherVal")),
   101  			},
   102  		},
   103  		"without attributes": {
   104  			src: wasmvmtypes.Events{{
   105  				Type: "foo",
   106  			}},
   107  			exp: sdk.Events{sdk.NewEvent("wasm-foo",
   108  				sdk.NewAttribute("_contract_address", myContract.String()))},
   109  		},
   110  		"error on short event type": {
   111  			src: wasmvmtypes.Events{{
   112  				Type: "f",
   113  			}},
   114  			isError: true,
   115  		},
   116  		"error on _contract_address": {
   117  			src: wasmvmtypes.Events{{
   118  				Type:       "foo",
   119  				Attributes: []wasmvmtypes.EventAttribute{{Key: "_contract_address", Value: RandomBech32AccountAddress(t)}},
   120  			}},
   121  			isError: true,
   122  		},
   123  		"error on reserved prefix": {
   124  			src: wasmvmtypes.Events{{
   125  				Type: "wasm",
   126  				Attributes: []wasmvmtypes.EventAttribute{
   127  					{Key: "_reserved", Value: "is skipped"},
   128  					{Key: "normal", Value: "is used"},
   129  				},
   130  			}},
   131  			isError: true,
   132  		},
   133  		"error on empty value": {
   134  			src: wasmvmtypes.Events{{
   135  				Type: "boom",
   136  				Attributes: []wasmvmtypes.EventAttribute{
   137  					{Key: "some", Value: "data"},
   138  					{Key: "key", Value: ""},
   139  				},
   140  			}},
   141  			isError: true,
   142  		},
   143  		"error on empty key": {
   144  			src: wasmvmtypes.Events{{
   145  				Type: "boom",
   146  				Attributes: []wasmvmtypes.EventAttribute{
   147  					{Key: "some", Value: "data"},
   148  					{Key: "", Value: "value"},
   149  				},
   150  			}},
   151  			isError: true,
   152  		},
   153  		"error on whitespace type": {
   154  			src: wasmvmtypes.Events{{
   155  				Type: "    f   ",
   156  				Attributes: []wasmvmtypes.EventAttribute{
   157  					{Key: "some", Value: "data"},
   158  				},
   159  			}},
   160  			isError: true,
   161  		},
   162  		"error on only whitespace key": {
   163  			src: wasmvmtypes.Events{{
   164  				Type: "boom",
   165  				Attributes: []wasmvmtypes.EventAttribute{
   166  					{Key: "some", Value: "data"},
   167  					{Key: "\n\n\n\n", Value: "value"},
   168  				},
   169  			}},
   170  			isError: true,
   171  		},
   172  		"error on only whitespace value": {
   173  			src: wasmvmtypes.Events{{
   174  				Type: "boom",
   175  				Attributes: []wasmvmtypes.EventAttribute{
   176  					{Key: "some", Value: "data"},
   177  					{Key: "myKey", Value: " \t\r\n"},
   178  				},
   179  			}},
   180  			isError: true,
   181  		},
   182  		"strip out whitespace": {
   183  			src: wasmvmtypes.Events{{
   184  				Type:       "  food\n",
   185  				Attributes: []wasmvmtypes.EventAttribute{{Key: "my Key", Value: "\tmyVal"}},
   186  			}},
   187  			exp: sdk.Events{sdk.NewEvent("wasm-food",
   188  				sdk.NewAttribute("_contract_address", myContract.String()),
   189  				sdk.NewAttribute("my Key", "myVal"))},
   190  		},
   191  		"empty event elements": {
   192  			src:     make(wasmvmtypes.Events, 10),
   193  			isError: true,
   194  		},
   195  		"nil": {
   196  			exp: sdk.Events{},
   197  		},
   198  	}
   199  	for name, spec := range specs {
   200  		t.Run(name, func(t *testing.T) {
   201  			gotEvent, err := newCustomEvents(spec.src, myContract)
   202  			if spec.isError {
   203  				assert.Error(t, err)
   204  			} else {
   205  				assert.NoError(t, err)
   206  				assert.Equal(t, spec.exp, gotEvent)
   207  			}
   208  		})
   209  	}
   210  }
   211  
   212  func TestNewWasmModuleEvent(t *testing.T) {
   213  	myContract := RandomAccountAddress(t)
   214  	specs := map[string]struct {
   215  		src     []wasmvmtypes.EventAttribute
   216  		exp     sdk.Events
   217  		isError bool
   218  	}{
   219  		"all good": {
   220  			src: []wasmvmtypes.EventAttribute{{Key: "myKey", Value: "myVal"}},
   221  			exp: sdk.Events{sdk.NewEvent("wasm",
   222  				sdk.NewAttribute("_contract_address", myContract.String()),
   223  				sdk.NewAttribute("myKey", "myVal"))},
   224  		},
   225  		"multiple attributes": {
   226  			src: []wasmvmtypes.EventAttribute{
   227  				{Key: "myKey", Value: "myVal"},
   228  				{Key: "myOtherKey", Value: "myOtherVal"},
   229  			},
   230  			exp: sdk.Events{sdk.NewEvent("wasm",
   231  				sdk.NewAttribute("_contract_address", myContract.String()),
   232  				sdk.NewAttribute("myKey", "myVal"),
   233  				sdk.NewAttribute("myOtherKey", "myOtherVal"))},
   234  		},
   235  		"without attributes": {
   236  			exp: sdk.Events{sdk.NewEvent("wasm",
   237  				sdk.NewAttribute("_contract_address", myContract.String()))},
   238  		},
   239  		"error on _contract_address": {
   240  			src:     []wasmvmtypes.EventAttribute{{Key: "_contract_address", Value: RandomBech32AccountAddress(t)}},
   241  			isError: true,
   242  		},
   243  		"error on whitespace key": {
   244  			src:     []wasmvmtypes.EventAttribute{{Key: "  ", Value: "value"}},
   245  			isError: true,
   246  		},
   247  		"error on whitespace value": {
   248  			src:     []wasmvmtypes.EventAttribute{{Key: "key", Value: "\n\n\n"}},
   249  			isError: true,
   250  		},
   251  		"strip whitespace": {
   252  			src: []wasmvmtypes.EventAttribute{{Key: "   my-real-key    ", Value: "\n\n\nsome-val\t\t\t"}},
   253  			exp: sdk.Events{sdk.NewEvent("wasm",
   254  				sdk.NewAttribute("_contract_address", myContract.String()),
   255  				sdk.NewAttribute("my-real-key", "some-val"))},
   256  		},
   257  		"empty elements": {
   258  			src:     make([]wasmvmtypes.EventAttribute, 10),
   259  			isError: true,
   260  		},
   261  		"nil": {
   262  			exp: sdk.Events{sdk.NewEvent("wasm",
   263  				sdk.NewAttribute("_contract_address", myContract.String()),
   264  			)},
   265  		},
   266  	}
   267  	for name, spec := range specs {
   268  		t.Run(name, func(t *testing.T) {
   269  			gotEvent, err := newWasmModuleEvent(spec.src, myContract)
   270  			if spec.isError {
   271  				assert.Error(t, err)
   272  			} else {
   273  				assert.NoError(t, err)
   274  				assert.Equal(t, spec.exp, gotEvent)
   275  			}
   276  		})
   277  	}
   278  }
   279  
   280  // returns true when a wasm module event was emitted for this contract already
   281  func hasWasmModuleEvent(ctx sdk.Context, contractAddr sdk.AccAddress) bool {
   282  	for _, e := range ctx.EventManager().Events() {
   283  		if e.Type == types.WasmModuleEventType {
   284  			for _, a := range e.Attributes {
   285  				if string(a.Key) == types.AttributeKeyContractAddr && string(a.Value) == contractAddr.String() {
   286  					return true
   287  				}
   288  			}
   289  		}
   290  	}
   291  	return false
   292  }