public async Task GetLastValidChatMessage() { var chat = fillTestDbHelper.Chats.FirstOrDefault(); var expectedMessage = fillTestDbHelper.Messages .OrderByDescending(opt => opt.SendingTime) .FirstOrDefault(opt => !opt.Deleted && opt.ChatId == chat.Id); var actualMessage = await loadMessagesService.GetLastValidChatMessageAsync(chat.Id); Assert.Equal(expectedMessage.GlobalId, actualMessage.GlobalId); }
private async Task <List <MessageDto> > DeleteChatMessagesInfoAsync(long chatId, 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 && opt.ChatId == chatId && opt.Deleted == false)); var query = from conversation in context.Chats join chatUser in context.ChatUsers on conversation.Id equals chatUser.ChatId where chatUser.Banned == false && chatUser.Deleted == false && conversation.Deleted == false && chatUser.UserId == userId && conversation.Id == chatId select new { Chat = conversation, User = chatUser }; var result = await query.FirstOrDefaultAsync().ConfigureAwait(false); if (result == null || result.User == null) { return(new List <MessageDto>()); } List <Message> messages = await context.Messages .Include(opt => opt.Attachments) .Where(messagesCondition) .ToListAsync() .ConfigureAwait(false); if (!messages.Any()) { return(new List <MessageDto>()); } var deletedMessagesIds = messages.Select(message => message.GlobalId).ToList(); var usersCondition = PredicateBuilder.New <ChatUser>(); usersCondition = deletedMessagesIds.Aggregate(usersCondition, (current, value) => current.Or(opt => opt.LastReadedGlobalMessageId == value).Expand()); var chatUsers = await context.ChatUsers.Where(usersCondition).ToListAsync().ConfigureAwait(false); var groupedChatUsers = chatUsers.GroupBy(opt => opt.LastReadedGlobalMessageId); foreach (var group in groupedChatUsers) { var message = await context.Messages .OrderByDescending(opt => opt.SendingTime) .ThenBy(opt => opt.GlobalId) .Where(opt => !deletedMessagesIds.Contains(opt.GlobalId) && opt.ChatId == chatId && !opt.Deleted) .FirstOrDefaultAsync() .ConfigureAwait(false); foreach (var chatUser in group) { chatUser.LastReadedGlobalMessageId = message?.GlobalId; } context.ChatUsers.UpdateRange(group); } List <MessageDto> deletedMessages = MessageConverter.GetMessagesDto(messages); foreach (var message in messages) { if (message.SenderId != result.User.UserId && result.User.UserRole == UserRole.User) { continue; } 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 lastMessage = await _loadMessagesService.GetLastValidChatMessageAsync(chatId).ConfigureAwait(false); result.Chat.LastMessageId = lastMessage?.Id ?? null; result.Chat.LastMessageGlobalId = lastMessage?.GlobalId; context.Update(result.Chat); await context.SaveChangesAsync().ConfigureAwait(false); return(deletedMessages); } } catch (Exception ex) { throw new DeleteMessagesException("An error occurred while deleting messages.", ex); } }