using BuildFlow.Platform.Application.Users.DTOs; using BuildFlow.Platform.Application.Users.Queries; using FluentAssertions; using IM.Application.Chat.Commands; using IM.Application.Chat.Handlers; using IM.Domain.Enums; using IM.Infrastructure.Persistence; using MediatR; using Microsoft.EntityFrameworkCore; using Moq; using Xunit; namespace BuildFlow.IM.Tests.Chat; /// /// CreatePrivateConversationCommandHandler:幂等创建私聊(A↔B 仅一条),返回 OtherUserId。 /// public class CreatePrivateConversationCommandHandlerTests { private static readonly Guid Current = Guid.Parse("22222222-2222-2222-2222-222222222222"); private static readonly Guid Target = Guid.Parse("33333333-3333-3333-3333-333333333333"); private static IMediator NewMediator() { var mediator = new Mock(); mediator.Setup(m => m.Send(It.IsAny(), It.IsAny())) .ReturnsAsync(new Dictionary { [Target] = new UserSummaryDto(Target, "Bob", null) }); return mediator.Object; } [Fact] public async Task Creates_new_private_conversation() { await using var db = IMTestDb.Create(); var handler = new CreatePrivateConversationCommandHandler(db, NewMediator()); var result = await handler.Handle(new CreatePrivateConversationCommand(Current, Target), CancellationToken.None); result.Type.Should().Be(ConversationTypeEnum.Private); result.OtherUserId.Should().Be(Target); (await db.Conversations.CountAsync(c => c.Type == ConversationTypeEnum.Private)).Should().Be(1); } [Fact] public async Task Returns_same_conversation_when_called_again() { await using var db = IMTestDb.Create(); var handler = new CreatePrivateConversationCommandHandler(db, NewMediator()); var first = await handler.Handle(new CreatePrivateConversationCommand(Current, Target), CancellationToken.None); var second = await handler.Handle(new CreatePrivateConversationCommand(Current, Target), CancellationToken.None); second.Id.Should().Be(first.Id); (await db.Conversations.CountAsync(c => c.Type == ConversationTypeEnum.Private)).Should().Be(1); } }