fix: self-contact related flaky tests (#4312)
This commit is contained in:
parent
57e370e7b9
commit
010afb4b39
|
@ -126,6 +126,7 @@ type Messenger struct {
|
||||||
systemMessagesTranslations *systemMessageTranslationsMap
|
systemMessagesTranslations *systemMessageTranslationsMap
|
||||||
allChats *chatMap
|
allChats *chatMap
|
||||||
selfContact *Contact
|
selfContact *Contact
|
||||||
|
selfContactSubscriptions []chan *SelfContactChangeEvent
|
||||||
allContacts *contactMap
|
allContacts *contactMap
|
||||||
allInstallations *installationMap
|
allInstallations *installationMap
|
||||||
modifiedInstallations *stringBoolMap
|
modifiedInstallations *stringBoolMap
|
||||||
|
@ -1592,6 +1593,7 @@ func (m *Messenger) watchIdentityImageChanges() {
|
||||||
identityImagesMap[img.Name] = *img
|
identityImagesMap[img.Name] = *img
|
||||||
}
|
}
|
||||||
m.selfContact.Images = identityImagesMap
|
m.selfContact.Images = identityImagesMap
|
||||||
|
m.publishSelfContactSubscriptions(&SelfContactChangeEvent{ImagesChanged: true})
|
||||||
|
|
||||||
if change.PublishExpected {
|
if change.PublishExpected {
|
||||||
err = m.syncProfilePictures(m.dispatchMessage, identityImages)
|
err = m.syncProfilePictures(m.dispatchMessage, identityImages)
|
||||||
|
|
|
@ -10,6 +10,8 @@ import (
|
||||||
"github.com/golang/protobuf/proto"
|
"github.com/golang/protobuf/proto"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
|
"github.com/ethereum/go-ethereum/log"
|
||||||
|
|
||||||
"github.com/status-im/status-go/deprecation"
|
"github.com/status-im/status-go/deprecation"
|
||||||
"github.com/status-im/status-go/eth-node/crypto"
|
"github.com/status-im/status-go/eth-node/crypto"
|
||||||
"github.com/status-im/status-go/eth-node/types"
|
"github.com/status-im/status-go/eth-node/types"
|
||||||
|
@ -26,6 +28,14 @@ const incomingMutualStateEventSentDefaultText = "@%s sent you a contact request"
|
||||||
const incomingMutualStateEventAcceptedDefaultText = "@%s accepted your contact request"
|
const incomingMutualStateEventAcceptedDefaultText = "@%s accepted your contact request"
|
||||||
const incomingMutualStateEventRemovedDefaultText = "@%s removed you as a contact"
|
const incomingMutualStateEventRemovedDefaultText = "@%s removed you as a contact"
|
||||||
|
|
||||||
|
type SelfContactChangeEvent struct {
|
||||||
|
DisplayNameChanged bool
|
||||||
|
PreferredNameChanged bool
|
||||||
|
BioChanged bool
|
||||||
|
SocialLinksChanged bool
|
||||||
|
ImagesChanged bool
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) prepareMutualStateUpdateMessage(contactID string, updateType MutualStateUpdateType, clock uint64, timestamp uint64, outgoing bool) (*common.Message, error) {
|
func (m *Messenger) prepareMutualStateUpdateMessage(contactID string, updateType MutualStateUpdateType, clock uint64, timestamp uint64, outgoing bool) (*common.Message, error) {
|
||||||
var text string
|
var text string
|
||||||
var to string
|
var to string
|
||||||
|
@ -766,6 +776,10 @@ func (m *Messenger) GetContactByID(pubKey string) *Contact {
|
||||||
return contact
|
return contact
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) GetSelfContact() *Contact {
|
||||||
|
return m.selfContact
|
||||||
|
}
|
||||||
|
|
||||||
func (m *Messenger) SetContactLocalNickname(request *requests.SetContactLocalNickname) (*MessengerResponse, error) {
|
func (m *Messenger) SetContactLocalNickname(request *requests.SetContactLocalNickname) (*MessengerResponse, error) {
|
||||||
|
|
||||||
if err := request.Validate(); err != nil {
|
if err := request.Validate(); err != nil {
|
||||||
|
@ -1291,3 +1305,19 @@ func (m *Messenger) forgetContactInfoRequest(publicKey string) {
|
||||||
|
|
||||||
delete(m.requestedContacts, publicKey)
|
delete(m.requestedContacts, publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) SubscribeToSelfContactChanges() chan *SelfContactChangeEvent {
|
||||||
|
s := make(chan *SelfContactChangeEvent, 10)
|
||||||
|
m.selfContactSubscriptions = append(m.selfContactSubscriptions, s)
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *Messenger) publishSelfContactSubscriptions(event *SelfContactChangeEvent) {
|
||||||
|
for _, s := range m.selfContactSubscriptions {
|
||||||
|
select {
|
||||||
|
case s <- event:
|
||||||
|
default:
|
||||||
|
log.Warn("self contact subscription channel full, dropping message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,8 @@ func (s *MessengerContactsTestSuite) Test_SelfContact() {
|
||||||
|
|
||||||
// Set values stored in settings
|
// Set values stored in settings
|
||||||
|
|
||||||
settingsList := []string{settings.DisplayName.GetReactName(), settings.PreferredName.GetReactName(), settings.Bio.GetReactName()}
|
changesLatch := SelfContactChangeEvent{}
|
||||||
|
|
||||||
setSettingsValues := func() {
|
setSettingsValues := func() {
|
||||||
err := s.m.SetDisplayName(displayName)
|
err := s.m.SetDisplayName(displayName)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
@ -58,7 +59,20 @@ func (s *MessengerContactsTestSuite) Test_SelfContact() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
SetSettingsAndWaitForChange(&s.Suite, s.m, settingsList, timeout, setSettingsValues)
|
eventHandler := func(event *SelfContactChangeEvent) bool {
|
||||||
|
if event.DisplayNameChanged {
|
||||||
|
changesLatch.DisplayNameChanged = true
|
||||||
|
}
|
||||||
|
if event.BioChanged {
|
||||||
|
changesLatch.BioChanged = true
|
||||||
|
}
|
||||||
|
if event.PreferredNameChanged {
|
||||||
|
changesLatch.PreferredNameChanged = true
|
||||||
|
}
|
||||||
|
return changesLatch.DisplayNameChanged && changesLatch.BioChanged && changesLatch.PreferredNameChanged
|
||||||
|
}
|
||||||
|
|
||||||
|
SetSettingsAndWaitForChange(&s.Suite, s.m, timeout, setSettingsValues, eventHandler)
|
||||||
|
|
||||||
// Set values stored in multiaccounts
|
// Set values stored in multiaccounts
|
||||||
|
|
||||||
|
@ -67,7 +81,7 @@ func (s *MessengerContactsTestSuite) Test_SelfContact() {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
SetIdentityImagesAndWaitForChange(&s.Suite, s.m.multiAccounts, timeout, setIdentityImages)
|
SetIdentityImagesAndWaitForChange(&s.Suite, s.m, timeout, setIdentityImages)
|
||||||
|
|
||||||
// Set social links. They are applied immediately, no need to wait.
|
// Set social links. They are applied immediately, no need to wait.
|
||||||
|
|
||||||
|
|
|
@ -181,6 +181,9 @@ func (m *Messenger) AddOrReplaceSocialLinks(socialLinks identity.SocialLinks) er
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
m.selfContact.SocialLinks = socialLinks
|
m.selfContact.SocialLinks = socialLinks
|
||||||
|
m.publishSelfContactSubscriptions(&SelfContactChangeEvent{
|
||||||
|
SocialLinksChanged: true,
|
||||||
|
})
|
||||||
|
|
||||||
err = m.syncSocialLinks(context.Background(), m.dispatchMessage)
|
err = m.syncSocialLinks(context.Background(), m.dispatchMessage)
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -445,22 +445,38 @@ func (s *MessengerLinkPreviewsTestSuite) Test_UnfurlURLs_StatusContactAdded() {
|
||||||
func (s *MessengerLinkPreviewsTestSuite) setProfileParameters(messenger *Messenger, displayName string, bio string, identityImages []images.IdentityImage) {
|
func (s *MessengerLinkPreviewsTestSuite) setProfileParameters(messenger *Messenger, displayName string, bio string, identityImages []images.IdentityImage) {
|
||||||
const timeout = 1 * time.Second
|
const timeout = 1 * time.Second
|
||||||
|
|
||||||
settingsList := []string{
|
changes := SelfContactChangeEvent{}
|
||||||
settings.DisplayName.GetReactName(),
|
|
||||||
settings.Bio.GetReactName(),
|
|
||||||
}
|
|
||||||
|
|
||||||
SetSettingsAndWaitForChange(&s.Suite, messenger, settingsList, timeout, func() {
|
SetSettingsAndWaitForChange(&s.Suite, messenger, timeout, func() {
|
||||||
err := messenger.SetDisplayName(displayName)
|
err := messenger.SetDisplayName(displayName)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
err = messenger.SetBio(bio)
|
err = messenger.SetBio(bio)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
|
}, func(event *SelfContactChangeEvent) bool {
|
||||||
|
if event.DisplayNameChanged {
|
||||||
|
changes.DisplayNameChanged = true
|
||||||
|
}
|
||||||
|
if event.BioChanged {
|
||||||
|
changes.BioChanged = true
|
||||||
|
}
|
||||||
|
return changes.DisplayNameChanged && changes.BioChanged
|
||||||
})
|
})
|
||||||
|
|
||||||
SetIdentityImagesAndWaitForChange(&s.Suite, messenger.multiAccounts, timeout, func() {
|
SetIdentityImagesAndWaitForChange(&s.Suite, messenger, timeout, func() {
|
||||||
err := messenger.multiAccounts.StoreIdentityImages(messenger.account.KeyUID, identityImages, false)
|
err := messenger.multiAccounts.StoreIdentityImages(messenger.account.KeyUID, identityImages, false)
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
selfContact := messenger.GetSelfContact()
|
||||||
|
s.Require().Equal(selfContact.DisplayName, displayName)
|
||||||
|
s.Require().Equal(selfContact.Bio, bio)
|
||||||
|
|
||||||
|
for _, image := range identityImages {
|
||||||
|
saved, ok := selfContact.Images[image.Name]
|
||||||
|
s.Require().True(ok)
|
||||||
|
s.Require().Equal(saved, image)
|
||||||
|
}
|
||||||
|
s.Require().Equal(selfContact.DisplayName, displayName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *MessengerLinkPreviewsTestSuite) Test_UnfurlURLs_SelfLink() {
|
func (s *MessengerLinkPreviewsTestSuite) Test_UnfurlURLs_SelfLink() {
|
||||||
|
|
|
@ -169,10 +169,13 @@ func (m *Messenger) startSettingsChangesLoop() {
|
||||||
switch s.GetReactName() {
|
switch s.GetReactName() {
|
||||||
case settings.DisplayName.GetReactName():
|
case settings.DisplayName.GetReactName():
|
||||||
m.selfContact.DisplayName = s.Value.(string)
|
m.selfContact.DisplayName = s.Value.(string)
|
||||||
|
m.publishSelfContactSubscriptions(&SelfContactChangeEvent{DisplayNameChanged: true})
|
||||||
case settings.PreferredName.GetReactName():
|
case settings.PreferredName.GetReactName():
|
||||||
m.selfContact.EnsName = s.Value.(string)
|
m.selfContact.EnsName = s.Value.(string)
|
||||||
|
m.publishSelfContactSubscriptions(&SelfContactChangeEvent{PreferredNameChanged: true})
|
||||||
case settings.Bio.GetReactName():
|
case settings.Bio.GetReactName():
|
||||||
m.selfContact.Bio = s.Value.(string)
|
m.selfContact.Bio = s.Value.(string)
|
||||||
|
m.publishSelfContactSubscriptions(&SelfContactChangeEvent{BioChanged: true})
|
||||||
}
|
}
|
||||||
case <-m.quit:
|
case <-m.quit:
|
||||||
return
|
return
|
||||||
|
|
|
@ -8,7 +8,6 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/suite"
|
"github.com/stretchr/testify/suite"
|
||||||
|
|
||||||
"github.com/status-im/status-go/multiaccounts"
|
|
||||||
"github.com/status-im/status-go/protocol/common"
|
"github.com/status-im/status-go/protocol/common"
|
||||||
"github.com/status-im/status-go/protocol/protobuf"
|
"github.com/status-im/status-go/protocol/protobuf"
|
||||||
"github.com/status-im/status-go/protocol/tt"
|
"github.com/status-im/status-go/protocol/tt"
|
||||||
|
@ -135,43 +134,35 @@ func PairDevices(s *suite.Suite, device1, device2 *Messenger) {
|
||||||
s.Require().NoError(err)
|
s.Require().NoError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetSettingsAndWaitForChange(s *suite.Suite, messenger *Messenger, settingsReactNames []string, timeout time.Duration, actionCallback func()) {
|
func SetSettingsAndWaitForChange(s *suite.Suite, messenger *Messenger, timeout time.Duration,
|
||||||
changedSettings := map[string]struct{}{}
|
actionCallback func(), eventCallback func(*SelfContactChangeEvent) bool) {
|
||||||
wg := sync.WaitGroup{}
|
|
||||||
|
|
||||||
for _, reactName := range settingsReactNames {
|
allEventsReceived := false
|
||||||
wg.Add(1)
|
channel := messenger.SubscribeToSelfContactChanges()
|
||||||
settingReactName := reactName // Loop variables captured by 'func' literals in 'go' statements might have unexpected values
|
wg := sync.WaitGroup{}
|
||||||
channel := messenger.settings.SubscribeToChanges()
|
wg.Add(1)
|
||||||
go func() {
|
|
||||||
defer wg.Done()
|
go func() {
|
||||||
for {
|
defer wg.Done()
|
||||||
select {
|
for !allEventsReceived {
|
||||||
case setting := <-channel:
|
select {
|
||||||
if setting.GetReactName() == settingReactName {
|
case event := <-channel:
|
||||||
changedSettings[settingReactName] = struct{}{}
|
allEventsReceived = eventCallback(event)
|
||||||
return
|
case <-time.After(timeout):
|
||||||
}
|
return
|
||||||
case <-time.After(timeout):
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}()
|
}
|
||||||
}
|
}()
|
||||||
|
|
||||||
actionCallback()
|
actionCallback()
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
s.Require().Len(changedSettings, len(settingsReactNames))
|
|
||||||
|
|
||||||
for _, reactName := range settingsReactNames {
|
s.Require().True(allEventsReceived)
|
||||||
_, ok := changedSettings[reactName]
|
|
||||||
s.Require().True(ok)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetIdentityImagesAndWaitForChange(s *suite.Suite, multiAccounts *multiaccounts.Database, timeout time.Duration, actionCallback func()) {
|
func SetIdentityImagesAndWaitForChange(s *suite.Suite, messenger *Messenger, timeout time.Duration, actionCallback func()) {
|
||||||
channel := multiAccounts.SubscribeToIdentityImageChanges()
|
channel := messenger.SubscribeToSelfContactChanges()
|
||||||
ok := false
|
ok := false
|
||||||
wg := sync.WaitGroup{}
|
wg := sync.WaitGroup{}
|
||||||
wg.Add(1)
|
wg.Add(1)
|
||||||
|
@ -179,8 +170,10 @@ func SetIdentityImagesAndWaitForChange(s *suite.Suite, multiAccounts *multiaccou
|
||||||
go func() {
|
go func() {
|
||||||
defer wg.Done()
|
defer wg.Done()
|
||||||
select {
|
select {
|
||||||
case <-channel:
|
case event := <-channel:
|
||||||
ok = true
|
if event.ImagesChanged {
|
||||||
|
ok = true
|
||||||
|
}
|
||||||
case <-time.After(timeout):
|
case <-time.After(timeout):
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -189,5 +182,6 @@ func SetIdentityImagesAndWaitForChange(s *suite.Suite, multiAccounts *multiaccou
|
||||||
actionCallback()
|
actionCallback()
|
||||||
|
|
||||||
wg.Wait()
|
wg.Wait()
|
||||||
|
|
||||||
s.Require().True(ok)
|
s.Require().True(ok)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue