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.Common;
using IM.Domain.Enums;
using IM.Infrastructure.Persistence;
using Microsoft.EntityFrameworkCore;
using Moq;
using Xunit;
namespace BuildFlow.IM.Tests.Chat;
///
/// MarkConversationUnreadCommandHandler:置未读=1+清空读位点,双写 Redis(Reset+Increment);
/// 参与者不存在抛 NotFound。
///
public class MarkConversationUnreadCommandHandlerTests
{
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 Marks_unread_and_calls_redis()
{
await using var db = IMTestDb.Create();
db.Conversations.Add(ImTestData.BuildConversation(ConvId, ConversationTypeEnum.Private, (UserId, 0)));
await db.SaveChangesAsync();
var unread = new Mock();
var handler = new MarkConversationUnreadCommandHandler(db, unread.Object);
await handler.Handle(new MarkConversationUnreadCommand(ConvId, UserId), CancellationToken.None);
var p = await db.ConversationParticipants.FirstAsync(x => x.ConversationId == ConvId && x.UserId == UserId);
p.UnreadCount.Should().Be(1);
p.LastReadMessageId.Should().BeNull();
unread.Verify(c => c.ResetAsync(ConvId, UserId, It.IsAny()), Times.Once);
unread.Verify(c => c.IncrementAsync(ConvId, UserId, 1, It.IsAny()), Times.Once);
}
[Fact]
public async Task Throws_not_found_when_participant_missing()
{
await using var db = IMTestDb.Create();
var unread = new Mock();
var handler = new MarkConversationUnreadCommandHandler(db, unread.Object);
var act = async () => await handler.Handle(new MarkConversationUnreadCommand(ConvId, UserId), CancellationToken.None);
var ex = await act.Should().ThrowAsync();
ex.Which.Code.Should().Be(ErrorCode.NotFound);
}
}