using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using NSubstitute;
using Xunit;
using BuildFlow.Platform.Application.Roles.Commands;
using BuildFlow.Platform.Application.Roles.Handlers;
using BuildFlow.Platform.Domain.Common;
using BuildFlow.Shared.Domain.Exceptions;
namespace BuildFlow.Platform.Tests.Roles;
///
/// 分配权限 Command 处理器单元测试。覆盖分配成功 + 该角色所有用户版本号批量自增、权限不存在拒绝。
///
public class AssignPermissionsCommandHandlerTests
{
[Fact]
public async Task Handle_ValidAssignment_ShouldBumpAllAffectedUsersVersion()
{
// Arrange:角色 A 关联两个用户,分配权限后两者版本号都应自增
var db = PlatformTestDb.CreateDbContext();
var roleId = Guid.NewGuid();
var permId = Guid.NewGuid();
var user1Id = Guid.NewGuid();
var user2Id = Guid.NewGuid();
db.Roles.Add(PlatformTestDb.WithAudit(new BuildFlow.Platform.Domain.Entities.Role.RoleEntity { Id = roleId, Name = "Admin" }));
db.Permissions.Add(PlatformTestDb.WithAudit(new BuildFlow.Platform.Domain.Entities.Permission.PermissionEntity
{
Id = permId,
Name = "用户管理",
Code = "user:read",
}));
await PlatformTestDb.SeedUserAsync(db, user1Id, "u1", permissionVersion: 1);
await PlatformTestDb.SeedUserAsync(db, user2Id, "u2", permissionVersion: 1);
db.UserRoles.Add(new BuildFlow.Platform.Domain.Entities.UserRole.UserRoleEntity { UserId = user1Id, RoleId = roleId, CreatedBy = "t", UpdatedBy = "t" });
db.UserRoles.Add(new BuildFlow.Platform.Domain.Entities.UserRole.UserRoleEntity { UserId = user2Id, RoleId = roleId, CreatedBy = "t", UpdatedBy = "t" });
await db.SaveChangesAsync();
var versionStore = Substitute.For();
var handler = new AssignPermissionsCommandHandler(db, versionStore);
// Act
await handler.Handle(new AssignPermissionsCommand(roleId, [permId]), CancellationToken.None);
// Assert:两个受影响用户的版本号都自增(1 → 2)
var users = await db.Users.Where(u => u.Id == user1Id || u.Id == user2Id).ToListAsync();
users.Should().AllSatisfy(u => u.PermissionVersion.Should().Be(2));
await versionStore.Received(1).BumpAsync(
Arg.Is>(ids => ids.Contains(user1Id) && ids.Contains(user2Id)),
Arg.Any());
}
[Fact]
public async Task Handle_NonExistentPermission_ShouldThrowNotFound()
{
// Arrange
var db = PlatformTestDb.CreateDbContext();
var roleId = Guid.NewGuid();
db.Roles.Add(PlatformTestDb.WithAudit(new BuildFlow.Platform.Domain.Entities.Role.RoleEntity { Id = roleId, Name = "Empty" }));
await db.SaveChangesAsync();
var handler = new AssignPermissionsCommandHandler(db, Substitute.For());
// Act
var act = () => handler.Handle(new AssignPermissionsCommand(roleId, [Guid.NewGuid()]), CancellationToken.None);
// Assert
await act.Should().ThrowAsync()
.WithMessage("*部分权限不存在*");
}
}