github.com/keybase/client/go@v0.0.0-20240309051027-028f7c731f8b/chat/replyto_test.go (about) 1 package chat 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/keybase/client/go/protocol/chat1" 8 "github.com/stretchr/testify/require" 9 ) 10 11 func TestChatReplyToBasic(t *testing.T) { 12 runWithMemberTypes(t, func(mt chat1.ConversationMembersType) { 13 ctc := makeChatTestContext(t, "ChatReplyTo", 1) 14 defer ctc.cleanup() 15 users := ctc.users() 16 17 ctx := ctc.as(t, users[0]).startCtx 18 timeout := 20 * time.Second 19 listener0 := newServerChatListener() 20 ctc.as(t, users[0]).h.G().NotifyRouter.AddListener(listener0) 21 t.Logf("uid0: %s", users[0].GetUID()) 22 23 conv := mustCreateConversationForTest(t, ctc, users[0], chat1.TopicType_CHAT, mt) 24 consumeNewConversation(t, listener0, conv.Id) 25 26 origID := mustPostLocalForTest(t, ctc, users[0], conv, 27 chat1.NewMessageBodyWithText(chat1.MessageText{ 28 Body: "MIKE", 29 })) 30 consumeNewMsgRemote(t, listener0, chat1.MessageType_TEXT) 31 consumeNewMsgLocal(t, listener0, chat1.MessageType_TEXT) 32 33 // reply 34 t.Logf("send reply") 35 postRes, err := ctc.as(t, users[0]).chatLocalHandler().PostLocal(ctx, chat1.PostLocalArg{ 36 ConversationID: conv.Id, 37 Msg: chat1.MessagePlaintext{ 38 ClientHeader: chat1.MessageClientHeader{ 39 Conv: conv.Triple, 40 MessageType: chat1.MessageType_TEXT, 41 TlfName: conv.TlfName, 42 }, 43 MessageBody: chat1.NewMessageBodyWithText(chat1.MessageText{ 44 Body: "REPLY", 45 }), 46 }, 47 ReplyTo: &origID, 48 }) 49 require.NoError(t, err) 50 51 // Check that we get the reply on notifications and fetches 52 select { 53 case note := <-listener0.newMessageLocal: 54 require.True(t, note.Message.IsValid()) 55 require.NotNil(t, note.Message.Valid().ReplyTo) 56 require.Equal(t, origID, note.Message.Valid().ReplyTo.GetMessageID()) 57 case <-time.After(timeout): 58 require.Fail(t, "no local") 59 } 60 select { 61 case note := <-listener0.newMessageRemote: 62 require.True(t, note.Message.IsValid()) 63 require.NotNil(t, note.Message.Valid().ReplyTo) 64 require.Equal(t, origID, note.Message.Valid().ReplyTo.GetMessageID()) 65 case <-time.After(timeout): 66 require.Fail(t, "no local") 67 } 68 threadRes, err := ctc.as(t, users[0]).chatLocalHandler().GetThreadLocal(ctx, chat1.GetThreadLocalArg{ 69 ConversationID: conv.Id, 70 Query: &chat1.GetThreadQuery{ 71 MessageTypes: []chat1.MessageType{chat1.MessageType_TEXT}, 72 }, 73 }) 74 require.NoError(t, err) 75 require.Equal(t, 2, len(threadRes.Thread.Messages)) 76 require.True(t, threadRes.Thread.Messages[0].IsValid()) 77 require.NotNil(t, threadRes.Thread.Messages[0].Valid().ReplyTo) 78 require.Equal(t, origID, threadRes.Thread.Messages[0].Valid().ReplyTo.GetMessageID()) 79 80 t.Logf("edit original message") 81 mustEditMsg(ctx, t, ctc, users[0], conv, origID) 82 consumeNewMsgRemote(t, listener0, chat1.MessageType_EDIT) 83 consumeNewMsgLocal(t, listener0, chat1.MessageType_EDIT) 84 for i := 0; i < 2; i++ { 85 select { 86 case update := <-listener0.messagesUpdated: 87 require.Equal(t, 1, len(update.Updates)) 88 require.Equal(t, postRes.MessageID, update.Updates[0].GetMessageID()) 89 require.True(t, update.Updates[0].IsValid()) 90 require.NotNil(t, update.Updates[0].Valid().ReplyTo) 91 require.True(t, update.Updates[0].Valid().ReplyTo.IsValid()) 92 require.Equal(t, "edited", update.Updates[0].Valid().ReplyTo.Valid().BodySummary) 93 case <-time.After(timeout): 94 require.Fail(t, "no message update") 95 } 96 } 97 98 t.Logf("delete original message") 99 mustDeleteMsg(ctx, t, ctc, users[0], conv, origID) 100 consumeNewMsgRemote(t, listener0, chat1.MessageType_DELETE) 101 consumeNewMsgLocal(t, listener0, chat1.MessageType_DELETE) 102 select { 103 case update := <-listener0.messagesUpdated: 104 require.Equal(t, 1, len(update.Updates)) 105 require.Equal(t, postRes.MessageID, update.Updates[0].GetMessageID()) 106 require.True(t, update.Updates[0].IsValid()) 107 require.NotNil(t, update.Updates[0].Valid().ReplyTo) 108 st, err := update.Updates[0].Valid().ReplyTo.State() 109 require.NoError(t, err) 110 require.Equal(t, chat1.MessageUnboxedState_PLACEHOLDER, st) 111 case <-time.After(timeout): 112 require.Fail(t, "no message update") 113 } 114 }) 115 }