From fc14fa0e87112d97bed7b2eafe86fbd01ed389c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Espino=20Garc=C3=ADa?= Date: Tue, 17 Jun 2025 08:16:06 +0200 Subject: [PATCH] Fix getAllChannels api not returning DMs/GMs (#31362) Automatic Merge --- .../channels/store/sqlstore/channel_store.go | 16 +++-- .../channels/store/storetest/channel_store.go | 66 +++++++++++-------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/server/channels/store/sqlstore/channel_store.go b/server/channels/store/sqlstore/channel_store.go index 2cb28ef352d..1fe216ea60b 100644 --- a/server/channels/store/sqlstore/channel_store.go +++ b/server/channels/store/sqlstore/channel_store.go @@ -1143,13 +1143,11 @@ func (s SqlChannelStore) GetChannels(teamId string, userId string, opts *model.C func (s SqlChannelStore) GetChannelsByUser(userId string, includeDeleted bool, lastDeleteAt, pageSize int, fromChannelID string) (model.ChannelList, error) { query := s.getQueryBuilder(). Select(channelSliceColumns(true, "Channels")...). - From("Channels, ChannelMembers, Teams"). + From("Channels"). + InnerJoin("ChannelMembers ON (Channels.Id = ChannelMembers.ChannelId)"). + LeftJoin("Teams ON (Channels.TeamId = Teams.Id)"). Where( - sq.And{ - sq.Expr("Channels.Id = ChannelMembers.ChannelId"), - sq.Expr("Channels.TeamId = Teams.Id"), - sq.Eq{"ChannelMembers.UserId": userId}, - }, + sq.Eq{"ChannelMembers.UserId": userId}, ). OrderBy("Channels.Id ASC") @@ -1170,6 +1168,7 @@ func (s SqlChannelStore) GetChannelsByUser(userId string, includeDeleted bool, l sq.GtOrEq{"Channels.DeleteAt": lastDeleteAt}, }, sq.Or{ + sq.Eq{"Teams.Id": nil}, sq.Eq{"Teams.DeleteAt": 0}, sq.GtOrEq{"Teams.DeleteAt": lastDeleteAt}, }, @@ -1180,7 +1179,10 @@ func (s SqlChannelStore) GetChannelsByUser(userId string, includeDeleted bool, l // Don't include archived channels or channels from deleted teams query = query.Where(sq.And{ sq.Eq{"Channels.DeleteAt": 0}, - sq.Eq{"Teams.DeleteAt": 0}, + sq.Or{ + sq.Eq{"Teams.DeleteAt": 0}, + sq.Eq{"Teams.Id": nil}, + }, }) } diff --git a/server/channels/store/storetest/channel_store.go b/server/channels/store/storetest/channel_store.go index 0adf50b341e..36b1f4125b1 100644 --- a/server/channels/store/storetest/channel_store.go +++ b/server/channels/store/storetest/channel_store.go @@ -3882,6 +3882,7 @@ func testChannelStoreGetChannels(t *testing.T, rctx request.CTX, ss store.Store) } func testChannelStoreGetChannelsByUser(t *testing.T, rctx request.CTX, ss store.Store) { + userID := model.NewId() team := &model.Team{ DisplayName: "Team1", Name: NewTestID(), @@ -3922,9 +3923,12 @@ func testChannelStoreGetChannelsByUser(t *testing.T, rctx request.CTX, ss store. _, nErr = ss.Channel().Save(rctx, &o3, -1) require.NoError(t, nErr) + o4, nErr := ss.Channel().CreateDirectChannel(rctx, &model.User{Id: userID}, &model.User{Id: model.NewId()}) + require.NoError(t, nErr) + m1 := model.ChannelMember{} m1.ChannelId = o1.Id - m1.UserId = model.NewId() + m1.UserId = userID m1.NotifyProps = model.GetDefaultChannelNotifyProps() _, err = ss.Channel().SaveMember(rctx, &m1) require.NoError(t, err) @@ -3938,22 +3942,25 @@ func testChannelStoreGetChannelsByUser(t *testing.T, rctx request.CTX, ss store. m3 := model.ChannelMember{} m3.ChannelId = o2.Id - m3.UserId = m1.UserId + m3.UserId = userID m3.NotifyProps = model.GetDefaultChannelNotifyProps() _, err = ss.Channel().SaveMember(rctx, &m3) require.NoError(t, err) m4 := model.ChannelMember{} m4.ChannelId = o3.Id - m4.UserId = m1.UserId + m4.UserId = userID m4.NotifyProps = model.GetDefaultChannelNotifyProps() _, err = ss.Channel().SaveMember(rctx, &m4) require.NoError(t, err) - list, nErr := ss.Channel().GetChannelsByUser(m1.UserId, false, 0, -1, "") + // No need to save member for direct channel + // since create direct channel already saves the members + + list, nErr := ss.Channel().GetChannelsByUser(userID, false, 0, -1, "") require.NoError(t, nErr) - require.Len(t, list, 3) - require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id}, []string{list[0].Id, list[1].Id, list[2].Id}, "channels did not match") + require.Len(t, list, 4) + require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id, o4.Id}, []string{list[0].Id, list[1].Id, list[2].Id, list[3].Id}, "channels did not match") nErr = ss.Channel().Delete(o2.Id, 10) require.NoError(t, nErr) @@ -3962,36 +3969,39 @@ func testChannelStoreGetChannelsByUser(t *testing.T, rctx request.CTX, ss store. require.NoError(t, nErr) // should return 1 - list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, false, 0, -1, "") - require.NoError(t, nErr) - require.Len(t, list, 1) - require.Equal(t, o1.Id, list[0].Id, "missing channel") - - // Should return all - list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, true, 0, -1, "") - require.NoError(t, nErr) - require.Len(t, list, 3) - require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id}, []string{list[0].Id, list[1].Id, list[2].Id}, "channels did not match") - - // Should still return all - list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, true, 10, -1, "") - require.NoError(t, nErr) - require.Len(t, list, 3) - require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id}, []string{list[0].Id, list[1].Id, list[2].Id}, "channels did not match") - - // Should return 2 - list, nErr = ss.Channel().GetChannelsByUser(m1.UserId, true, 20, -1, "") + list, nErr = ss.Channel().GetChannelsByUser(userID, false, 0, -1, "") require.NoError(t, nErr) require.Len(t, list, 2) - require.ElementsMatch(t, []string{o1.Id, o3.Id}, []string{list[0].Id, list[1].Id}, "channels did not match") + require.ElementsMatch(t, []string{o1.Id, o4.Id}, []string{list[0].Id, list[1].Id}, "channels did not match") - // Archive team and verify channels don't show up + // Should return all + list, nErr = ss.Channel().GetChannelsByUser(userID, true, 0, -1, "") + require.NoError(t, nErr) + require.Len(t, list, 4) + require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id, o4.Id}, []string{list[0].Id, list[1].Id, list[2].Id, list[3].Id}, "channels did not match") + + // Should still return all + list, nErr = ss.Channel().GetChannelsByUser(userID, true, 10, -1, "") + require.NoError(t, nErr) + require.Len(t, list, 4) + require.ElementsMatch(t, []string{o1.Id, o2.Id, o3.Id, o4.Id}, []string{list[0].Id, list[1].Id, list[2].Id, list[3].Id}, "channels did not match") + + // Should return 2 + list, nErr = ss.Channel().GetChannelsByUser(userID, true, 20, -1, "") + require.NoError(t, nErr) + require.Len(t, list, 3) + require.ElementsMatch(t, []string{o1.Id, o3.Id, o4.Id}, []string{list[0].Id, list[1].Id, list[2].Id}, "channels did not match") + + // Archive team and delete DM and verify channels don't show up team.DeleteAt = model.GetMillis() _, nErr = ss.Team().Update(team) require.NoError(t, nErr) + nErr = ss.Channel().Delete(o4.Id, 30) + require.NoError(t, nErr) + // Should return an error since team is archived and there are no results - _, nErr = ss.Channel().GetChannelsByUser(m1.UserId, false, 0, -1, "") + _, nErr = ss.Channel().GetChannelsByUser(userID, false, 0, -1, "") require.Error(t, nErr) }