Beispiel #1
0
        public async Task GetLastValidChannelMessage()
        {
            var channel         = fillTestDbHelper.Channels.FirstOrDefault();
            var expectedMessage = fillTestDbHelper.Messages
                                  .OrderByDescending(opt => opt.SendingTime)
                                  .FirstOrDefault(opt => !opt.Deleted && opt.ChannelId == channel.ChannelId);
            var actualMessage = await loadMessagesService.GetLastValidChannelMessageAsync(channel.ChannelId);

            Assert.Equal(expectedMessage.GlobalId, actualMessage.GlobalId);
        }
        private async Task <List <MessageDto> > DeleteChannelMessagesInfoAsync(long channelId, IEnumerable <Guid> messagesIds, long userId)
        {
            try
            {
                using (MessengerDbContext context = contextFactory.Create())
                {
                    var messagesCondition = PredicateBuilder.New <Message>();
                    messagesCondition = messagesIds.Aggregate(messagesCondition,
                                                              (current, value) => current.Or(opt => opt.GlobalId == value).Expand());
                    var channelUser = await context.ChannelUsers
                                      .Include(opt => opt.Channel)
                                      .FirstOrDefaultAsync(opt =>
                                                           opt.ChannelId == channelId &&
                                                           opt.UserId == userId &&
                                                           opt.ChannelUserRole >= ChannelUserRole.Administrator)
                                      .ConfigureAwait(false);

                    if (channelUser == null)
                    {
                        throw new PermissionDeniedException();
                    }

                    var messages = await context.Messages
                                   .Include(opt => opt.Attachments)
                                   .Where(messagesCondition)
                                   .Where(opt => opt.ChannelId == channelId)
                                   .ToListAsync()
                                   .ConfigureAwait(false);

                    if (!messages.Any())
                    {
                        return(new List <MessageDto>());
                    }
                    var deletedMessagesIds = messages.Select(message => message.GlobalId).ToList();
                    var usersCondition     = PredicateBuilder.New <ChannelUser>();
                    usersCondition = deletedMessagesIds.Aggregate(usersCondition,
                                                                  (current, value) => current.Or(opt => opt.LastReadedGlobalMessageId == value).Expand());
                    var channelUsers = await context.ChannelUsers.Where(usersCondition).ToListAsync().ConfigureAwait(false);

                    var groupedChannelUsers = channelUsers.GroupBy(opt => opt.LastReadedGlobalMessageId);
                    foreach (var group in groupedChannelUsers)
                    {
                        var message = await context.Messages
                                      .OrderByDescending(opt => opt.SendingTime)
                                      .ThenBy(opt => opt.GlobalId)
                                      .Where(opt => !deletedMessagesIds.Contains(opt.GlobalId) && opt.ChannelId == channelId && !opt.Deleted)
                                      .FirstOrDefaultAsync()
                                      .ConfigureAwait(false);

                        foreach (var user in group)
                        {
                            user.LastReadedGlobalMessageId = message?.GlobalId;
                        }
                        context.ChannelUsers.UpdateRange(group);
                    }
                    var deletedMessages = MessageConverter.GetMessagesDto(messages);
                    messages.ForEach(message =>
                    {
                        message.Deleted   = true;
                        message.UpdatedAt = DateTime.UtcNow.ToUnixTime();
                        if (NodeSettings.Configs.Node.PermanentlyDeleting)
                        {
                            message.Attachments = null;
                            message.Replyto     = null;
                            message.SendingTime = 0;
                            message.Text        = null;
                            message.SenderId    = null;
                        }
                    });
                    context.UpdateRange(messages);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    Message lastValidMessage = await _loadMessagesService.GetLastValidChannelMessageAsync(channelId).ConfigureAwait(false);

                    channelUser.Channel.LastMessageId       = lastValidMessage?.Id ?? null;
                    channelUser.Channel.LastMessageGlobalId = lastValidMessage?.GlobalId;
                    context.Update(channelUser);
                    await context.SaveChangesAsync().ConfigureAwait(false);

                    return(deletedMessages);
                }
            }
            catch (Exception ex)
            {
                throw new DeleteMessagesException("An error ocurred while deleting the messages.", ex);
            }
        }