Ensure users status is set to offline when deactivated (#30900)

Этот коммит содержится в:
Daniel Espino García
2025-05-29 10:41:14 +02:00
коммит произвёл GitHub
родитель 79bf1c34db
Коммит 293f38ad0b
11 изменённых файлов: 141 добавлений и 16 удалений

Просмотреть файл

@@ -46,7 +46,7 @@ type mockSuite struct {
}
func (ms *mockSuite) SetStatusLastActivityAt(userID string, activityAt int64) {}
func (ms *mockSuite) SetStatusOffline(userID string, manual bool) {}
func (ms *mockSuite) SetStatusOffline(userID string, manual bool, force bool) {}
func (ms *mockSuite) IsUserAway(lastActivityAt int64) bool { return false }
func (ms *mockSuite) SetStatusOnline(userID string, manual bool) {}
func (ms *mockSuite) UpdateLastActivityAtIfNeeded(session model.Session) {}

Просмотреть файл

@@ -352,13 +352,13 @@ func (ps *PlatformService) SetStatusOnline(userID string, manual bool) {
}
}
func (ps *PlatformService) SetStatusOffline(userID string, manual bool) {
func (ps *PlatformService) SetStatusOffline(userID string, manual bool, force bool) {
if !*ps.Config().ServiceSettings.EnableUserStatuses {
return
}
status, err := ps.GetStatus(userID)
if err == nil && status.Manual && !manual {
if !force && err == nil && status.Manual && !manual {
return // manually set status always overrides non-manual one
}

Просмотреть файл

@@ -52,3 +52,128 @@ func TestTruncateDNDEndTime(t *testing.T) {
// 2025-Jan-20 at 00:00:10 GMT remains unchanged
assert.Equal(t, int64(1737331200), truncateDNDEndTime(1737331200))
}
func TestSetStatusOffline(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
user := th.BasicUser
t.Run("when user statuses are disabled", func(t *testing.T) {
th.Service.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.EnableUserStatuses = false
})
// Set initial status to online
status := &model.Status{
UserId: user.Id,
Status: model.StatusOnline,
}
th.Service.SaveAndBroadcastStatus(status)
// Try to set offline
th.Service.SetStatusOffline(user.Id, false, false)
// Enable user statuses to see what is really in the database
th.Service.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.EnableUserStatuses = true
})
// Status should remain unchanged
after, err := th.Service.GetStatus(user.Id)
require.Nil(t, err)
assert.Equal(t, model.StatusOnline, after.Status)
})
t.Run("when setting status manually over manually set status", func(t *testing.T) {
th.Service.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.EnableUserStatuses = true
})
// Set initial status to online manually
status := &model.Status{
UserId: user.Id,
Status: model.StatusOnline,
Manual: true,
}
th.Service.SaveAndBroadcastStatus(status)
// Try to set offline non-manually
th.Service.SetStatusOffline(user.Id, false, false)
// Status should remain unchanged because manual status takes precedence
after, err := th.Service.GetStatus(user.Id)
require.Nil(t, err)
assert.Equal(t, model.StatusOnline, after.Status)
assert.True(t, after.Manual)
})
t.Run("when force flag is true over manually set status", func(t *testing.T) {
th.Service.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.EnableUserStatuses = true
})
// Set initial status to online manually
status := &model.Status{
UserId: user.Id,
Status: model.StatusOnline,
Manual: true,
}
th.Service.SaveAndBroadcastStatus(status)
// Try to set offline with force flag
th.Service.SetStatusOffline(user.Id, false, true)
// Status should change despite being manual
after, err := th.Service.GetStatus(user.Id)
require.Nil(t, err)
assert.Equal(t, model.StatusOffline, after.Status)
assert.False(t, after.Manual)
})
t.Run("when setting status normally", func(t *testing.T) {
th.Service.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.EnableUserStatuses = true
})
// Set initial status to online
status := &model.Status{
UserId: user.Id,
Status: model.StatusOnline,
Manual: false,
}
th.Service.SaveAndBroadcastStatus(status)
// Set offline
th.Service.SetStatusOffline(user.Id, false, false)
// Status should change
after, err := th.Service.GetStatus(user.Id)
require.Nil(t, err)
assert.Equal(t, model.StatusOffline, after.Status)
assert.False(t, after.Manual)
})
t.Run("when setting status manually over normal status", func(t *testing.T) {
th.Service.UpdateConfig(func(cfg *model.Config) {
*cfg.ServiceSettings.EnableUserStatuses = true
})
// Set initial status to online
status := &model.Status{
UserId: user.Id,
Status: model.StatusOnline,
Manual: false,
}
th.Service.SaveAndBroadcastStatus(status)
// Set offline manually
th.Service.SetStatusOffline(user.Id, true, false)
// Status should change and be marked as manual
after, err := th.Service.GetStatus(user.Id)
require.Nil(t, err)
assert.Equal(t, model.StatusOffline, after.Status)
assert.True(t, after.Manual)
})
}

Просмотреть файл

@@ -580,7 +580,7 @@ func (h *Hub) Start() {
// Only set to offline if there are no
// active connections in other nodes as well.
if clusterCnt == 0 {
h.platform.SetStatusOffline(userID, false)
h.platform.SetStatusOffline(userID, false, false)
}
})
continue
@@ -704,7 +704,7 @@ func (h *Hub) Start() {
case <-h.stop:
for webConn := range connIndex.All() {
webConn.Close()
h.platform.SetStatusOffline(webConn.UserId, false)
h.platform.SetStatusOffline(webConn.UserId, false, false)
}
h.explicitStop = true