using BuildFlow.Platform.Application.Users.DTOs; using BuildFlow.Platform.Application.Users.Queries; using IM.Application.Chat.Handlers; using IM.Application.Chat.Queries; using IM.Domain.Common; using IM.Domain.Enums; using IM.Infrastructure.Persistence; using MediatR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Moq; using Xunit; namespace BuildFlow.IM.Tests.Chat; /// /// GetConversationsQueryHandler 的会话列表断言:未读数展示必须优先使用 Redis 热数据。 /// public class GetConversationsQueryHandlerTests { private static readonly Guid UserId = Guid.Parse("22222222-2222-2222-2222-222222222222"); private static readonly Guid OtherUserId = Guid.Parse("33333333-3333-3333-3333-333333333333"); private static readonly Guid ConversationId = Guid.Parse("11111111-1111-1111-1111-111111111111"); [Fact] public async Task Uses_redis_unread_in_conversation_list_when_pg_cold_backup_is_zero() { await using var db = BuildInMemoryDb(); db.Conversations.Add(ImTestData.BuildConversation( ConversationId, ConversationTypeEnum.Private, (UserId, 0), (OtherUserId, 0))); await db.SaveChangesAsync(); var mediator = new Mock(); mediator .Setup(m => m.Send( It.Is(q => q.UserIds.SequenceEqual(new[] { OtherUserId })), It.IsAny())) .ReturnsAsync(new Dictionary { [OtherUserId] = new(OtherUserId, "Bob", null) }); var unreadCounter = new Mock(); unreadCounter .Setup(c => c.GetByUserAsync( UserId, It.Is>(ids => ids.SequenceEqual(new[] { ConversationId })), It.IsAny())) .ReturnsAsync(new Dictionary { [ConversationId] = 2 }); var handler = new GetConversationsQueryHandler(db, mediator.Object, unreadCounter.Object); var result = await handler.Handle(new GetConversationsQuery(UserId), CancellationToken.None); var conversation = Assert.Single(result); Assert.Equal(2, conversation.UnreadCount); Assert.Equal("Bob", conversation.OtherUserName); mediator.Verify(m => m.Send( It.Is(q => q.UserIds.SequenceEqual(new[] { OtherUserId })), It.IsAny()), Times.Once); } private static ImDbContext BuildInMemoryDb() { var services = new ServiceCollection(); services.AddDbContext(o => o.UseInMemoryDatabase($"im-conversation-{Guid.NewGuid()}")); return services.BuildServiceProvider().GetRequiredService(); } }