package isphere import ( "context" "testing" "isphere-ai-bridge/internal/msglib" ) func TestMsgLibMessageSourceMapsListMessagesToReceiveMessages(t *testing.T) { fake := &fakeMsgLibMessageLister{ result: msglib.ListMessagesResult{ ReadOnly: true, MessageBodyValuesReturned: true, RawRowsReturned: false, FilePathsReturned: false, SourceTables: []string{"tblMsgGroupPersonMsg"}, Messages: []msglib.ListMessage{{ MessageID: "db-msg-1", ID: "db-msg-1", ConversationID: "group-redacted", ConversationType: "group", SenderID: "sender-redacted", SenderName: "Sender Redacted", ReceiverID: "", Text: "redacted body", ContentText: "redacted body", ContentType: "file", Timestamp: "1783423807000", CreatedAt: "2026-07-10T00:00:00Z", Subject: "redacted subject", Read: true, Source: "local_readonly", RawRef: "msglib:tblMsgGroupPersonMsg", Attachments: []msglib.ListMessageAttachment{{ FileID: "file-redacted-1", FileName: "redacted.docx", SizeBytes: 1234, DownloadRef: "", }}, }}, }, } source := MsgLibMessageSource{ Lister: fake, IncludeBody: true, IncludeAttachmentMetadata: true, } got, err := source.ReceiveMessages(context.Background(), ReceiveMessagesQuery{ ConversationID: "group-redacted", Query: "redacted", Since: "2026-07-10T00:00:00Z", Limit: 5, }) if err != nil { t.Fatalf("ReceiveMessages returned error: %v", err) } if len(fake.calls) != 1 { t.Fatalf("ListMessages calls = %d, want 1", len(fake.calls)) } call := fake.calls[0] if call.ConversationID != "group-redacted" || call.Query != "redacted" || call.Since != "2026-07-10T00:00:00Z" || call.Limit != 5 { t.Fatalf("ListMessages options = %+v", call) } if !call.IncludeBody || !call.IncludeAttachmentMetadata { t.Fatalf("ListMessages include flags = body:%v attachments:%v", call.IncludeBody, call.IncludeAttachmentMetadata) } if len(got.Messages) != 1 { t.Fatalf("messages = %+v, want one", got.Messages) } msg := got.Messages[0] if msg.ID != "db-msg-1" || msg.ConversationID != "group-redacted" || msg.ConversationType != "group" { t.Fatalf("unexpected message identity: %+v", msg) } if msg.SenderID != "sender-redacted" || msg.ReceiverID != "" || msg.Text != "redacted body" || msg.Subject != "redacted subject" || !msg.Read { t.Fatalf("unexpected message fields: %+v", msg) } if msg.Source != "local_readonly" || msg.RawRef != "msglib:tblMsgGroupPersonMsg" { t.Fatalf("source refs = %q/%q", msg.Source, msg.RawRef) } if len(msg.Attachments) != 1 || msg.Attachments[0].FileName != "redacted.docx" || msg.Attachments[0].DownloadRef != "" { t.Fatalf("attachments = %+v", msg.Attachments) } if msg.Attachments[0].SizeBytes == nil || *msg.Attachments[0].SizeBytes != 1234 { t.Fatalf("attachment size = %+v", msg.Attachments[0].SizeBytes) } } type fakeMsgLibMessageLister struct { calls []msglib.ListMessagesOptions result msglib.ListMessagesResult } func (f *fakeMsgLibMessageLister) ListMessages(_ context.Context, opts msglib.ListMessagesOptions) (msglib.ListMessagesResult, error) { f.calls = append(f.calls, opts) return f.result, nil }