github.com/cosmos/cosmos-sdk@v0.50.10/types/events_test.go (about)

     1  package types_test
     2  
     3  import (
     4  	"encoding/json"
     5  	"reflect"
     6  	"testing"
     7  
     8  	abci "github.com/cometbft/cometbft/abci/types"
     9  	"github.com/stretchr/testify/suite"
    10  
    11  	"cosmossdk.io/math"
    12  
    13  	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    14  	testdata "github.com/cosmos/cosmos-sdk/testutil/testdata"
    15  	sdk "github.com/cosmos/cosmos-sdk/types"
    16  )
    17  
    18  type eventsTestSuite struct {
    19  	suite.Suite
    20  }
    21  
    22  func TestEventsTestSuite(t *testing.T) {
    23  	suite.Run(t, new(eventsTestSuite))
    24  }
    25  
    26  func (s *eventsTestSuite) TestAppendEvents() {
    27  	e1 := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))
    28  	e2 := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "bar"))
    29  	a := sdk.Events{e1}
    30  	b := sdk.Events{e2}
    31  	c := a.AppendEvents(b)
    32  	s.Require().Equal(c, sdk.Events{e1, e2})
    33  	s.Require().Equal(c, sdk.Events{e1}.AppendEvent(sdk.NewEvent("transfer", sdk.NewAttribute("sender", "bar"))))
    34  	s.Require().Equal(c, sdk.Events{e1}.AppendEvents(sdk.Events{e2}))
    35  }
    36  
    37  func (s *eventsTestSuite) TestAppendAttributes() {
    38  	e := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))
    39  	e = e.AppendAttributes(sdk.NewAttribute("recipient", "bar"))
    40  	s.Require().Len(e.Attributes, 2)
    41  	s.Require().Equal(e, sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"), sdk.NewAttribute("recipient", "bar")))
    42  }
    43  
    44  func (s *eventsTestSuite) TestGetAttributes() {
    45  	e := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))
    46  	e = e.AppendAttributes(sdk.NewAttribute("recipient", "bar"))
    47  	attr, found := e.GetAttribute("recipient")
    48  	s.Require().True(found)
    49  	s.Require().Equal(attr, sdk.NewAttribute("recipient", "bar"))
    50  	_, found = e.GetAttribute("foo")
    51  	s.Require().False(found)
    52  
    53  	events := sdk.Events{e}.AppendEvent(sdk.NewEvent("message", sdk.NewAttribute("sender", "bar")))
    54  	attrs, found := events.GetAttributes("sender")
    55  	s.Require().True(found)
    56  	s.Require().Len(attrs, 2)
    57  	s.Require().Equal(attrs[0], sdk.NewAttribute("sender", "foo"))
    58  	s.Require().Equal(attrs[1], sdk.NewAttribute("sender", "bar"))
    59  	_, found = events.GetAttributes("foo")
    60  	s.Require().False(found)
    61  }
    62  
    63  func (s *eventsTestSuite) TestEmptyEvents() {
    64  	s.Require().Equal(sdk.EmptyEvents(), sdk.Events{})
    65  }
    66  
    67  func (s *eventsTestSuite) TestAttributeString() {
    68  	s.Require().Equal("foo: bar", sdk.NewAttribute("foo", "bar").String())
    69  }
    70  
    71  func (s *eventsTestSuite) TestToABCIEvents() {
    72  	e := sdk.Events{sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))}
    73  	abciEvents := e.ToABCIEvents()
    74  	s.Require().Len(abciEvents, 1)
    75  	s.Require().Equal(abciEvents[0].Type, e[0].Type)
    76  	s.Require().Equal(abciEvents[0].Attributes, e[0].Attributes)
    77  }
    78  
    79  func (s *eventsTestSuite) TestEventManager() {
    80  	em := sdk.NewEventManager()
    81  	event := sdk.NewEvent("reward", sdk.NewAttribute("x", "y"))
    82  	events := sdk.Events{sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))}
    83  
    84  	em.EmitEvents(events)
    85  	em.EmitEvent(event)
    86  
    87  	s.Require().Len(em.Events(), 2)
    88  	s.Require().Equal(em.Events(), events.AppendEvent(event))
    89  }
    90  
    91  func (s *eventsTestSuite) TestEmitTypedEvent() {
    92  	s.Run("deterministic key-value order", func() {
    93  		for i := 0; i < 10; i++ {
    94  			em := sdk.NewEventManager()
    95  			coin := sdk.NewCoin("fakedenom", math.NewInt(1999999))
    96  			s.Require().NoError(em.EmitTypedEvent(&coin))
    97  			s.Require().Len(em.Events(), 1)
    98  			attrs := em.Events()[0].Attributes
    99  			s.Require().Len(attrs, 2)
   100  			s.Require().Equal(attrs[0].Key, "amount")
   101  			s.Require().Equal(attrs[1].Key, "denom")
   102  		}
   103  	})
   104  }
   105  
   106  func (s *eventsTestSuite) TestEventManagerTypedEvents() {
   107  	em := sdk.NewEventManager()
   108  
   109  	coin := sdk.NewCoin("fakedenom", math.NewInt(1999999))
   110  	cat := testdata.Cat{
   111  		Moniker: "Garfield",
   112  		Lives:   6,
   113  	}
   114  	animal, err := codectypes.NewAnyWithValue(&cat)
   115  	s.Require().NoError(err)
   116  	hasAnimal := testdata.HasAnimal{
   117  		X:      1000,
   118  		Animal: animal,
   119  	}
   120  
   121  	s.Require().NoError(em.EmitTypedEvents(&coin))
   122  	s.Require().NoError(em.EmitTypedEvent(&hasAnimal))
   123  	s.Require().Len(em.Events(), 2)
   124  
   125  	msg1, err := sdk.ParseTypedEvent(em.Events().ToABCIEvents()[0])
   126  	s.Require().NoError(err)
   127  	s.Require().Equal(coin.String(), msg1.String())
   128  	s.Require().Equal(reflect.TypeOf(&coin), reflect.TypeOf(msg1))
   129  
   130  	msg2, err := sdk.ParseTypedEvent(em.Events().ToABCIEvents()[1])
   131  	s.Require().NoError(err)
   132  	s.Require().Equal(reflect.TypeOf(&hasAnimal), reflect.TypeOf(msg2))
   133  	response := msg2.(*testdata.HasAnimal)
   134  	s.Require().Equal(hasAnimal.Animal.String(), response.Animal.String())
   135  }
   136  
   137  func (s *eventsTestSuite) TestStringifyEvents() {
   138  	cases := []struct {
   139  		name       string
   140  		events     sdk.Events
   141  		expTxtStr  string
   142  		expJSONStr string
   143  	}{
   144  		{
   145  			name: "default",
   146  			events: sdk.Events{
   147  				sdk.NewEvent("message", sdk.NewAttribute(sdk.AttributeKeySender, "foo")),
   148  				sdk.NewEvent("message", sdk.NewAttribute(sdk.AttributeKeyModule, "bank")),
   149  			},
   150  			expTxtStr:  "\t\t- message\n\t\t\t- sender: foo\n\t\t- message\n\t\t\t- module: bank",
   151  			expJSONStr: "[{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"foo\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"module\",\"value\":\"bank\"}]}]",
   152  		},
   153  		{
   154  			name: "multiple events with same attributes",
   155  			events: sdk.Events{
   156  				sdk.NewEvent(
   157  					"message",
   158  					sdk.NewAttribute(sdk.AttributeKeyModule, "staking"),
   159  					sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1foo"),
   160  				),
   161  				sdk.NewEvent("message", sdk.NewAttribute(sdk.AttributeKeySender, "foo")),
   162  			},
   163  			expTxtStr:  "\t\t- message\n\t\t\t- module: staking\n\t\t\t- sender: cosmos1foo\n\t\t- message\n\t\t\t- sender: foo",
   164  			expJSONStr: `[{"type":"message","attributes":[{"key":"module","value":"staking"},{"key":"sender","value":"cosmos1foo"}]},{"type":"message","attributes":[{"key":"sender","value":"foo"}]}]`,
   165  		},
   166  	}
   167  
   168  	for _, test := range cases {
   169  		se := sdk.StringifyEvents(test.events.ToABCIEvents())
   170  		s.Require().Equal(test.expTxtStr, se.String())
   171  		bz, err := json.Marshal(se)
   172  		s.Require().NoError(err)
   173  		s.Require().Equal(test.expJSONStr, string(bz))
   174  	}
   175  }
   176  
   177  func (s *eventsTestSuite) TestMarkEventsToIndex() {
   178  	events := []abci.Event{
   179  		{
   180  			Type: "message",
   181  			Attributes: []abci.EventAttribute{
   182  				{Key: "sender", Value: "foo"},
   183  				{Key: "recipient", Value: "bar"},
   184  			},
   185  		},
   186  		{
   187  			Type: "staking",
   188  			Attributes: []abci.EventAttribute{
   189  				{Key: "deposit", Value: "5"},
   190  				{Key: "unbond", Value: "10"},
   191  			},
   192  		},
   193  	}
   194  
   195  	testCases := map[string]struct {
   196  		events   []abci.Event
   197  		indexSet map[string]struct{}
   198  		expected []abci.Event
   199  	}{
   200  		"empty index set": {
   201  			events: events,
   202  			expected: []abci.Event{
   203  				{
   204  					Type: "message",
   205  					Attributes: []abci.EventAttribute{
   206  						{Key: "sender", Value: "foo", Index: true},
   207  						{Key: "recipient", Value: "bar", Index: true},
   208  					},
   209  				},
   210  				{
   211  					Type: "staking",
   212  					Attributes: []abci.EventAttribute{
   213  						{Key: "deposit", Value: "5", Index: true},
   214  						{Key: "unbond", Value: "10", Index: true},
   215  					},
   216  				},
   217  			},
   218  			indexSet: map[string]struct{}{},
   219  		},
   220  		"index some events": {
   221  			events: events,
   222  			expected: []abci.Event{
   223  				{
   224  					Type: "message",
   225  					Attributes: []abci.EventAttribute{
   226  						{Key: "sender", Value: "foo", Index: true},
   227  						{Key: "recipient", Value: "bar"},
   228  					},
   229  				},
   230  				{
   231  					Type: "staking",
   232  					Attributes: []abci.EventAttribute{
   233  						{Key: "deposit", Value: "5", Index: true},
   234  						{Key: "unbond", Value: "10"},
   235  					},
   236  				},
   237  			},
   238  			indexSet: map[string]struct{}{
   239  				"message.sender":  {},
   240  				"staking.deposit": {},
   241  			},
   242  		},
   243  		"index all events": {
   244  			events: events,
   245  			expected: []abci.Event{
   246  				{
   247  					Type: "message",
   248  					Attributes: []abci.EventAttribute{
   249  						{Key: "sender", Value: "foo", Index: true},
   250  						{Key: "recipient", Value: "bar", Index: true},
   251  					},
   252  				},
   253  				{
   254  					Type: "staking",
   255  					Attributes: []abci.EventAttribute{
   256  						{Key: "deposit", Value: "5", Index: true},
   257  						{Key: "unbond", Value: "10", Index: true},
   258  					},
   259  				},
   260  			},
   261  			indexSet: map[string]struct{}{
   262  				"message.sender":    {},
   263  				"message.recipient": {},
   264  				"staking.deposit":   {},
   265  				"staking.unbond":    {},
   266  			},
   267  		},
   268  	}
   269  
   270  	for name, tc := range testCases {
   271  		tc := tc
   272  		s.T().Run(name, func(_ *testing.T) {
   273  			s.Require().Equal(tc.expected, sdk.MarkEventsToIndex(tc.events, tc.indexSet))
   274  		})
   275  	}
   276  }