merged from gramsrv upstream
This commit is contained in:
parent
79c64ee916
commit
21a0856587
651 changed files with 54774 additions and 4590 deletions
190
internal/store/postgres/dialog_snapshot_hash_integration_test.go
Normal file
190
internal/store/postgres/dialog_snapshot_hash_integration_test.go
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
func TestChannelDialogSnapshotHashTracksDependenciesWithoutWideHeaders(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
suffix := randomSuffix(t)
|
||||
|
||||
owner, err := NewUserStore(pool).Create(ctx, domain.User{
|
||||
AccessHash: 51,
|
||||
Phone: "+1778" + suffix + "01",
|
||||
FirstName: "SnapshotHashOwner",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create owner: %v", err)
|
||||
}
|
||||
created, err := NewChannelStore(pool).CreateChannel(ctx, domain.CreateChannelRequest{
|
||||
CreatorUserID: owner.ID,
|
||||
Title: "Snapshot Hash " + suffix,
|
||||
Megagroup: true,
|
||||
Date: 1700000600,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create channel: %v", err)
|
||||
}
|
||||
channelID := created.Channel.ID
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM channels WHERE id = $1", channelID)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = $1", owner.ID)
|
||||
})
|
||||
|
||||
channels := NewChannelStore(pool)
|
||||
load := func() domain.ChannelDialogList {
|
||||
t.Helper()
|
||||
list, err := channels.ListChannelDialogSnapshotHeaders(ctx, owner.ID, domain.DialogFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("list snapshot headers: %v", err)
|
||||
}
|
||||
if len(list.Dialogs) != 1 || list.Hash == 0 {
|
||||
t.Fatalf("snapshot = %+v, want one dialog and non-zero hash", list)
|
||||
}
|
||||
dialog := list.Dialogs[0]
|
||||
if dialog.Peer.ID != channelID || dialog.TopMessage == 0 || dialog.TopMessageDate == 0 {
|
||||
t.Fatalf("ordering header = %+v, want peer/top/date", dialog)
|
||||
}
|
||||
if dialog.ReadInboxMaxID != 0 || dialog.ReadOutboxMaxID != 0 || dialog.UnreadCount != 0 ||
|
||||
dialog.UnreadMentions != 0 || dialog.UnreadReactions != 0 || dialog.Pts != 0 {
|
||||
t.Fatalf("snapshot header retained mutable hydration fields: %+v", dialog)
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
before := load()
|
||||
changed, err := channels.SetChannelDialogUnreadMark(ctx, owner.ID, channelID, true)
|
||||
if err != nil || !changed {
|
||||
t.Fatalf("set unread mark = %v, %v", changed, err)
|
||||
}
|
||||
afterOwnerState := load()
|
||||
if afterOwnerState.Hash == before.Hash {
|
||||
t.Fatalf("owner-local dependency hash stayed %d after unread mark", before.Hash)
|
||||
}
|
||||
if afterOwnerState.Dialogs[0].TopMessage != before.Dialogs[0].TopMessage ||
|
||||
afterOwnerState.Dialogs[0].TopMessageDate != before.Dialogs[0].TopMessageDate {
|
||||
t.Fatalf("unread mark changed ordering header: before=%+v after=%+v", before.Dialogs[0], afterOwnerState.Dialogs[0])
|
||||
}
|
||||
|
||||
if _, err := pool.Exec(ctx, "UPDATE channels SET title = title || ' changed' WHERE id = $1", channelID); err != nil {
|
||||
t.Fatalf("update channel title: %v", err)
|
||||
}
|
||||
afterSharedState := load()
|
||||
if afterSharedState.Hash == afterOwnerState.Hash {
|
||||
t.Fatalf("shared channel dependency hash stayed %d after channel-base change", afterOwnerState.Hash)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrivateDialogSnapshotHashTracksDraftDependency(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
suffix := randomSuffix(t)
|
||||
users := NewUserStore(pool)
|
||||
owner, err := users.Create(ctx, domain.User{
|
||||
AccessHash: 52,
|
||||
Phone: "+1778" + suffix + "02",
|
||||
FirstName: "PrivateSnapshotOwner",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create owner: %v", err)
|
||||
}
|
||||
peer, err := users.Create(ctx, domain.User{
|
||||
AccessHash: 53,
|
||||
Phone: "+1778" + suffix + "03",
|
||||
FirstName: "PrivateSnapshotPeer",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create peer: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = ANY($1::bigint[])", []int64{owner.ID, peer.ID})
|
||||
})
|
||||
|
||||
dialogs := NewDialogStore(pool)
|
||||
dialogPeer := domain.Peer{Type: domain.PeerTypeUser, ID: peer.ID}
|
||||
if err := dialogs.Upsert(ctx, owner.ID, domain.Dialog{
|
||||
Peer: dialogPeer,
|
||||
TopMessage: 7,
|
||||
TopMessageDate: 1700000610,
|
||||
}); err != nil {
|
||||
t.Fatalf("upsert dialog: %v", err)
|
||||
}
|
||||
before, err := dialogs.ListDialogSnapshotHeaders(ctx, owner.ID, domain.DialogFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("list snapshot before draft: %v", err)
|
||||
}
|
||||
if len(before.Dialogs) != 1 || before.Hash == 0 {
|
||||
t.Fatalf("snapshot before draft = %+v", before)
|
||||
}
|
||||
if err := dialogs.SaveDraft(ctx, owner.ID, domain.DialogDraft{
|
||||
Peer: dialogPeer,
|
||||
Date: 1700000611,
|
||||
Message: "draft changes hash without changing ordering",
|
||||
}); err != nil {
|
||||
t.Fatalf("save draft: %v", err)
|
||||
}
|
||||
after, err := dialogs.ListDialogSnapshotHeaders(ctx, owner.ID, domain.DialogFilter{})
|
||||
if err != nil {
|
||||
t.Fatalf("list snapshot after draft: %v", err)
|
||||
}
|
||||
if after.Hash == before.Hash {
|
||||
t.Fatalf("private snapshot hash stayed %d after draft change", before.Hash)
|
||||
}
|
||||
if after.Dialogs[0].TopMessage != before.Dialogs[0].TopMessage || after.Dialogs[0].TopMessageDate != before.Dialogs[0].TopMessageDate {
|
||||
t.Fatalf("draft changed ordering header: before=%+v after=%+v", before.Dialogs[0], after.Dialogs[0])
|
||||
}
|
||||
}
|
||||
|
||||
func TestPrivateDialogAllBuiltinSnapshotIncludesMainAndArchive(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
suffix := randomSuffix(t)
|
||||
users := NewUserStore(pool)
|
||||
owner, err := users.Create(ctx, domain.User{AccessHash: 61, Phone: "+1778" + suffix + "11", FirstName: "AllFolderOwner"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mainPeer, err := users.Create(ctx, domain.User{AccessHash: 62, Phone: "+1778" + suffix + "12", FirstName: "MainPeer"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
archivePeer, err := users.Create(ctx, domain.User{AccessHash: 63, Phone: "+1778" + suffix + "13", FirstName: "ArchivePeer"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = ANY($1::bigint[])", []int64{owner.ID, mainPeer.ID, archivePeer.ID})
|
||||
})
|
||||
dialogs := NewDialogStore(pool)
|
||||
for index, peer := range []int64{mainPeer.ID, archivePeer.ID} {
|
||||
if err := dialogs.Upsert(ctx, owner.ID, domain.Dialog{
|
||||
Peer: domain.Peer{Type: domain.PeerTypeUser, ID: peer},
|
||||
TopMessage: 10 + index, TopMessageDate: 1700000700 + index,
|
||||
}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
if err := dialogs.EditPeerFolders(ctx, owner.ID, []domain.FolderPeerUpdate{{
|
||||
Peer: domain.Peer{Type: domain.PeerTypeUser, ID: archivePeer.ID}, FolderID: domain.DialogArchiveFolderID,
|
||||
}}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
all, err := dialogs.ListAllBuiltinDialogSnapshotHeaders(ctx, owner.ID)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(all.Dialogs) != 2 {
|
||||
t.Fatalf("all built-in private dialogs = %+v", all.Dialogs)
|
||||
}
|
||||
folders := map[int64]int{}
|
||||
for _, dialog := range all.Dialogs {
|
||||
folders[dialog.Peer.ID] = dialog.FolderID
|
||||
}
|
||||
if folders[mainPeer.ID] != domain.DialogMainFolderID || folders[archivePeer.ID] != domain.DialogArchiveFolderID {
|
||||
t.Fatalf("all built-in private folders = %#v", folders)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue