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 }