feat: support quoted message headers
This commit is contained in:
@@ -302,6 +302,70 @@ func TestHandleBroadcastDataP2P(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleBroadcastDataPreservesReplyHead(t *testing.T) {
|
||||
numUsers := 2
|
||||
helper := TopicTestHelper{}
|
||||
helper.setUp(t, numUsers, types.TopicCatP2P, "p2p-test" /*attach=*/, true)
|
||||
defer helper.tearDown()
|
||||
|
||||
reply := map[string]any{
|
||||
"seq": int64(128),
|
||||
"type": "text",
|
||||
"text": "今天晚上一起吃饭吗?",
|
||||
"from": helper.uids[1].UserId(),
|
||||
}
|
||||
helper.mm.EXPECT().Save(types.TenantID(1), gomock.Any(), gomock.Any(), gomock.Any()).
|
||||
DoAndReturn(func(_ types.TenantID, msg *types.Message, _ []string, _ bool) (*types.MessageSaveResult, error) {
|
||||
got, ok := msg.Head["x-im-reply"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("stored x-im-reply: got %#v", msg.Head["x-im-reply"])
|
||||
}
|
||||
if got["seq"] != reply["seq"] || got["type"] != reply["type"] || got["text"] != reply["text"] || got["from"] != reply["from"] {
|
||||
t.Fatalf("stored x-im-reply changed: got %#v want %#v", got, reply)
|
||||
}
|
||||
return &types.MessageSaveResult{SeqId: 1, MarkedReadBySender: true}, nil
|
||||
})
|
||||
|
||||
from := helper.uids[0].UserId()
|
||||
msg := &ClientComMessage{
|
||||
AsUser: from,
|
||||
Original: from,
|
||||
Pub: &MsgClientPub{
|
||||
Topic: "p2p",
|
||||
Head: map[string]any{
|
||||
"mime": "application/json",
|
||||
"x-im-schema": 1,
|
||||
"x-im-type": "text",
|
||||
"x-im-client-mid": "mid-reply-1",
|
||||
"x-im-reply": reply,
|
||||
},
|
||||
Content: map[string]any{"text": "好啊"},
|
||||
NoEcho: true,
|
||||
},
|
||||
sess: helper.sessions[0],
|
||||
}
|
||||
helper.topic.handleClientMsg(msg)
|
||||
helper.finish()
|
||||
|
||||
if errorMsgs, hasError := helper.hubMessages["__ERROR__"]; hasError {
|
||||
t.Fatal(errorMsgs[0].Ctrl.Text)
|
||||
}
|
||||
if len(helper.results[1].messages) != 1 {
|
||||
t.Fatalf("peer: expected 1 message, got %d", len(helper.results[1].messages))
|
||||
}
|
||||
data := helper.results[1].messages[0].(*ServerComMessage).Data
|
||||
if data == nil {
|
||||
t.Fatalf("peer response must have data")
|
||||
}
|
||||
got, ok := data.Head["x-im-reply"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("broadcast x-im-reply: got %#v", data.Head["x-im-reply"])
|
||||
}
|
||||
if got["seq"] != reply["seq"] || got["type"] != reply["type"] || got["text"] != reply["text"] || got["from"] != reply["from"] {
|
||||
t.Fatalf("broadcast x-im-reply changed: got %#v want %#v", got, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func TestHandleBroadcastDataP2PRequiresRelationship(t *testing.T) {
|
||||
numUsers := 2
|
||||
helper := TopicTestHelper{}
|
||||
@@ -1130,6 +1194,65 @@ func TestSaveMessageMaybeKafkaPublishesWithoutDBPersist(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaveMessageMaybeKafkaPreservesReplyHead(t *testing.T) {
|
||||
ctrl := gomock.NewController(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
oldKafkaBus := kafkaBus
|
||||
oldStore := store.Store
|
||||
oldMessages := store.Messages
|
||||
oldPublisher := publishKafkaMessagePersist
|
||||
defer func() {
|
||||
kafkaBus = oldKafkaBus
|
||||
store.Store = oldStore
|
||||
store.Messages = oldMessages
|
||||
publishKafkaMessagePersist = oldPublisher
|
||||
}()
|
||||
|
||||
kafkaBus = &kafkaRuntime{}
|
||||
mockStore := mock_store.NewMockPersistentStorageInterface(ctrl)
|
||||
mockStore.EXPECT().GetUid().Return(types.Uid(102))
|
||||
store.Store = mockStore
|
||||
store.Messages = mock_store.NewMockMessagesPersistenceInterface(ctrl)
|
||||
var publishedPayload kafkaMessagePersistPayload
|
||||
publishKafkaMessagePersist = func(_ context.Context, _, _ string, envelope kafkaEnvelope) error {
|
||||
if err := json.Unmarshal(envelope.Payload, &publishedPayload); err != nil {
|
||||
t.Fatalf("failed to unmarshal kafka payload: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
reply := map[string]any{
|
||||
"seq": float64(12),
|
||||
"type": "text",
|
||||
"text": "quoted hello",
|
||||
"from": types.Uid(2).UserId(),
|
||||
}
|
||||
msg := &types.Message{
|
||||
TenantID: 1,
|
||||
Topic: "grp-test",
|
||||
SeqId: 7,
|
||||
From: types.Uid(1).String(),
|
||||
Head: types.KVMap{
|
||||
"x-im-client-mid": "client-reply-1",
|
||||
"x-im-type": "text",
|
||||
"x-im-reply": reply,
|
||||
},
|
||||
Content: map[string]any{"text": "reply"},
|
||||
}
|
||||
|
||||
if _, err := saveMessageMaybeKafka(context.Background(), 1, msg, nil, true); err != nil {
|
||||
t.Fatalf("saveMessageMaybeKafka returned error: %v", err)
|
||||
}
|
||||
got, ok := publishedPayload.Message.Head["x-im-reply"].(map[string]any)
|
||||
if !ok {
|
||||
t.Fatalf("kafka payload x-im-reply: got %#v", publishedPayload.Message.Head["x-im-reply"])
|
||||
}
|
||||
if got["seq"] != reply["seq"] || got["type"] != reply["type"] || got["text"] != reply["text"] || got["from"] != reply["from"] {
|
||||
t.Fatalf("kafka payload x-im-reply changed: got %#v want %#v", got, reply)
|
||||
}
|
||||
}
|
||||
|
||||
func TestShouldTryHotMessageFallback(t *testing.T) {
|
||||
if !shouldTryHotMessageFallback(types.TopicCatGrp, 159, &types.QueryOpt{Since: 159, Limit: 1}) {
|
||||
t.Fatal("expected fallback for latest group seq query")
|
||||
|
||||
Reference in New Issue
Block a user