488 lines
19 KiB
Go
488 lines
19 KiB
Go
package chatlists
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"strings"
|
|
"testing"
|
|
|
|
"telesrv/internal/domain"
|
|
"telesrv/internal/links"
|
|
"telesrv/internal/store/memory"
|
|
)
|
|
|
|
func TestSharedFolderInviteJoinUpdatesAndLeave(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
chatlists := memory.NewChatlistStore()
|
|
svc := NewService(chatlists, dialogs, WithSlugGenerator(func() (string, error) { return "slug-one", nil }))
|
|
|
|
ownerID := int64(1001)
|
|
viewerID := int64(2002)
|
|
peerA := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3001}, AccessHash: 31}
|
|
peerB := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3002}, AccessHash: 32}
|
|
peerC := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3003}, AccessHash: 33}
|
|
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Team",
|
|
IncludePeers: []domain.DialogFolderPeer{peerA},
|
|
}); err != nil {
|
|
t.Fatalf("seed owner folder: %v", err)
|
|
}
|
|
|
|
folder, invite, err := svc.ExportInvite(ctx, ownerID, 2, "Main link", []domain.DialogFolderPeer{peerA}, 100)
|
|
if err != nil {
|
|
t.Fatalf("ExportInvite: %v", err)
|
|
}
|
|
if invite.Slug != "slug-one" || !folder.IsChatlist || !folder.HasMyInvites {
|
|
t.Fatalf("export = folder %+v invite %+v, want chatlist with invite slug", folder, invite)
|
|
}
|
|
persisted, found, err := dialogs.GetFolder(ctx, ownerID, 2)
|
|
if err != nil || !found || !persisted.IsChatlist || !persisted.HasMyInvites {
|
|
t.Fatalf("persisted folder = %+v found %v err %v, want exported chatlist", persisted, found, err)
|
|
}
|
|
|
|
preview, err := svc.CheckInvite(ctx, viewerID, "https://t.me/addlist/slug-one")
|
|
if err != nil {
|
|
t.Fatalf("CheckInvite before join: %v", err)
|
|
}
|
|
if len(preview.Missing) != 1 || preview.Missing[0].Peer != peerA.Peer || preview.LocalFolder != nil {
|
|
t.Fatalf("preview before join = %+v, want missing peerA and no local folder", preview)
|
|
}
|
|
|
|
joined, err := svc.JoinInvite(ctx, viewerID, "slug-one", nil, 101)
|
|
if err != nil {
|
|
t.Fatalf("JoinInvite: %v", err)
|
|
}
|
|
if joined.Folder.ID != 2 || !joined.Folder.IsChatlist || joined.Folder.HasMyInvites || len(joined.Folder.IncludePeers) != 1 {
|
|
t.Fatalf("joined folder = %+v, want imported local chatlist with peerA", joined.Folder)
|
|
}
|
|
|
|
preview, err = svc.CheckInvite(ctx, viewerID, "slug-one")
|
|
if err != nil {
|
|
t.Fatalf("CheckInvite after join: %v", err)
|
|
}
|
|
if preview.LocalFolder == nil || preview.Membership == nil || len(preview.Already) != 1 || len(preview.Missing) != 0 {
|
|
t.Fatalf("preview after join = %+v, want already imported", preview)
|
|
}
|
|
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Team",
|
|
IsChatlist: true,
|
|
HasMyInvites: true,
|
|
IncludePeers: []domain.DialogFolderPeer{peerA, peerB},
|
|
}); err != nil {
|
|
t.Fatalf("extend owner folder: %v", err)
|
|
}
|
|
if _, err := svc.EditInvite(ctx, ownerID, 2, "slug-one", nil, &[]domain.DialogFolderPeer{peerA, peerB}, false); err != nil {
|
|
t.Fatalf("EditInvite add peerB: %v", err)
|
|
}
|
|
updates, err := svc.GetUpdates(ctx, viewerID, joined.Folder.ID)
|
|
if err != nil {
|
|
t.Fatalf("GetUpdates: %v", err)
|
|
}
|
|
if len(updates.Missing) != 1 || updates.Missing[0].Peer != peerB.Peer {
|
|
t.Fatalf("updates = %+v, want missing peerB", updates)
|
|
}
|
|
ownerUpdates, err := svc.GetUpdates(ctx, ownerID, folder.ID)
|
|
if err != nil {
|
|
t.Fatalf("GetUpdates owner exported folder: %v", err)
|
|
}
|
|
if len(ownerUpdates.Missing) != 0 {
|
|
t.Fatalf("owner updates = %+v, want empty", ownerUpdates)
|
|
}
|
|
updated, err := svc.JoinUpdates(ctx, viewerID, joined.Folder.ID, []domain.DialogFolderPeer{peerB}, 102)
|
|
if err != nil {
|
|
t.Fatalf("JoinUpdates: %v", err)
|
|
}
|
|
if len(updated.Folder.IncludePeers) != 2 {
|
|
t.Fatalf("updated folder peers = %+v, want 2 peers", updated.Folder.IncludePeers)
|
|
}
|
|
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Team",
|
|
IsChatlist: true,
|
|
HasMyInvites: true,
|
|
IncludePeers: []domain.DialogFolderPeer{peerA, peerB, peerC},
|
|
}); err != nil {
|
|
t.Fatalf("extend owner folder with peerC: %v", err)
|
|
}
|
|
if _, err := svc.EditInvite(ctx, ownerID, 2, "slug-one", nil, &[]domain.DialogFolderPeer{peerA, peerB, peerC}, false); err != nil {
|
|
t.Fatalf("EditInvite add peerC: %v", err)
|
|
}
|
|
if err := svc.HideUpdates(ctx, viewerID, joined.Folder.ID); err != nil {
|
|
t.Fatalf("HideUpdates: %v", err)
|
|
}
|
|
updates, err = svc.GetUpdates(ctx, viewerID, joined.Folder.ID)
|
|
if err != nil {
|
|
t.Fatalf("GetUpdates after hide: %v", err)
|
|
}
|
|
if len(updates.Missing) != 0 {
|
|
t.Fatalf("updates after hide = %+v, want empty", updates)
|
|
}
|
|
|
|
suggestions, err := svc.LeaveSuggestions(ctx, viewerID, joined.Folder.ID)
|
|
if err != nil {
|
|
t.Fatalf("LeaveSuggestions: %v", err)
|
|
}
|
|
if len(suggestions) != 2 {
|
|
t.Fatalf("leave suggestions = %+v, want current two imported peers", suggestions)
|
|
}
|
|
if _, err := svc.Leave(ctx, viewerID, joined.Folder.ID, suggestions, 103); err != nil {
|
|
t.Fatalf("Leave: %v", err)
|
|
}
|
|
if _, found, err := dialogs.GetFolder(ctx, viewerID, joined.Folder.ID); err != nil || found {
|
|
t.Fatalf("local folder after leave found=%v err=%v, want deleted", found, err)
|
|
}
|
|
}
|
|
|
|
func TestDeleteLastSharedFolderInviteClearsOwnerFlag(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
chatlists := memory.NewChatlistStore()
|
|
slugs := []string{"slug-a", "slug-b"}
|
|
svc := NewService(chatlists, dialogs, WithSlugGenerator(func() (string, error) {
|
|
slug := slugs[0]
|
|
slugs = slugs[1:]
|
|
return slug, nil
|
|
}))
|
|
|
|
ownerID := int64(1001)
|
|
peer := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3001}, AccessHash: 31}
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Team",
|
|
IncludePeers: []domain.DialogFolderPeer{peer},
|
|
}); err != nil {
|
|
t.Fatalf("seed owner folder: %v", err)
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "one", []domain.DialogFolderPeer{peer}, 100); err != nil {
|
|
t.Fatalf("ExportInvite one: %v", err)
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "two", []domain.DialogFolderPeer{peer}, 101); err != nil {
|
|
t.Fatalf("ExportInvite two: %v", err)
|
|
}
|
|
if folder, changed, err := svc.DeleteInvite(ctx, ownerID, 2, "slug-a"); err != nil || changed || folder.HasMyInvites {
|
|
t.Fatalf("DeleteInvite first = folder %+v changed %v err %v, want no folder update", folder, changed, err)
|
|
}
|
|
persisted, found, err := dialogs.GetFolder(ctx, ownerID, 2)
|
|
if err != nil || !found || !persisted.HasMyInvites {
|
|
t.Fatalf("folder after first delete = %+v found %v err %v, want has_my_invites", persisted, found, err)
|
|
}
|
|
folder, changed, err := svc.DeleteInvite(ctx, ownerID, 2, "slug-b")
|
|
if err != nil || !changed || folder.HasMyInvites {
|
|
t.Fatalf("DeleteInvite last = folder %+v changed %v err %v, want cleared flag", folder, changed, err)
|
|
}
|
|
persisted, found, err = dialogs.GetFolder(ctx, ownerID, 2)
|
|
if err != nil || !found || persisted.HasMyInvites {
|
|
t.Fatalf("folder after last delete = %+v found %v err %v, want has_my_invites=false", persisted, found, err)
|
|
}
|
|
}
|
|
|
|
func TestSharedFolderSlugValidation(t *testing.T) {
|
|
ctx := context.Background()
|
|
svc := NewService(memory.NewChatlistStore(), memory.NewDialogStore())
|
|
if _, err := svc.CheckInvite(ctx, 2002, "bad!"); !errors.Is(err, domain.ErrChatlistInviteInvalid) {
|
|
t.Fatalf("CheckInvite bad slug err = %v, want ErrChatlistInviteInvalid", err)
|
|
}
|
|
longSlug := strings.Repeat("a", links.MaxChatlistSlugBytes+1)
|
|
if _, err := svc.JoinInvite(ctx, 2002, longSlug, nil, 100); !errors.Is(err, domain.ErrChatlistInviteInvalid) {
|
|
t.Fatalf("JoinInvite long slug err = %v, want ErrChatlistInviteInvalid", err)
|
|
}
|
|
}
|
|
|
|
func TestRevokedSharedFolderInviteRemainsListedButCannotBeImported(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
chatlists := memory.NewChatlistStore()
|
|
svc := NewService(chatlists, dialogs, WithSlugGenerator(func() (string, error) { return "slug-revoke", nil }))
|
|
|
|
ownerID := int64(1001)
|
|
viewerID := int64(2002)
|
|
peer := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3001}, AccessHash: 31}
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Team",
|
|
IncludePeers: []domain.DialogFolderPeer{peer},
|
|
}); err != nil {
|
|
t.Fatalf("seed owner folder: %v", err)
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "Main link", []domain.DialogFolderPeer{peer}, 100); err != nil {
|
|
t.Fatalf("ExportInvite: %v", err)
|
|
}
|
|
revoked, err := svc.EditInvite(ctx, ownerID, 2, "slug-revoke", nil, nil, true)
|
|
if err != nil {
|
|
t.Fatalf("EditInvite revoke: %v", err)
|
|
}
|
|
if !revoked.Revoked {
|
|
t.Fatalf("revoked invite = %+v, want Revoked=true", revoked)
|
|
}
|
|
invites, err := svc.ListInvites(ctx, ownerID, 2)
|
|
if err != nil {
|
|
t.Fatalf("ListInvites: %v", err)
|
|
}
|
|
if len(invites) != 1 || !invites[0].Revoked {
|
|
t.Fatalf("listed invites = %+v, want revoked invite visible to owner", invites)
|
|
}
|
|
if _, err := svc.CheckInvite(ctx, viewerID, "slug-revoke"); !errors.Is(err, domain.ErrChatlistInviteExpired) {
|
|
t.Fatalf("CheckInvite revoked err = %v, want ErrChatlistInviteExpired", err)
|
|
}
|
|
if _, err := svc.JoinInvite(ctx, viewerID, "slug-revoke", nil, 101); !errors.Is(err, domain.ErrChatlistInviteExpired) {
|
|
t.Fatalf("JoinInvite revoked err = %v, want ErrChatlistInviteExpired", err)
|
|
}
|
|
}
|
|
|
|
func TestSharedFolderJoinUpdatesAndLeaveUseChannelMemberships(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
channels := &fakeChatlistChannels{}
|
|
svc := NewService(
|
|
memory.NewChatlistStore(),
|
|
dialogs,
|
|
WithChannels(channels),
|
|
WithSlugGenerator(func() (string, error) { return "slug-channel", nil }),
|
|
)
|
|
|
|
ownerID := int64(1001)
|
|
viewerID := int64(2002)
|
|
peerA := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3001}, AccessHash: 31}
|
|
peerB := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3002}, AccessHash: 32}
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Team",
|
|
IncludePeers: []domain.DialogFolderPeer{peerA, peerB},
|
|
}); err != nil {
|
|
t.Fatalf("seed owner folder: %v", err)
|
|
}
|
|
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "Main link", []domain.DialogFolderPeer{peerA, peerB}, 100); err != nil {
|
|
t.Fatalf("ExportInvite: %v", err)
|
|
}
|
|
if got := channels.getIDs; len(got) != 2 || got[0] != peerA.Peer.ID || got[1] != peerB.Peer.ID {
|
|
t.Fatalf("shareability channel checks = %v, want peerA/peerB", got)
|
|
}
|
|
|
|
joined, err := svc.JoinInvite(ctx, viewerID, "slug-channel", []domain.DialogFolderPeer{peerA}, 101)
|
|
if err != nil {
|
|
t.Fatalf("JoinInvite peerA: %v", err)
|
|
}
|
|
if got := channels.inviteIDs; len(got) != 1 || got[0] != peerA.Peer.ID {
|
|
t.Fatalf("invite channel calls = %v, want peerA", got)
|
|
}
|
|
if len(joined.ChannelResults) != 1 || joined.ChannelResults[0].Channel.ID != peerA.Peer.ID {
|
|
t.Fatalf("join channel results = %+v, want peerA result", joined.ChannelResults)
|
|
}
|
|
|
|
updated, err := svc.JoinUpdates(ctx, viewerID, joined.Folder.ID, []domain.DialogFolderPeer{peerB}, 102)
|
|
if err != nil {
|
|
t.Fatalf("JoinUpdates peerB: %v", err)
|
|
}
|
|
if got := channels.inviteIDs; len(got) != 2 || got[1] != peerB.Peer.ID {
|
|
t.Fatalf("invite channel calls after updates = %v, want peerB appended", got)
|
|
}
|
|
if len(updated.ChannelResults) != 1 || updated.ChannelResults[0].Channel.ID != peerB.Peer.ID {
|
|
t.Fatalf("update channel results = %+v, want peerB result", updated.ChannelResults)
|
|
}
|
|
|
|
leave, err := svc.Leave(ctx, viewerID, joined.Folder.ID, []domain.DialogFolderPeer{peerA}, 103)
|
|
if err != nil {
|
|
t.Fatalf("Leave peerA: %v", err)
|
|
}
|
|
if got := channels.leaveIDs; len(got) != 1 || got[0] != peerA.Peer.ID {
|
|
t.Fatalf("leave channel calls = %v, want peerA", got)
|
|
}
|
|
if len(leave.ChannelResults) != 1 || leave.ChannelResults[0].Channel.ID != peerA.Peer.ID {
|
|
t.Fatalf("leave channel results = %+v, want peerA result", leave.ChannelResults)
|
|
}
|
|
}
|
|
|
|
func TestSharedFolderPublicPeerFallsBackToSelfJoin(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
channels := &fakeChatlistChannels{publicOnly: true}
|
|
svc := NewService(
|
|
memory.NewChatlistStore(),
|
|
dialogs,
|
|
WithChannels(channels),
|
|
WithSlugGenerator(func() (string, error) { return "slug-public", nil }),
|
|
)
|
|
|
|
ownerID := int64(1001)
|
|
viewerID := int64(2002)
|
|
peer := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3001}, AccessHash: 31}
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Public",
|
|
IncludePeers: []domain.DialogFolderPeer{peer},
|
|
}); err != nil {
|
|
t.Fatalf("seed owner folder: %v", err)
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "", []domain.DialogFolderPeer{peer}, 100); err != nil {
|
|
t.Fatalf("ExportInvite: %v", err)
|
|
}
|
|
if _, err := svc.JoinInvite(ctx, viewerID, "slug-public", []domain.DialogFolderPeer{peer}, 101); err != nil {
|
|
t.Fatalf("JoinInvite public peer: %v", err)
|
|
}
|
|
if len(channels.inviteIDs) != 0 {
|
|
t.Fatalf("invite channel calls = %v, want none for public-only owner", channels.inviteIDs)
|
|
}
|
|
if got := channels.joinIDs; len(got) != 1 || got[0] != peer.Peer.ID {
|
|
t.Fatalf("join channel calls = %v, want self-join peer", got)
|
|
}
|
|
}
|
|
|
|
func TestExportInviteRejectsRuleBasedFolder(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
svc := NewService(memory.NewChatlistStore(), dialogs, WithSlugGenerator(func() (string, error) { return "slug-two", nil }))
|
|
ownerID := int64(1001)
|
|
peer := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3001}, AccessHash: 31}
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Rule based",
|
|
Groups: true,
|
|
IncludePeers: []domain.DialogFolderPeer{peer},
|
|
}); err != nil {
|
|
t.Fatalf("seed folder: %v", err)
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "", []domain.DialogFolderPeer{peer}, 0); !errors.Is(err, domain.ErrChatlistNotShareable) {
|
|
t.Fatalf("ExportInvite rule folder err = %v, want ErrChatlistNotShareable", err)
|
|
}
|
|
}
|
|
|
|
func TestExportInviteRejectsUserPeers(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
svc := NewService(memory.NewChatlistStore(), dialogs, WithSlugGenerator(func() (string, error) { return "slug-user-peer", nil }))
|
|
ownerID := int64(1001)
|
|
peer := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeUser, ID: 2002}, AccessHash: 22}
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Users",
|
|
IncludePeers: []domain.DialogFolderPeer{peer},
|
|
}); err != nil {
|
|
t.Fatalf("seed folder: %v", err)
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "", []domain.DialogFolderPeer{peer}, 0); !errors.Is(err, domain.ErrChatlistNotShareable) {
|
|
t.Fatalf("ExportInvite user peer err = %v, want ErrChatlistNotShareable", err)
|
|
}
|
|
}
|
|
|
|
func TestChatlistInviteLimitUsesPremiumTier(t *testing.T) {
|
|
ctx := context.Background()
|
|
dialogs := memory.NewDialogStore()
|
|
chatlists := memory.NewChatlistStore()
|
|
ownerID := int64(1001)
|
|
peer := domain.DialogFolderPeer{Peer: domain.Peer{Type: domain.PeerTypeChannel, ID: 3001}, AccessHash: 31}
|
|
if err := dialogs.UpsertFolder(ctx, ownerID, domain.DialogFolder{
|
|
ID: 2,
|
|
Title: "Team",
|
|
IncludePeers: []domain.DialogFolderPeer{peer},
|
|
}); err != nil {
|
|
t.Fatalf("seed folder: %v", err)
|
|
}
|
|
|
|
nextSlug := 0
|
|
slugger := func() (string, error) {
|
|
nextSlug++
|
|
return "slug-limit-" + string(rune('a'+nextSlug)), nil
|
|
}
|
|
svc := NewService(chatlists, dialogs, WithSlugGenerator(slugger))
|
|
for i := 0; i < domain.MaxChatlistInvitesDefault; i++ {
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "", []domain.DialogFolderPeer{peer}, i+1); err != nil {
|
|
t.Fatalf("ExportInvite default #%d: %v", i+1, err)
|
|
}
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "", []domain.DialogFolderPeer{peer}, 10); !errors.Is(err, domain.ErrChatlistInvitesTooMuch) {
|
|
t.Fatalf("ExportInvite over default limit err = %v, want ErrChatlistInvitesTooMuch", err)
|
|
}
|
|
if _, err := svc.EditInvite(ctx, ownerID, 2, "slug-limit-b", nil, nil, true); err != nil {
|
|
t.Fatalf("EditInvite revoke first default link: %v", err)
|
|
}
|
|
if _, _, err := svc.ExportInvite(ctx, ownerID, 2, "", []domain.DialogFolderPeer{peer}, 11); err != nil {
|
|
t.Fatalf("ExportInvite after revoked link freed active limit: %v", err)
|
|
}
|
|
|
|
premiumSvc := NewService(
|
|
chatlists,
|
|
dialogs,
|
|
WithSlugGenerator(slugger),
|
|
WithPremiumChecker(func(context.Context, int64) bool { return true }),
|
|
)
|
|
if _, _, err := premiumSvc.ExportInvite(ctx, ownerID, 2, "", []domain.DialogFolderPeer{peer}, 11); err != nil {
|
|
t.Fatalf("ExportInvite premium extra link: %v", err)
|
|
}
|
|
}
|
|
|
|
type fakeChatlistChannels struct {
|
|
getIDs []int64
|
|
inviteIDs []int64
|
|
joinIDs []int64
|
|
leaveIDs []int64
|
|
publicOnly bool
|
|
}
|
|
|
|
func (f *fakeChatlistChannels) GetChannel(_ context.Context, userID, channelID int64) (domain.ChannelView, error) {
|
|
f.getIDs = append(f.getIDs, channelID)
|
|
role := domain.ChannelRoleCreator
|
|
if f.publicOnly {
|
|
role = domain.ChannelRoleMember
|
|
}
|
|
return domain.ChannelView{
|
|
Channel: domain.Channel{
|
|
ID: channelID,
|
|
AccessHash: channelID * 10,
|
|
Title: "Team",
|
|
Username: "team",
|
|
Megagroup: true,
|
|
},
|
|
Self: domain.ChannelMember{
|
|
ChannelID: channelID,
|
|
UserID: userID,
|
|
Role: role,
|
|
Status: domain.ChannelMemberActive,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (f *fakeChatlistChannels) InviteToChannel(_ context.Context, userID, channelID int64, userIDs []int64, date int) (domain.CreateChannelResult, error) {
|
|
f.inviteIDs = append(f.inviteIDs, channelID)
|
|
if len(userIDs) == 0 {
|
|
return domain.CreateChannelResult{}, domain.ErrUsersTooMuch
|
|
}
|
|
return fakeChatlistChannelResult(userIDs[0], channelID, domain.ChannelMemberActive, date), nil
|
|
}
|
|
|
|
func (f *fakeChatlistChannels) JoinChannel(_ context.Context, userID, channelID int64, date int) (domain.CreateChannelResult, error) {
|
|
f.joinIDs = append(f.joinIDs, channelID)
|
|
return fakeChatlistChannelResult(userID, channelID, domain.ChannelMemberActive, date), nil
|
|
}
|
|
|
|
func (f *fakeChatlistChannels) LeaveChannel(_ context.Context, userID, channelID int64, date int) (domain.CreateChannelResult, error) {
|
|
f.leaveIDs = append(f.leaveIDs, channelID)
|
|
return fakeChatlistChannelResult(userID, channelID, domain.ChannelMemberLeft, date), nil
|
|
}
|
|
|
|
func fakeChatlistChannelResult(userID, channelID int64, status domain.ChannelMemberStatus, date int) domain.CreateChannelResult {
|
|
return domain.CreateChannelResult{
|
|
Channel: domain.Channel{
|
|
ID: channelID,
|
|
AccessHash: channelID * 10,
|
|
Title: "Team",
|
|
Username: "team",
|
|
Megagroup: true,
|
|
Date: date,
|
|
},
|
|
Members: []domain.ChannelMember{{
|
|
ChannelID: channelID,
|
|
UserID: userID,
|
|
Role: domain.ChannelRoleMember,
|
|
Status: status,
|
|
JoinedAt: date,
|
|
}},
|
|
Recipients: []int64{userID},
|
|
}
|
|
}
|