using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using NSubstitute;
using Xunit;
using BuildFlow.Platform.Application.Users.Commands;
using BuildFlow.Platform.Application.Users.Handlers;
using BuildFlow.Platform.Domain.Common;
using BuildFlow.Shared.Domain.Exceptions;
namespace BuildFlow.Platform.Tests.Users;
///
/// 分配角色 Command 处理器单元测试。覆盖分配成功 + 权限版本号自增、角色不存在拒绝。
///
public class AssignRolesCommandHandlerTests
{
[Fact]
public async Task Handle_ValidAssignment_ShouldBumpPermissionVersion()
{
// Arrange
var db = PlatformTestDb.CreateDbContext();
var userId = Guid.NewGuid();
await PlatformTestDb.SeedUserAsync(db, userId, "assign-target", permissionVersion: 3);
var roleId = Guid.NewGuid();
db.Roles.Add(PlatformTestDb.WithAudit(new BuildFlow.Platform.Domain.Entities.Role { Id = roleId, Name = "Editor" }));
await db.SaveChangesAsync();
var versionStore = Substitute.For();
var handler = new AssignRolesCommandHandler(db, versionStore);
// Act
await handler.Handle(new AssignRolesCommand(userId, [roleId]), CancellationToken.None);
// Assert:版本号自增(3 → 4)+ Redis 镜像同步
var user = await db.Users.FirstAsync(u => u.Id == userId);
user.PermissionVersion.Should().Be(4);
await versionStore.Received(1).BumpAsync(Arg.Is>(ids => ids.Contains(userId)), Arg.Any());
}
[Fact]
public async Task Handle_NonExistentRole_ShouldThrowNotFound()
{
// Arrange
var db = PlatformTestDb.CreateDbContext();
var userId = Guid.NewGuid();
await PlatformTestDb.SeedUserAsync(db, userId, "victim");
var handler = new AssignRolesCommandHandler(db, Substitute.For());
// Act
var act = () => handler.Handle(new AssignRolesCommand(userId, [Guid.NewGuid()]), CancellationToken.None);
// Assert
await act.Should().ThrowAsync()
.WithMessage("*部分角色不存在*");
}
}