package members import ( "context" "testing" "time" "github.com/stretchr/testify/require" "go.mau.fi/mautrix-telegram/pkg/gotd/testutil" "go.mau.fi/mautrix-telegram/pkg/gotd/tg" ) func TestChannelMembers_Count(t *testing.T) { a := require.New(t) ctx := context.Background() mock, m := testManager(t) ch := m.Channel(getTestChannel()) members := Channel(ch) mock.ExpectCall(&tg.ChannelsGetParticipantsRequest{ Channel: ch.InputChannel(), Filter: &tg.ChannelParticipantsRecent{}, Offset: 0, Limit: 1, }).ThenErr(testutil.TestError()) _, err := members.Count(ctx) a.Error(err) mock.ExpectCall(&tg.ChannelsGetParticipantsRequest{ Channel: ch.InputChannel(), Filter: &tg.ChannelParticipantsRecent{}, Offset: 0, Limit: 1, }).ThenResult(&tg.ChannelsChannelParticipantsNotModified{}) _, err = members.Count(ctx) a.Error(err) mock.ExpectCall(&tg.ChannelsGetParticipantsRequest{ Channel: ch.InputChannel(), Filter: &tg.ChannelParticipantsRecent{}, Offset: 0, Limit: 1, }).ThenResult(&tg.ChannelsChannelParticipants{ Count: 10, }) count, err := members.Count(ctx) a.NoError(err) a.Equal(10, count) } func TestChannelMembers_ForEach(t *testing.T) { ctx := context.Background() now := time.Now() date := int(now.Unix()) t.Run("Good", func(t *testing.T) { a := require.New(t) mock, m := testManager(t) rawCh := getTestChannel() rawCh.Date = date ch := m.Channel(rawCh) members := Channel(ch) mock.ExpectCall(&tg.ChannelsGetFullChannelRequest{ Channel: ch.InputChannel(), }).ThenResult(&tg.MessagesChatFull{ FullChat: getTestChannelFull(), }) mock.ExpectCall(&tg.ChannelsGetParticipantsRequest{ Channel: ch.InputChannel(), Filter: &tg.ChannelParticipantsRecent{}, Offset: 0, Limit: 100, }).ThenResult(&tg.ChannelsChannelParticipants{ Count: 10, Participants: []tg.ChannelParticipantClass{ &tg.ChannelParticipant{ UserID: 10, Date: date, }, &tg.ChannelParticipantSelf{ UserID: 10, InviterID: 11, Date: date, }, &tg.ChannelParticipantCreator{ UserID: 10, Rank: "rank", }, &tg.ChannelParticipantAdmin{ UserID: 10, InviterID: 11, Date: date, Rank: "rank", }, &tg.ChannelParticipantBanned{ Peer: &tg.PeerUser{UserID: 10}, Date: date, }, &tg.ChannelParticipantLeft{ Peer: &tg.PeerUser{UserID: 10}, }, }, Users: []tg.UserClass{ &tg.User{ ID: 10, AccessHash: 10, }, &tg.User{ ID: 11, AccessHash: 10, }, }, }).ExpectCall(&tg.ChannelsGetParticipantsRequest{ Channel: ch.InputChannel(), Filter: &tg.ChannelParticipantsRecent{}, Offset: 100, Limit: 100, }).ThenResult(&tg.ChannelsChannelParticipants{ Count: 10, }) expected := []struct { Status Status JoinDate time.Time JoinDateSet bool Rank string RankSet bool InviterID int64 }{ {Status: Plain, JoinDate: now, JoinDateSet: true}, {Status: Plain, JoinDate: now, JoinDateSet: true, InviterID: 11}, {Status: Creator, Rank: "rank", RankSet: true, JoinDate: now, JoinDateSet: true}, {Status: Admin, Rank: "rank", RankSet: true, JoinDate: now, JoinDateSet: true, InviterID: 11}, {Status: Banned, JoinDate: now, JoinDateSet: true}, {Status: Left}, } i := 0 a.NoError(members.ForEach(ctx, func(m Member) error { p := m.(ChannelMember) e := expected[i] a.Equal(e.Status, p.Status(), i) a.Equal(int64(10), p.User().ID()) if join, ok := p.JoinDate(); e.JoinDateSet { a.True(ok, i) a.Equal(e.JoinDate.Unix(), join.Unix(), i) } else { a.False(ok, i) } if rank, ok := p.Rank(); e.RankSet { a.True(ok, i) a.Equal(e.Rank, rank, i) } else { a.False(ok, i) } if inviter, ok := p.InvitedBy(); e.InviterID != 0 { a.True(ok, i) a.Equal(e.InviterID, inviter.ID()) } else { a.False(ok, i) } i++ return nil })) }) t.Run("ChannelInfoUnavailableError", func(t *testing.T) { a := require.New(t) mock, m := testManager(t) rawCh := getTestChannel() rawCh.Date = date ch := m.Channel(rawCh) rawFull := &tg.ChannelFull{ HasScheduled: true, ID: 11, About: "garfield blog", ParticipantsCount: 1, ChatPhoto: &tg.PhotoEmpty{}, } rawFull.SetFlags() mock.ExpectCall(&tg.ChannelsGetFullChannelRequest{ Channel: ch.InputChannel(), }).ThenResult(&tg.MessagesChatFull{ FullChat: rawFull, }) members := Channel(ch) var targetErr *ChannelInfoUnavailableError a.ErrorAs(members.ForEach(ctx, func(p Member) error { return nil }), &targetErr) }) } func TestChannelMembers_Kick(t *testing.T) { a := require.New(t) ctx := context.Background() mock, m := testManager(t) u := m.User(getTestUser()) ch := m.Channel(getTestChannel()) members := Channel(ch) rights := tg.ChatBannedRights{ ViewMessages: true, } rights.SetFlags() member := ChannelMember{ parent: members, user: u, raw: &tg.ChannelParticipant{}, } mock.ExpectCall(&tg.ChannelsEditBannedRequest{ Channel: ch.InputChannel(), Participant: u.InputPeer(), BannedRights: rights, }).ThenRPCErr(getTestError()) a.Error(member.Kick(ctx, false)) mock.ExpectCall(&tg.ChannelsDeleteParticipantHistoryRequest{ Channel: ch.InputChannel(), Participant: u.InputPeer(), }).ThenRPCErr(getTestError()) a.Error(member.Kick(ctx, true)) mock.ExpectCall(&tg.ChannelsEditBannedRequest{ Channel: ch.InputChannel(), Participant: u.InputPeer(), BannedRights: rights, }).ThenResult(&tg.Updates{}) a.NoError(member.Kick(ctx, false)) mock.ExpectCall(&tg.ChannelsDeleteParticipantHistoryRequest{ Channel: ch.InputChannel(), Participant: u.InputPeer(), }).ThenResult(&tg.MessagesAffectedHistory{}) mock.ExpectCall(&tg.ChannelsEditBannedRequest{ Channel: ch.InputChannel(), Participant: u.InputPeer(), BannedRights: rights, }).ThenResult(&tg.Updates{}) a.NoError(member.Kick(ctx, true)) } func TestChannelMembers_EditAdminRights(t *testing.T) { a := require.New(t) ctx := context.Background() mock, m := testManager(t) u := m.User(getTestUser()) ch := m.Channel(getTestChannel()) members := Channel(ch) rights := tg.ChatAdminRights{ AddAdmins: true, } rights.SetFlags() mock.ExpectCall(&tg.ChannelsEditAdminRequest{ Channel: ch.InputChannel(), UserID: u.InputUser(), AdminRights: rights, Rank: "rank", }).ThenRPCErr(getTestError()) a.Error(members.EditAdminRights(ctx, u.InputUser(), AdminRights{ Rank: "rank", AddAdmins: true, })) mock.ExpectCall(&tg.ChannelsEditAdminRequest{ Channel: ch.InputChannel(), UserID: u.InputUser(), AdminRights: rights, Rank: "rank", }).ThenResult(&tg.Updates{}) a.NoError(members.EditAdminRights(ctx, u.InputUser(), AdminRights{ Rank: "rank", AddAdmins: true, })) }