owpengram-server/internal/rpc/rpc_testkit_messages_test.go
2026-09-01 12:06:31 +03:00

624 lines
21 KiB
Go

package rpc
import (
"context"
"telesrv/internal/domain"
)
type captureMessages struct {
list domain.MessageList
filter domain.MessageFilter
sendResult domain.SendPrivateTextResult
sendUserID int64
sendReq domain.SendPrivateTextRequest
setThemeUserID int64
setThemeReq domain.SetPrivateChatThemeRequest
setThemeRes domain.SetPrivateChatThemeResult
forwardUserID int64
forwardReq domain.ForwardPrivateMessagesRequest
forwardRes domain.ForwardPrivateMessagesResult
readResult domain.ReadHistoryResult
readReq domain.ReadHistoryRequest
readPeer domain.Peer
readMaxID int
readContentsReq domain.ReadMessageContentsRequest
readContentsRes domain.ReadMessageContentsResult
setReactionReq domain.SetPrivateMessageReactionsRequest
setReactionRes domain.PrivateMessageReactionsResult
getReactionReq domain.PrivateMessageReactionsRequest
getReactionRes domain.PrivateMessageReactionsResult
savedTagPeer domain.Peer
savedTags []domain.SavedReactionTag
updatedSavedTag domain.SavedReactionTag
savedTagErr error
getMessagesCalls int
getMessagesIDs [][]int
getMessagesListed bool
editReq domain.EditMessageRequest
editRes domain.EditMessageResult
outboxReadDateReq domain.OutboxReadDateRequest
outboxReadDate int
deleteMessagesReq domain.DeleteMessagesRequest
deleteMessagesRes domain.DeleteMessagesResult
deleteHistoryReq domain.DeleteHistoryRequest
deleteHistoryRes domain.DeleteMessagesResult
mediaReq domain.MediaSearchRequest
}
type scheduledCaptureMessages struct {
*captureMessages
scheduled []domain.ScheduledMessage
scheduleReq domain.ScheduleMessageRequest
editScheduledReq domain.EditScheduledMessageRequest
claimScheduledReq domain.ScheduledMessageClaim
deletedScheduled domain.ScheduledMessageFilter
markedScheduledID int
markedSentID int
releasedScheduled int
releasedErrMessage string
}
type ttlCaptureMessages struct {
*captureMessages
setTTLUserID int64
setTTLPeer domain.Peer
setTTLPeriod int
defaultTTLUserID int64
defaultTTLPeriod int
expiredPrivateClaims []domain.DeleteMessagesRequest
}
func (s *ttlCaptureMessages) GetPrivateHistoryTTL(_ context.Context, _ int64, _ domain.Peer) (int, error) {
return s.setTTLPeriod, nil
}
func (s *ttlCaptureMessages) SetPrivateHistoryTTL(_ context.Context, userID int64, peer domain.Peer, period int) error {
s.setTTLUserID = userID
s.setTTLPeer = peer
s.setTTLPeriod = period
return nil
}
func (s *ttlCaptureMessages) DefaultHistoryTTL(_ context.Context, userID int64) (int, error) {
s.defaultTTLUserID = userID
return s.defaultTTLPeriod, nil
}
func (s *ttlCaptureMessages) SetDefaultHistoryTTL(_ context.Context, userID int64, period int) error {
s.defaultTTLUserID = userID
s.defaultTTLPeriod = period
return nil
}
func (s *ttlCaptureMessages) ClaimExpiredPrivateMessages(context.Context, int, int) ([]domain.DeleteMessagesRequest, error) {
return append([]domain.DeleteMessagesRequest(nil), s.expiredPrivateClaims...), nil
}
func (s *scheduledCaptureMessages) ScheduleMessage(_ context.Context, userID int64, req domain.ScheduleMessageRequest) (domain.ScheduledMessage, error) {
s.scheduleReq = req
if req.OwnerUserID == 0 {
req.OwnerUserID = userID
}
msg := domain.ScheduledMessage{
OwnerUserID: req.OwnerUserID,
ID: len(s.scheduled) + 41,
Peer: req.Peer,
RandomID: req.RandomID,
Message: req.Message,
Entities: append([]domain.MessageEntity(nil), req.Entities...),
Media: req.Media,
Silent: req.Silent,
NoForwards: req.NoForwards,
ReplyTo: req.ReplyTo,
Forward: req.Forward,
SendAs: req.SendAs,
ScheduleDate: req.ScheduleDate,
ScheduleRepeatPeriod: req.ScheduleRepeatPeriod,
CreatedAt: req.Date,
UpdatedAt: req.Date,
State: "pending",
}
s.scheduled = append(s.scheduled, msg)
return msg, nil
}
func (s *scheduledCaptureMessages) EditScheduledMessage(_ context.Context, userID int64, req domain.EditScheduledMessageRequest) (domain.ScheduledMessage, error) {
s.editScheduledReq = req
if req.OwnerUserID == 0 {
req.OwnerUserID = userID
}
for i := range s.scheduled {
if s.scheduled[i].OwnerUserID == req.OwnerUserID && s.scheduled[i].Peer == req.Peer && s.scheduled[i].ID == req.ID {
if req.SetMessage {
s.scheduled[i].Message = req.Message
s.scheduled[i].Entities = append([]domain.MessageEntity(nil), req.Entities...)
}
s.scheduled[i].ScheduleDate = req.ScheduleDate
s.scheduled[i].UpdatedAt = req.Date
return s.scheduled[i], nil
}
}
return domain.ScheduledMessage{}, domain.ErrMessageIDInvalid
}
func (s *scheduledCaptureMessages) ListScheduledMessages(_ context.Context, userID int64, filter domain.ScheduledMessageFilter) (domain.ScheduledMessageList, error) {
if filter.OwnerUserID == 0 {
filter.OwnerUserID = userID
}
items := s.matchScheduled(filter)
return domain.ScheduledMessageList{Messages: items, Count: len(items)}, nil
}
func (s *scheduledCaptureMessages) GetScheduledMessages(_ context.Context, userID int64, filter domain.ScheduledMessageFilter) (domain.ScheduledMessageList, error) {
if filter.OwnerUserID == 0 {
filter.OwnerUserID = userID
}
items := s.matchScheduled(filter)
return domain.ScheduledMessageList{Messages: items, Count: len(items)}, nil
}
func (s *scheduledCaptureMessages) DeleteScheduledMessages(_ context.Context, userID int64, filter domain.ScheduledMessageFilter, _ int) ([]domain.ScheduledMessage, error) {
if filter.OwnerUserID == 0 {
filter.OwnerUserID = userID
}
s.deletedScheduled = filter
deleted := s.matchScheduled(filter)
s.removeScheduled(filter)
return deleted, nil
}
func (s *scheduledCaptureMessages) ClaimScheduledMessages(_ context.Context, userID int64, claim domain.ScheduledMessageClaim) ([]domain.ScheduledMessage, error) {
if claim.OwnerUserID == 0 {
claim.OwnerUserID = userID
}
s.claimScheduledReq = claim
return s.matchScheduled(domain.ScheduledMessageFilter{OwnerUserID: claim.OwnerUserID, Peer: claim.Peer, IDs: claim.IDs}), nil
}
func (s *scheduledCaptureMessages) ClaimDueScheduledMessages(context.Context, int, int, int) ([]domain.ScheduledMessage, error) {
return nil, nil
}
func (s *scheduledCaptureMessages) MarkScheduledMessageSent(_ context.Context, _ int64, id, sentMessageID, _ int) error {
s.markedScheduledID = id
s.markedSentID = sentMessageID
s.removeScheduled(domain.ScheduledMessageFilter{OwnerUserID: s.scheduleReq.OwnerUserID, Peer: s.scheduleReq.Peer, IDs: []int{id}})
return nil
}
func (s *scheduledCaptureMessages) ReleaseScheduledMessage(_ context.Context, _ int64, id int, errText string) error {
s.releasedScheduled = id
s.releasedErrMessage = errText
return nil
}
func (s *scheduledCaptureMessages) HasScheduledMessages(_ context.Context, userID int64, peer domain.Peer) (bool, error) {
return len(s.matchScheduled(domain.ScheduledMessageFilter{OwnerUserID: userID, Peer: peer})) > 0, nil
}
func (s *scheduledCaptureMessages) matchScheduled(filter domain.ScheduledMessageFilter) []domain.ScheduledMessage {
idSet := make(map[int]struct{}, len(filter.IDs))
for _, id := range filter.IDs {
idSet[id] = struct{}{}
}
out := make([]domain.ScheduledMessage, 0, len(s.scheduled))
for _, msg := range s.scheduled {
if filter.OwnerUserID != 0 && msg.OwnerUserID != filter.OwnerUserID {
continue
}
if filter.Peer.ID != 0 && msg.Peer != filter.Peer {
continue
}
if len(idSet) > 0 {
if _, ok := idSet[msg.ID]; !ok {
continue
}
}
out = append(out, msg)
}
return out
}
func (s *scheduledCaptureMessages) removeScheduled(filter domain.ScheduledMessageFilter) {
idSet := make(map[int]struct{}, len(filter.IDs))
for _, id := range filter.IDs {
idSet[id] = struct{}{}
}
kept := s.scheduled[:0]
for _, msg := range s.scheduled {
if filter.OwnerUserID != 0 && msg.OwnerUserID != filter.OwnerUserID {
kept = append(kept, msg)
continue
}
if filter.Peer.ID != 0 && msg.Peer != filter.Peer {
kept = append(kept, msg)
continue
}
if len(idSet) > 0 {
if _, ok := idSet[msg.ID]; ok {
continue
}
}
kept = append(kept, msg)
}
s.scheduled = kept
}
func (s *captureMessages) SendPrivateText(_ context.Context, userID int64, req domain.SendPrivateTextRequest) (domain.SendPrivateTextResult, error) {
s.sendUserID = userID
s.sendReq = req
if s.sendResult.SenderMessage.ID == 0 {
s.sendResult.SenderMessage = domain.Message{
ID: 1,
OwnerUserID: req.SenderUserID,
RandomID: req.RandomID,
Peer: domain.Peer{Type: domain.PeerTypeUser, ID: req.RecipientUserID},
From: domain.Peer{Type: domain.PeerTypeUser, ID: req.SenderUserID},
Date: req.Date,
Out: true,
Silent: req.Silent,
NoForwards: req.NoForwards,
Body: req.Message,
Entities: req.Entities,
Media: req.Media,
ReplyTo: req.ReplyTo,
Forward: req.Forward,
ViaBotID: req.ViaBotID,
Pts: 1,
}
s.sendResult.SenderEvent = domain.UpdateEvent{
UserID: req.SenderUserID,
Type: domain.UpdateEventNewMessage,
Pts: 1,
PtsCount: 1,
Date: req.Date,
Message: s.sendResult.SenderMessage,
}
}
return s.sendResult, nil
}
func (s *captureMessages) SetChatTheme(_ context.Context, userID int64, req domain.SetPrivateChatThemeRequest) (domain.SetPrivateChatThemeResult, error) {
s.setThemeUserID = userID
s.setThemeReq = req
if s.setThemeRes.OwnerUserID == 0 {
s.setThemeRes = domain.SetPrivateChatThemeResult{
OwnerUserID: userID,
Peer: req.Peer,
Emoticon: req.Emoticon,
Changed: true,
Send: domain.SendPrivateTextResult{
SenderMessage: domain.Message{
ID: 1,
OwnerUserID: userID,
Peer: req.Peer,
From: domain.Peer{Type: domain.PeerTypeUser, ID: userID},
Date: req.Date,
Out: true,
Media: &domain.MessageMedia{
Kind: domain.MessageMediaKindService,
ServiceAction: &domain.MessageServiceAction{
Kind: domain.MessageServiceActionSetChatTheme,
ChatThemeEmoticon: req.Emoticon,
},
},
Pts: 1,
},
SenderEvent: domain.UpdateEvent{
UserID: userID,
Type: domain.UpdateEventNewMessage,
Pts: 1,
PtsCount: 1,
Date: req.Date,
},
},
}
s.setThemeRes.Send.SenderEvent.Message = s.setThemeRes.Send.SenderMessage
}
return s.setThemeRes, nil
}
func (s *captureMessages) ForwardPrivateMessages(_ context.Context, userID int64, req domain.ForwardPrivateMessagesRequest) (domain.ForwardPrivateMessagesResult, error) {
s.forwardUserID = userID
s.forwardReq = req
if len(s.forwardRes.SenderMessages) == 0 {
s.forwardRes.OwnerUserID = userID
s.forwardRes.SenderMessages = make([]domain.Message, 0, len(req.MessageIDs))
s.forwardRes.SenderEvents = make([]domain.UpdateEvent, 0, len(req.MessageIDs))
for i := range req.MessageIDs {
msg := domain.Message{
ID: i + 1,
OwnerUserID: req.OwnerUserID,
RandomID: req.RandomIDs[i],
Peer: domain.Peer{Type: domain.PeerTypeUser, ID: req.ToUserID},
From: domain.Peer{Type: domain.PeerTypeUser, ID: req.OwnerUserID},
Date: req.Date,
Out: true,
Silent: req.Silent,
NoForwards: req.NoForwards,
Body: "forwarded",
ReplyTo: req.ReplyTo,
Forward: &domain.MessageForward{From: domain.Peer{Type: domain.PeerTypeUser, ID: req.FromPeer.ID}, Date: req.Date - 1},
Pts: i + 1,
}
event := domain.UpdateEvent{
UserID: req.OwnerUserID,
Type: domain.UpdateEventNewMessage,
Pts: msg.Pts,
PtsCount: 1,
Date: req.Date,
Message: msg,
}
s.forwardRes.SenderMessages = append(s.forwardRes.SenderMessages, msg)
s.forwardRes.SenderEvents = append(s.forwardRes.SenderEvents, event)
}
}
return s.forwardRes, nil
}
func (s *captureMessages) GetMessages(_ context.Context, _ int64, ids []int) (domain.MessageList, error) {
s.getMessagesCalls++
s.getMessagesIDs = append(s.getMessagesIDs, append([]int(nil), ids...))
byID := make(map[int]domain.Message, len(s.list.Messages))
for _, msg := range s.list.Messages {
byID[msg.ID] = msg
}
out := domain.MessageList{Messages: make([]domain.Message, 0, len(ids)), Users: s.list.Users}
if s.getMessagesListed {
for _, msg := range s.list.Messages {
for _, id := range ids {
if msg.ID == id {
out.Messages = append(out.Messages, msg)
break
}
}
}
return out, nil
}
for _, id := range ids {
if msg, ok := byID[id]; ok {
out.Messages = append(out.Messages, msg)
}
}
return out, nil
}
func (s *captureMessages) GetHistory(_ context.Context, _ int64, filter domain.MessageFilter) (domain.MessageList, error) {
s.filter = filter
return s.list, nil
}
func (s *captureMessages) Search(_ context.Context, _ int64, filter domain.MessageFilter) (domain.MessageList, error) {
s.filter = filter
return s.list, nil
}
func (s *captureMessages) SearchPrivateMedia(_ context.Context, _, _ int64, req domain.MediaSearchRequest) (domain.MessageList, error) {
s.mediaReq = req
return domain.MessageList{}, nil
}
func (s *captureMessages) CountPrivateMediaCategories(_ context.Context, _, _ int64) (domain.MediaCategoryCounts, error) {
return domain.MediaCategoryCounts{}, nil
}
func (s *captureMessages) ReadHistory(_ context.Context, _ int64, req domain.ReadHistoryRequest) (domain.ReadHistoryResult, error) {
s.readReq = req
s.readPeer = req.Peer
s.readMaxID = req.MaxID
if s.readResult.OwnerUserID == 0 {
s.readResult.OwnerUserID = req.OwnerUserID
}
if s.readResult.Peer.ID == 0 {
s.readResult.Peer = req.Peer
}
if s.readResult.MaxID == 0 {
s.readResult.MaxID = req.MaxID
}
return s.readResult, nil
}
func (s *captureMessages) ReadMessageContents(_ context.Context, userID int64, req domain.ReadMessageContentsRequest) (domain.ReadMessageContentsResult, error) {
s.readContentsReq = req
if s.readContentsRes.OwnerUserID == 0 {
s.readContentsRes.OwnerUserID = userID
}
return s.readContentsRes, nil
}
func (s *captureMessages) GetOutboxReadDate(_ context.Context, _ int64, req domain.OutboxReadDateRequest) (int, error) {
s.outboxReadDateReq = req
if s.outboxReadDate == 0 {
return 0, domain.ErrMessageNotReadYet
}
return s.outboxReadDate, nil
}
func (s *captureMessages) SetMessageReactions(_ context.Context, userID int64, req domain.SetPrivateMessageReactionsRequest) (domain.PrivateMessageReactionsResult, error) {
s.setReactionReq = req
if len(s.setReactionRes.Messages) == 0 {
if len(req.Reactions) == 0 {
reactions := domain.ChannelMessageReactions{
CanSeeList: req.Peer.ID != userID,
AsTags: req.Peer.ID == userID,
Results: []domain.ChannelMessageReactionCount{},
Recent: []domain.ChannelMessagePeerReaction{},
}
s.setReactionRes = domain.PrivateMessageReactionsResult{
Messages: []domain.Message{{
ID: req.MessageID,
OwnerUserID: userID,
Peer: req.Peer,
From: domain.Peer{Type: domain.PeerTypeUser, ID: req.Peer.ID},
Date: req.Date,
Reactions: &reactions,
}},
Reactions: reactions,
}
return s.setReactionRes, nil
}
reactions := domain.ChannelMessageReactions{
CanSeeList: req.Peer.ID != userID,
AsTags: req.Peer.ID == userID,
Results: []domain.ChannelMessageReactionCount{{
Reaction: req.Reactions[0],
Count: 1,
ChosenOrder: 1,
}},
}
if req.Peer.ID != userID {
reactions.Recent = []domain.ChannelMessagePeerReaction{{
UserID: userID,
Reaction: req.Reactions[0],
My: true,
Big: req.Big,
ChosenOrder: 1,
Date: req.Date,
}}
}
s.setReactionRes = domain.PrivateMessageReactionsResult{
Messages: []domain.Message{{
ID: req.MessageID,
OwnerUserID: userID,
Peer: req.Peer,
From: domain.Peer{Type: domain.PeerTypeUser, ID: req.Peer.ID},
Date: req.Date,
Reactions: &reactions,
}},
Reactions: reactions,
}
}
return s.setReactionRes, nil
}
func (s *captureMessages) VoteMessagePoll(_ context.Context, _ int64, _ domain.VotePrivateMessagePollRequest) (domain.PrivateMessagePollResult, error) {
return domain.PrivateMessagePollResult{}, domain.ErrMessageIDInvalid
}
func (s *captureMessages) CloseMessagePoll(_ context.Context, _ int64, _ domain.ClosePrivateMessagePollRequest) (domain.PrivateMessagePollResult, error) {
return domain.PrivateMessagePollResult{}, domain.ErrMessageIDInvalid
}
func (s *captureMessages) GetMessageReactions(_ context.Context, userID int64, req domain.PrivateMessageReactionsRequest) (domain.PrivateMessageReactionsResult, error) {
s.getReactionReq = req
if len(s.getReactionRes.Messages) == 0 && len(req.IDs) > 0 {
reactions := domain.ChannelMessageReactions{CanSeeList: true, Results: []domain.ChannelMessageReactionCount{}, Recent: []domain.ChannelMessagePeerReaction{}}
s.getReactionRes = domain.PrivateMessageReactionsResult{
Messages: []domain.Message{{
ID: req.IDs[0],
OwnerUserID: userID,
Peer: req.Peer,
From: domain.Peer{Type: domain.PeerTypeUser, ID: req.Peer.ID},
Reactions: &reactions,
}},
Reactions: reactions,
}
}
return s.getReactionRes, nil
}
func (s *captureMessages) SavedReactionTags(_ context.Context, _ int64, savedPeer domain.Peer, _ int) ([]domain.SavedReactionTag, error) {
s.savedTagPeer = savedPeer
return append([]domain.SavedReactionTag(nil), s.savedTags...), s.savedTagErr
}
func (s *captureMessages) UpdateSavedReactionTag(_ context.Context, _ int64, tag domain.SavedReactionTag) error {
s.updatedSavedTag = tag
for i := range s.savedTags {
if s.savedTags[i].Reaction.Key() == tag.Reaction.Key() {
s.savedTags[i].Title = tag.Title
return s.savedTagErr
}
}
return s.savedTagErr
}
func (s *captureMessages) EditMessage(_ context.Context, userID int64, req domain.EditMessageRequest) (domain.EditMessageResult, error) {
s.editReq = req
if s.editRes.OwnerUserID == 0 {
s.editRes.OwnerUserID = userID
}
if len(s.editRes.Edited) == 0 {
msg := domain.Message{
ID: req.ID,
OwnerUserID: req.OwnerUserID,
Peer: req.Peer,
From: domain.Peer{Type: domain.PeerTypeUser, ID: req.OwnerUserID},
Date: req.EditDate - 10,
EditDate: req.EditDate,
Out: true,
Body: req.Message,
Entities: append([]domain.MessageEntity(nil), req.Entities...),
Pts: 7,
}
s.editRes.Edited = []domain.EditedMessageForUser{{
UserID: req.OwnerUserID,
Message: msg,
Event: domain.UpdateEvent{
UserID: req.OwnerUserID,
Type: domain.UpdateEventEditMessage,
Pts: 7,
PtsCount: 1,
Date: req.EditDate,
Message: msg,
},
}}
}
return s.editRes, nil
}
func (s *captureMessages) DeleteMessages(_ context.Context, userID int64, req domain.DeleteMessagesRequest) (domain.DeleteMessagesResult, error) {
s.deleteMessagesReq = req
if s.deleteMessagesRes.OwnerUserID == 0 {
s.deleteMessagesRes.OwnerUserID = userID
}
return s.deleteMessagesRes, nil
}
func (s *captureMessages) GetSavedDialogs(_ context.Context, _ int64, _ domain.SavedDialogsFilter) (domain.SavedDialogList, error) {
return domain.SavedDialogList{}, nil
}
func (s *captureMessages) GetPinnedSavedDialogs(_ context.Context, _ int64) (domain.SavedDialogList, error) {
return domain.SavedDialogList{}, nil
}
func (s *captureMessages) GetSavedDialogsByPeers(_ context.Context, _ int64, _ []domain.Peer) (domain.SavedDialogList, error) {
return domain.SavedDialogList{}, nil
}
func (s *captureMessages) ToggleSavedDialogPin(_ context.Context, _ int64, _ domain.Peer, _ bool) (bool, error) {
return false, nil
}
func (s *captureMessages) ReorderPinnedSavedDialogs(_ context.Context, _ int64, _ []domain.Peer, _ bool) error {
return nil
}
func (s *captureMessages) DeleteSavedHistory(_ context.Context, _ int64, _ domain.DeleteSavedHistoryRequest) (domain.DeleteSavedHistoryResult, error) {
return domain.DeleteSavedHistoryResult{}, nil
}
func (s *captureMessages) DeleteHistory(_ context.Context, userID int64, req domain.DeleteHistoryRequest) (domain.DeleteMessagesResult, error) {
s.deleteHistoryReq = req
if s.deleteHistoryRes.OwnerUserID == 0 {
s.deleteHistoryRes.OwnerUserID = userID
}
return s.deleteHistoryRes, nil
}
func (s *captureMessages) PinPrivateMessage(_ context.Context, userID int64, req domain.PinPrivateMessageRequest) (domain.PinPrivateMessageResult, error) {
return domain.PinPrivateMessageResult{OwnerUserID: userID}, nil
}
func (s *captureMessages) UnpinAllPrivateMessages(_ context.Context, userID int64, req domain.UnpinAllPrivateMessagesRequest) (domain.PinPrivateMessageResult, error) {
return domain.PinPrivateMessageResult{OwnerUserID: userID}, nil
}
func (s *captureMessages) ListUnreadReactionMessages(_ context.Context, _ int64, _ domain.Peer, _ int) ([]domain.Message, error) {
return nil, nil
}
func (s *captureMessages) ReadPeerReactions(_ context.Context, _ int64, _ domain.Peer) (int, error) {
return 0, nil
}