using BuildFlow.Shared.Domain.Errors; using BuildFlow.Shared.Domain.Exceptions; using FluentAssertions; using IM.Application.Chat.Commands; using IM.Application.Chat.Handlers; using IM.Domain.Enums; using IM.Infrastructure.Persistence; using Microsoft.EntityFrameworkCore; using Xunit; namespace BuildFlow.IM.Tests.Chat; /// /// SetConversationPinnedCommandHandler:成功置顶(IsPinned=true, PinnedAt 有值)/ 取消置顶 /// (IsPinned=false, PinnedAt 清空);参与者不存在抛 NotFound。 /// public class SetConversationPinnedCommandHandlerTests { private static readonly Guid UserId = Guid.Parse("22222222-2222-2222-2222-222222222222"); private static readonly Guid ConvId = Guid.Parse("11111111-1111-1111-1111-111111111111"); [Fact] public async Task Pins_conversation() { await using var db = IMTestDb.Create(); db.Conversations.Add(ImTestData.BuildConversation(ConvId, ConversationTypeEnum.Private, (UserId, 0))); await db.SaveChangesAsync(); var handler = new SetConversationPinnedCommandHandler(db); await handler.Handle(new SetConversationPinnedCommand(ConvId, UserId, true), CancellationToken.None); var p = await db.ConversationParticipants.FirstAsync(x => x.ConversationId == ConvId && x.UserId == UserId); p.IsPinned.Should().BeTrue(); p.PinnedAt.Should().NotBeNull(); } [Fact] public async Task Unpins_conversation() { await using var db = IMTestDb.Create(); db.Conversations.Add(ImTestData.BuildConversation(ConvId, ConversationTypeEnum.Private, (UserId, 0))); await db.SaveChangesAsync(); var handler = new SetConversationPinnedCommandHandler(db); await handler.Handle(new SetConversationPinnedCommand(ConvId, UserId, false), CancellationToken.None); var p = await db.ConversationParticipants.FirstAsync(x => x.ConversationId == ConvId && x.UserId == UserId); p.IsPinned.Should().BeFalse(); p.PinnedAt.Should().BeNull(); } [Fact] public async Task Throws_not_found_when_participant_missing() { await using var db = IMTestDb.Create(); var handler = new SetConversationPinnedCommandHandler(db); var act = async () => await handler.Handle(new SetConversationPinnedCommand(ConvId, UserId, true), CancellationToken.None); var ex = await act.Should().ThrowAsync(); ex.Which.Code.Should().Be(ErrorCode.NotFound); } }