github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/chat/teamchannelsource_test.go (about) 1 package chat 2 3 import ( 4 "context" 5 "testing" 6 7 "github.com/keybase/client/go/chat/globals" 8 "github.com/keybase/client/go/kbtest" 9 "github.com/keybase/client/go/protocol/chat1" 10 "github.com/keybase/client/go/protocol/gregor1" 11 "github.com/keybase/client/go/protocol/keybase1" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestTeamChannelSource(t *testing.T) { 16 runWithMemberTypes(t, func(mt chat1.ConversationMembersType) { 17 // Only run this test for teams 18 switch mt { 19 case chat1.ConversationMembersType_TEAM: 20 default: 21 return 22 } 23 24 ctc := makeChatTestContext(t, "TestTeamChannelSource", 2) 25 defer ctc.cleanup() 26 users := ctc.users() 27 28 ctx1 := ctc.as(t, users[0]).startCtx 29 // ctx2 := ctc.as(t, users[1]).startCtx 30 listener1 := newServerChatListener() 31 ctc.as(t, users[0]).h.G().NotifyRouter.AddListener(listener1) 32 listener2 := newServerChatListener() 33 ctc.as(t, users[1]).h.G().NotifyRouter.AddListener(listener2) 34 ui := kbtest.NewChatUI() 35 ctc.as(t, users[0]).h.mockChatUI = ui 36 ctc.as(t, users[1]).h.mockChatUI = ui 37 ctc.world.Tcs[users[0].Username].ChatG.Syncer.(*Syncer).isConnected = true 38 ctc.world.Tcs[users[1].Username].ChatG.Syncer.(*Syncer).isConnected = true 39 uid1 := users[0].User.GetUID().ToBytes() 40 g1 := ctc.world.Tcs[users[0].Username].Context() 41 uid2 := users[1].User.GetUID().ToBytes() 42 g2 := ctc.world.Tcs[users[1].Username].Context() 43 t.Logf("uid1: %v, uid2: %v", users[0].User.GetUID(), users[1].User.GetUID()) 44 45 var tlfID chat1.TLFID 46 ctx := context.TODO() 47 48 type expectedResult struct { 49 ConvID chat1.ConversationID 50 Existence chat1.ConversationExistence 51 MemberStatus chat1.ConversationMemberStatus 52 TopicName string 53 } 54 55 // Verify all public functions of the team channel source return the expected results. 56 assertTeamChannelSource := func(g *globals.Context, uid gregor1.UID, expectedResults map[chat1.ConvIDStr]expectedResult) { 57 convs, err := g.TeamChannelSource.GetChannelsFull(ctx, uid, tlfID, chat1.TopicType_CHAT) 58 require.NoError(t, err) 59 require.Equal(t, len(expectedResults), len(convs)) 60 for _, conv := range convs { 61 expected, ok := expectedResults[conv.GetConvID().ConvIDStr()] 62 require.True(t, ok) 63 require.Equal(t, expected.ConvID, conv.GetConvID()) 64 require.Equal(t, expected.Existence, conv.Info.Existence) 65 require.Equal(t, expected.MemberStatus, conv.Info.MemberStatus) 66 } 67 68 mentions, err := g.TeamChannelSource.GetChannelsTopicName(ctx, uid, tlfID, chat1.TopicType_CHAT) 69 require.NoError(t, err) 70 require.Equal(t, len(expectedResults), len(mentions)) 71 for _, mention := range mentions { 72 expected, ok := expectedResults[mention.ConvID.ConvIDStr()] 73 require.True(t, ok) 74 require.Equal(t, expected.ConvID, mention.ConvID) 75 require.Equal(t, expected.TopicName, mention.TopicName) 76 } 77 78 for _, expected := range expectedResults { 79 topicName, err := g.TeamChannelSource.GetChannelTopicName(ctx, uid, tlfID, 80 chat1.TopicType_CHAT, expected.ConvID) 81 require.NoError(t, err) 82 require.Equal(t, expected.TopicName, topicName) 83 } 84 } 85 assertTeamChannelSource(g1, uid1, nil) 86 assertTeamChannelSource(g2, uid2, nil) 87 88 conv := mustCreateConversationForTest(t, ctc, users[0], chat1.TopicType_CHAT, mt, 89 ctc.as(t, users[1]).user()) 90 consumeNewConversation(t, listener1, conv.Id) 91 consumeNewConversation(t, listener2, conv.Id) 92 tlfID = conv.Triple.Tlfid 93 generalChannel := expectedResult{ 94 ConvID: conv.Id, 95 Existence: chat1.ConversationExistence_ACTIVE, 96 MemberStatus: chat1.ConversationMemberStatus_ACTIVE, 97 TopicName: "general", 98 } 99 // Both members can see the #general channel and are ACTIVE 100 expectedResults1 := map[chat1.ConvIDStr]expectedResult{conv.Id.ConvIDStr(): generalChannel} 101 expectedResults2 := map[chat1.ConvIDStr]expectedResult{conv.Id.ConvIDStr(): generalChannel} 102 assertTeamChannelSource(g1, uid1, expectedResults1) 103 assertTeamChannelSource(g2, uid2, expectedResults2) 104 105 topicName := "channel1" 106 channel1, err := ctc.as(t, users[0]).chatLocalHandler().NewConversationLocal(ctx, 107 chat1.NewConversationLocalArg{ 108 TlfName: conv.TlfName, 109 TopicName: &topicName, 110 TopicType: chat1.TopicType_CHAT, 111 TlfVisibility: keybase1.TLFVisibility_PRIVATE, 112 MembersType: chat1.ConversationMembersType_TEAM, 113 }) 114 require.NoError(t, err) 115 channelConvID := channel1.Conv.GetConvID() 116 consumeNewConversation(t, listener1, channelConvID) 117 assertNoNewConversation(t, listener2) 118 consumeNewMsgRemote(t, listener1, chat1.MessageType_JOIN) 119 consumeTeamType(t, listener1) 120 consumeTeamType(t, listener2) 121 consumeNewMsgRemote(t, listener1, chat1.MessageType_SYSTEM) 122 consumeNewMsgRemote(t, listener1, chat1.MessageType_SYSTEM) 123 consumeNewMsgRemote(t, listener2, chat1.MessageType_SYSTEM) 124 consumeNewMsgRemote(t, listener2, chat1.MessageType_SYSTEM) 125 t.Logf("created %v", topicName) 126 127 // Both members can see the #general channel and are ACTIVE 128 channel1User1 := expectedResult{ 129 ConvID: channelConvID, 130 Existence: chat1.ConversationExistence_ACTIVE, 131 MemberStatus: chat1.ConversationMemberStatus_ACTIVE, 132 TopicName: topicName, 133 } 134 expectedResults1[channelConvID.ConvIDStr()] = channel1User1 135 136 channel1User2 := expectedResult{ 137 ConvID: channelConvID, 138 Existence: chat1.ConversationExistence_ACTIVE, 139 MemberStatus: chat1.ConversationMemberStatus_NEVER_JOINED, 140 TopicName: topicName, 141 } 142 expectedResults2[channelConvID.ConvIDStr()] = channel1User2 143 assertTeamChannelSource(g1, uid1, expectedResults1) 144 assertTeamChannelSource(g2, uid2, expectedResults2) 145 146 // test rename 147 topicName = "channel1-renamed" 148 marg := chat1.PostMetadataNonblockArg{ 149 ConversationID: channelConvID, 150 TlfName: conv.TlfName, 151 TlfPublic: false, 152 ChannelName: topicName, 153 } 154 _, err = ctc.as(t, users[0]).chatLocalHandler().PostMetadataNonblock(ctx1, marg) 155 require.NoError(t, err) 156 consumeNewMsgRemote(t, listener1, chat1.MessageType_METADATA) 157 consumeNewMsgRemote(t, listener2, chat1.MessageType_METADATA) 158 t.Logf("renamed %v", topicName) 159 160 channel1User1.TopicName = topicName 161 channel1User2.TopicName = topicName 162 expectedResults1[channelConvID.ConvIDStr()] = channel1User1 163 expectedResults2[channelConvID.ConvIDStr()] = channel1User2 164 assertTeamChannelSource(g1, uid1, expectedResults1) 165 assertTeamChannelSource(g2, uid2, expectedResults2) 166 167 channel1User2.MemberStatus = chat1.ConversationMemberStatus_ACTIVE 168 expectedResults2[channelConvID.ConvIDStr()] = channel1User2 169 _, err = ctc.as(t, users[1]).chatLocalHandler().JoinConversationLocal(ctx1, chat1.JoinConversationLocalArg{ 170 TlfName: conv.TlfName, 171 TopicType: chat1.TopicType_CHAT, 172 Visibility: keybase1.TLFVisibility_PRIVATE, 173 TopicName: topicName, 174 }) 175 require.NoError(t, err) 176 consumeNewMsgRemote(t, listener1, chat1.MessageType_JOIN) 177 consumeNewMsgRemote(t, listener2, chat1.MessageType_JOIN) 178 assertTeamChannelSource(g1, uid1, expectedResults1) 179 assertTeamChannelSource(g2, uid2, expectedResults2) 180 181 _, err = ctc.as(t, users[0]).chatLocalHandler().DeleteConversationLocal(ctx1, 182 chat1.DeleteConversationLocalArg{ 183 ConvID: channelConvID, 184 }) 185 require.NoError(t, err) 186 consumeLeaveConv(t, listener1) 187 consumeTeamType(t, listener1) 188 delete(expectedResults1, channelConvID.ConvIDStr()) 189 delete(expectedResults2, channelConvID.ConvIDStr()) 190 assertTeamChannelSource(g1, uid1, expectedResults1) 191 assertTeamChannelSource(g2, uid2, expectedResults2) 192 193 updates := consumeNewThreadsStale(t, listener1) 194 require.Equal(t, 1, len(updates)) 195 require.Equal(t, channelConvID, updates[0].ConvID, "wrong cid") 196 require.Equal(t, chat1.StaleUpdateType_CLEAR, updates[0].UpdateType) 197 198 updates = consumeNewThreadsStale(t, listener2) 199 require.Equal(t, 1, len(updates)) 200 require.Equal(t, channelConvID, updates[0].ConvID, "wrong cid") 201 require.Equal(t, chat1.StaleUpdateType_CLEAR, updates[0].UpdateType) 202 }) 203 }