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);
}
}