owpengram-server/internal/store/postgres/message_webpage_resolve_integration_test.go

92 lines
4 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package postgres
import (
"context"
"errors"
"testing"
"telesrv/internal/domain"
)
// TestMessageStoreResolveWebPageIntegration 对 live Postgres 验证 WebPageResolve 分支:
// 双盒 media 就地换 done、body/edit_date 不变无「已编辑」标记、durable web_page 事件
// 经 box JOIN 重建出 done mediadifference 复用)、幂等。需 TELESRV_TEST_POSTGRES_DSN。
func TestMessageStoreResolveWebPageIntegration(t *testing.T) {
pool := testPool(t)
ctx := context.Background()
suffix := randomSuffix(t)
users := NewUserStore(pool)
sender, err := users.Create(ctx, domain.User{AccessHash: 41, Phone: "+1667" + suffix + "11", FirstName: "WPSender"})
if err != nil {
t.Fatalf("create sender: %v", err)
}
recipient, err := users.Create(ctx, domain.User{AccessHash: 42, Phone: "+1667" + suffix + "12", FirstName: "WPRecipient"})
if err != nil {
t.Fatalf("create recipient: %v", err)
}
t.Cleanup(func() {
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = ANY($1::bigint[])", []int64{sender.ID, recipient.ID})
})
const url = "https://example.com/x"
urlHash := domain.WebPageURLHash(url)
peer := domain.Peer{Type: domain.PeerTypeUser, ID: recipient.ID}
messages := NewMessageStore(pool)
sent, err := messages.SendPrivateText(ctx, domain.SendPrivateTextRequest{
SenderUserID: sender.ID, RecipientUserID: recipient.ID, RandomID: 778811,
Message: "see " + url, Date: 1700000300,
Media: &domain.MessageMedia{Kind: domain.MessageMediaKindWebPage, WebPage: &domain.MessageWebPage{State: domain.MessageWebPageStatePending, ID: urlHash, URL: url}},
})
if err != nil {
t.Fatalf("SendPrivateText: %v", err)
}
done := &domain.MessageMedia{Kind: domain.MessageMediaKindWebPage, WebPage: &domain.MessageWebPage{State: domain.MessageWebPageStateDone, ID: urlHash, URL: url, DisplayURL: "example.com", Title: "Example"}}
resolveReq := domain.EditMessageRequest{
OwnerUserID: sender.ID, Peer: peer, ID: sent.SenderMessage.ID,
Media: done, WebPageResolve: true, ExpectedWebPageID: urlHash,
}
res, err := messages.EditMessage(ctx, resolveReq)
if err != nil {
t.Fatalf("EditMessage(WebPageResolve): %v", err)
}
self := res.Self()
if self.Event.Type != domain.UpdateEventWebPage {
t.Fatalf("self event type = %q, want web_page", self.Event.Type)
}
if self.Message.Media == nil || self.Message.Media.WebPage == nil || self.Message.Media.WebPage.State != domain.MessageWebPageStateDone {
t.Fatalf("self media not resolved: %+v", self.Message.Media)
}
if self.Message.Body != "see "+url || self.Message.EditDate != 0 {
t.Fatalf("body/edit_date changed: body=%q edit_date=%d", self.Message.Body, self.Message.EditDate)
}
// 接收方盒子media=donebody/edit_date 不变。
rh, err := messages.ListByUser(ctx, recipient.ID, domain.MessageFilter{HasPeer: true, Peer: domain.Peer{Type: domain.PeerTypeUser, ID: sender.ID}, Limit: 10})
if err != nil {
t.Fatalf("recipient history: %v", err)
}
if len(rh.Messages) != 1 || rh.Messages[0].Media == nil || rh.Messages[0].Media.WebPage == nil || rh.Messages[0].Media.WebPage.State != domain.MessageWebPageStateDone {
t.Fatalf("recipient media not resolved: %+v", rh.Messages)
}
if rh.Messages[0].Body != "see "+url || rh.Messages[0].EditDate != 0 {
t.Fatalf("recipient body/edit_date changed: %+v", rh.Messages[0])
}
// durable 事件difference 复用经 box JOIN 重建出 done media。
recipientEvents, err := NewUpdateEventStore(pool).ListAfter(ctx, recipient.ID, 0, 10)
if err != nil {
t.Fatalf("recipient events: %v", err)
}
last := recipientEvents[len(recipientEvents)-1]
if last.Type != domain.UpdateEventWebPage || last.Message.Media == nil || last.Message.Media.WebPage == nil || last.Message.Media.WebPage.State != domain.MessageWebPageStateDone {
t.Fatalf("recipient durable web_page event = %+v, want done media", last)
}
// 幂等:再次解析 → ErrMessageNotModified。
if _, err := messages.EditMessage(ctx, resolveReq); !errors.Is(err, domain.ErrMessageNotModified) {
t.Fatalf("re-resolve err = %v, want ErrMessageNotModified", err)
}
}