Files

139 lines
4.5 KiB
Go

package ctxmgr
import (
"context"
"testing"
)
func TestCompressDismissed(t *testing.T) {
futureIDs := []int64{10, 11, 12, 13, 14}
// 1. 倒序读第 14 条 (最高一条)
b1, d1 := compressDismissed(9, []int64{14}, futureIDs)
if b1 != 9 {
t.Errorf("expected baseline 9, got %d", b1)
}
if len(d1) != 1 || d1[0] != 14 {
t.Errorf("expected dismissed [14], got %v", d1)
}
// 2. 读第 10 条 (与 baseline 9 连续)
b2, d2 := compressDismissed(9, []int64{10, 14}, futureIDs)
if b2 != 10 {
t.Errorf("expected baseline 10, got %d", b2)
}
if len(d2) != 1 || d2[0] != 14 {
t.Errorf("expected dismissed [14], got %v", d2)
}
// 3. 补齐 11, 12, 13,全连续收敛
b3, d3 := compressDismissed(10, []int64{11, 12, 13, 14}, futureIDs)
if b3 != 14 {
t.Errorf("expected baseline 14, got %d", b3)
}
if len(d3) != 0 {
t.Errorf("expected empty dismissed, got %v", d3)
}
}
func TestChatUnreadLifecycle(t *testing.T) {
ctx := context.Background()
mgr := NewContextManager(nil, nil, DefaultTimeDecayConfig())
sessID := "sess_unread_test_01"
userID := int64(1001)
// 1. 会话尚无消息时,首次查询返回 0 未读
sum1, err := mgr.GetChatUnreadSummary(ctx, sessID, userID, 0)
if err != nil {
t.Fatalf("GetChatUnreadSummary failed: %v", err)
}
if sum1.Total != 0 {
t.Errorf("expected 0 unread on empty session, got %d", sum1.Total)
}
// 2. 写入初始历史消息 2 条
_ = mgr.RecordUserMessage(ctx, sessID, userID, "user", "你好", "CASUAL_CHAT", "", nil)
_ = mgr.RecordUserMessage(ctx, sessID, 0, "assistant", "你好!有什么我可以帮您的?", "CASUAL_CHAT", "", nil)
// 首次进入会话,初始化默认全部已读
posInit, err := mgr.GetChatReadPosition(ctx, sessID, userID)
if err != nil {
t.Fatalf("GetChatReadPosition failed: %v", err)
}
if posInit == nil {
// 触发初始化
sumInit, _ := mgr.GetChatUnreadSummary(ctx, sessID, userID, 0)
if sumInit.Total != 0 {
t.Errorf("expected 0 unread on initial load, got %d", sumInit.Total)
}
}
// 3. 新收到来自 assistant 的 2 条消息
_ = mgr.RecordUserMessage(ctx, sessID, 0, "assistant", "更新文档进展", "QUERY_PROGRESS", "", nil)
_ = mgr.RecordUserMessage(ctx, sessID, 0, "assistant", "请确认方案卡片", "DOCGOV_SUBMIT_REVIEW", "", nil)
// 以及用户自己发出的 1 条消息 (不能被算作未读)
_ = mgr.RecordUserMessage(ctx, sessID, userID, "user", "我看看", "CASUAL_CHAT", "", nil)
sum2, err := mgr.GetChatUnreadSummary(ctx, sessID, userID, 0)
if err != nil {
t.Fatalf("GetChatUnreadSummary failed: %v", err)
}
if sum2.Total != 2 {
t.Fatalf("expected 2 unread assistant messages, got %d", sum2.Total)
}
if len(sum2.UnreadMessageIDs) != 2 {
t.Fatalf("expected 2 unread IDs, got %v", sum2.UnreadMessageIDs)
}
newestUnreadID := sum2.NextMessageID
if newestUnreadID != sum2.UnreadMessageIDs[0] {
t.Errorf("expected NextMessageID to match first unread ID %d, got %d", sum2.UnreadMessageIDs[0], newestUnreadID)
}
// 4. 倒序消费:先标记最新的一条已读 (逐条消费循环第一步)
posAfterFirst, err := mgr.MarkChatRead(ctx, MarkChatReadRequest{
SessionID: sessID,
UserID: userID,
ReadMessageIDs: []int64{newestUnreadID},
})
if err != nil {
t.Fatalf("MarkChatRead failed: %v", err)
}
if len(posAfterFirst.DismissedUnreadIDs) != 1 || posAfterFirst.DismissedUnreadIDs[0] != newestUnreadID {
t.Errorf("expected dismissed [%d], got %v", newestUnreadID, posAfterFirst.DismissedUnreadIDs)
}
// 再次查询未读,还剩 1 条
sum3, err := mgr.GetChatUnreadSummary(ctx, sessID, userID, 0)
if err != nil {
t.Fatalf("GetChatUnreadSummary failed: %v", err)
}
if sum3.Total != 1 {
t.Fatalf("expected 1 unread remaining, got %d", sum3.Total)
}
remainingID := sum3.NextMessageID
// 5. 消费最后一条未读,此时触发与 baseline 连续的自动压缩
posAfterSecond, err := mgr.MarkChatRead(ctx, MarkChatReadRequest{
SessionID: sessID,
UserID: userID,
ReadMessageIDs: []int64{remainingID},
})
if err != nil {
t.Fatalf("MarkChatRead second step failed: %v", err)
}
if len(posAfterSecond.DismissedUnreadIDs) != 0 {
t.Errorf("expected dismissed array to be compressed to empty, got %v", posAfterSecond.DismissedUnreadIDs)
}
// 全部已读
sumFinal, err := mgr.GetChatUnreadSummary(ctx, sessID, userID, 0)
if err != nil {
t.Fatalf("GetChatUnreadSummary failed: %v", err)
}
if sumFinal.Total != 0 {
t.Errorf("expected 0 unread after all consumed, got %d", sumFinal.Total)
}
}