merged from gramsrv upstream
This commit is contained in:
parent
79c64ee916
commit
21a0856587
651 changed files with 54774 additions and 4590 deletions
157
internal/store/postgres/contact_sparse_integration_test.go
Normal file
157
internal/store/postgres/contact_sparse_integration_test.go
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
func TestContactProjectionForViewerUserIDsPostgresDoesNotCrossPairs(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
suffix := randomSuffix(t)
|
||||
users := NewUserStore(pool)
|
||||
viewerA := createTestUser(t, ctx, users, "+1910"+suffix+"01", "Viewer", "A")
|
||||
viewerB := createTestUser(t, ctx, users, "+1910"+suffix+"02", "Viewer", "B")
|
||||
ownerA := createTestUser(t, ctx, users, "+1910"+suffix+"03", "Owner", "A")
|
||||
ownerB := createTestUser(t, ctx, users, "+1910"+suffix+"04", "Owner", "B")
|
||||
userIDs := []int64{viewerA.ID, viewerB.ID, ownerA.ID, ownerB.ID}
|
||||
photoBase := time.Now().UnixNano() & 0x3fffffffffffffff
|
||||
photoIDs := []int64{photoBase + 1, photoBase + 2, photoBase + 3, photoBase + 4}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = ANY($1::bigint[])", userIDs)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM photos WHERE id = ANY($1::bigint[])", photoIDs)
|
||||
})
|
||||
media := NewMediaStore(pool)
|
||||
for _, photoID := range photoIDs {
|
||||
if err := media.PutPhoto(ctx, domain.Photo{
|
||||
ID: photoID, AccessHash: photoID + 100, FileReference: []byte("sparse-ref"), Date: 1700000000, DCID: 2,
|
||||
Sizes: []domain.PhotoSize{{Kind: domain.PhotoSizeKindStripped, Type: "i", Bytes: []byte{1, 2, byte(photoID)}}},
|
||||
}); err != nil {
|
||||
t.Fatalf("PutPhoto(%d): %v", photoID, err)
|
||||
}
|
||||
}
|
||||
contacts := NewContactStore(pool)
|
||||
rows := []struct {
|
||||
viewer int64
|
||||
owner int64
|
||||
name string
|
||||
photo int64
|
||||
}{
|
||||
{viewerA.ID, ownerA.ID, "A expected", photoIDs[0]},
|
||||
{viewerA.ID, ownerB.ID, "B cross", photoIDs[1]},
|
||||
{viewerB.ID, ownerA.ID, "A cross", photoIDs[2]},
|
||||
{viewerB.ID, ownerB.ID, "B expected", photoIDs[3]},
|
||||
}
|
||||
for _, row := range rows {
|
||||
if _, err := contacts.Upsert(ctx, row.viewer, domain.ContactInput{
|
||||
ContactUserID: row.owner,
|
||||
FirstName: row.name,
|
||||
Phone: "known-phone",
|
||||
Note: "private note",
|
||||
NoteEntities: []domain.MessageEntity{{
|
||||
Type: domain.MessageEntityBold, Length: 7,
|
||||
}},
|
||||
}); err != nil {
|
||||
t.Fatalf("Upsert %d->%d: %v", row.viewer, row.owner, err)
|
||||
}
|
||||
if _, found, err := contacts.SetPersonalPhoto(ctx, row.viewer, row.owner, row.photo, 1700000001); err != nil || !found {
|
||||
t.Fatalf("SetPersonalPhoto %d->%d: found=%v err=%v", row.viewer, row.owner, found, err)
|
||||
}
|
||||
}
|
||||
got, err := contacts.ContactProjectionForViewerUserIDs(ctx, map[int64][]int64{
|
||||
viewerA.ID: {ownerA.ID},
|
||||
viewerB.ID: {ownerB.ID},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("ContactProjectionForViewerUserIDs: %v", err)
|
||||
}
|
||||
if len(got.Contacts[viewerA.ID]) != 1 || got.Contacts[viewerA.ID][ownerA.ID].FirstName != "A expected" {
|
||||
t.Fatalf("viewer A contacts = %+v", got.Contacts[viewerA.ID])
|
||||
}
|
||||
contactA := got.Contacts[viewerA.ID][ownerA.ID]
|
||||
if !reflect.DeepEqual(contactA.User, domain.User{ID: ownerA.ID}) {
|
||||
t.Fatalf("viewer A sparse projection retained joined base user data: %+v", contactA.User)
|
||||
}
|
||||
if contactA.Phone != "known-phone" || contactA.Note != "private note" || len(contactA.NoteEntities) != 1 || contactA.NoteEntities[0].Length != 7 {
|
||||
t.Fatalf("viewer A sparse overlay = %+v", contactA)
|
||||
}
|
||||
if len(got.Contacts[viewerB.ID]) != 1 || got.Contacts[viewerB.ID][ownerB.ID].FirstName != "B expected" {
|
||||
t.Fatalf("viewer B contacts = %+v", got.Contacts[viewerB.ID])
|
||||
}
|
||||
if _, ok := got.Contacts[viewerA.ID][ownerB.ID]; ok {
|
||||
t.Fatal("viewer A received crossed owner B")
|
||||
}
|
||||
if _, ok := got.Contacts[viewerB.ID][ownerA.ID]; ok {
|
||||
t.Fatal("viewer B received crossed owner A")
|
||||
}
|
||||
if got.PersonalPhotos[viewerA.ID][ownerA.ID].PhotoID != photoIDs[0] || len(got.PersonalPhotos[viewerA.ID]) != 1 {
|
||||
t.Fatalf("viewer A personal photos = %+v", got.PersonalPhotos[viewerA.ID])
|
||||
}
|
||||
if got.PersonalPhotos[viewerB.ID][ownerB.ID].PhotoID != photoIDs[3] || len(got.PersonalPhotos[viewerB.ID]) != 1 {
|
||||
t.Fatalf("viewer B personal photos = %+v", got.PersonalPhotos[viewerB.ID])
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetReverseContactsForViewerUserIDsPostgresDoesNotCrossPairs(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
suffix := randomSuffix(t)
|
||||
users := NewUserStore(pool)
|
||||
viewerA := createTestUser(t, ctx, users, "+1911"+suffix+"01", "Viewer", "A")
|
||||
viewerB := createTestUser(t, ctx, users, "+1911"+suffix+"02", "Viewer", "B")
|
||||
ownerA := createTestUser(t, ctx, users, "+1911"+suffix+"03", "Owner", "A")
|
||||
ownerB := createTestUser(t, ctx, users, "+1911"+suffix+"04", "Owner", "B")
|
||||
userIDs := []int64{viewerA.ID, viewerB.ID, ownerA.ID, ownerB.ID}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = ANY($1::bigint[])", userIDs)
|
||||
})
|
||||
|
||||
contacts := NewContactStore(pool)
|
||||
for _, row := range []struct {
|
||||
owner int64
|
||||
viewer int64
|
||||
name string
|
||||
}{
|
||||
{ownerA.ID, viewerA.ID, "A expected"},
|
||||
{ownerA.ID, viewerB.ID, "A cross"},
|
||||
{ownerB.ID, viewerA.ID, "B cross"},
|
||||
{ownerB.ID, viewerB.ID, "B expected"},
|
||||
} {
|
||||
if _, err := contacts.Upsert(ctx, row.owner, domain.ContactInput{
|
||||
ContactUserID: row.viewer,
|
||||
FirstName: row.name,
|
||||
Note: "relationship-only",
|
||||
}); err != nil {
|
||||
t.Fatalf("Upsert %d->%d: %v", row.owner, row.viewer, err)
|
||||
}
|
||||
}
|
||||
if _, err := contacts.SetCloseFriends(ctx, ownerA.ID, []int64{viewerA.ID}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
got, err := contacts.GetReverseContactsForViewerUserIDs(ctx, map[int64][]int64{
|
||||
ownerA.ID: {viewerA.ID},
|
||||
ownerB.ID: {viewerB.ID},
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("GetReverseContactsForViewerUserIDs: %v", err)
|
||||
}
|
||||
contactA, found := got[ownerA.ID][viewerA.ID]
|
||||
if !found || contactA.User.ID != viewerA.ID || contactA.FirstName != "A expected" || !contactA.CloseFriend {
|
||||
t.Fatalf("owner A exact relationship = %+v found=%v", contactA, found)
|
||||
}
|
||||
contactB, found := got[ownerB.ID][viewerB.ID]
|
||||
if !found || contactB.User.ID != viewerB.ID || contactB.FirstName != "B expected" || contactB.CloseFriend {
|
||||
t.Fatalf("owner B exact relationship = %+v found=%v", contactB, found)
|
||||
}
|
||||
if _, found := got[ownerA.ID][viewerB.ID]; found {
|
||||
t.Fatal("owner A received crossed viewer B")
|
||||
}
|
||||
if _, found := got[ownerB.ID][viewerA.ID]; found {
|
||||
t.Fatal("owner B received crossed viewer A")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue