using BuildFlow.Platform.Application.Roles.Commands; using BuildFlow.Platform.Application.Roles.Handlers; using BuildFlow.Platform.Application.Roles.Queries; using BuildFlow.Platform.Infrastructure.Persistence; using BuildFlow.Shared.Domain.Errors; using BuildFlow.Shared.Domain.Exceptions; using FluentAssertions; using Microsoft.EntityFrameworkCore; using Xunit; namespace BuildFlow.Platform.Tests.Roles; /// /// [SOP-PLATFORM] Roles 模块 5 个 Handler 覆盖测试。 /// 覆盖: Create / GetById / GetList / Update / Delete。 /// 飞书矩阵: platform/Roles 子域(5 Handler 零覆盖→全补)。 /// public class RolesHandlerTests { private static PlatformDbContext CreateDb([System.Runtime.CompilerServices.CallerMemberName] string name = "") => PlatformTestDb.CreateDbContext(name); #region CreateRole [Fact] public async Task CreateRole_Valid_ReturnsDto() { var db = CreateDb(); var result = await new CreateRoleCommandHandler(db) .Handle(new CreateRoleCommand("Admin", "管理员"), CancellationToken.None); result.Name.Should().Be("Admin"); (await db.Roles.CountAsync()).Should().Be(1); } [Fact] public async Task CreateRole_DuplicateName_ThrowsBusiness() { var db = CreateDb(); await new CreateRoleCommandHandler(db).Handle(new CreateRoleCommand("Admin", null), CancellationToken.None); var act = async () => await new CreateRoleCommandHandler(db) .Handle(new CreateRoleCommand("Admin", null), CancellationToken.None); var ex = await act.Should().ThrowAsync(); ex.Which.Code.Should().Be(ErrorCode.AlreadyExists); } #endregion #region GetRoleById [Fact] public async Task GetRoleById_Existing_ReturnsDto() { var db = CreateDb(); var role = await new CreateRoleCommandHandler(db) .Handle(new CreateRoleCommand("Manager", "经理"), CancellationToken.None); var result = await new GetRoleByIdQueryHandler(db) .Handle(new GetRoleByIdQuery(role.Id), CancellationToken.None); result.Name.Should().Be("Manager"); } [Fact] public async Task GetRoleById_NonExistent_ThrowsNotFound() { var db = CreateDb(); var act = async () => await new GetRoleByIdQueryHandler(db) .Handle(new GetRoleByIdQuery(Guid.NewGuid()), CancellationToken.None); var ex = await act.Should().ThrowAsync(); ex.Which.Code.Should().Be(ErrorCode.NotFound); } #endregion #region GetRoleList [Fact] public async Task GetRoleList_ReturnsAll() { var db = CreateDb(); await new CreateRoleCommandHandler(db).Handle(new CreateRoleCommand("R1", null), CancellationToken.None); await new CreateRoleCommandHandler(db).Handle(new CreateRoleCommand("R2", null), CancellationToken.None); var result = await new GetRoleListQueryHandler(db) .Handle(new GetRoleListQuery(), CancellationToken.None); result.Should().HaveCount(2); } #endregion #region UpdateRole [Fact] public async Task UpdateRole_Existing_UpdatesFields() { var db = CreateDb(); var role = await new CreateRoleCommandHandler(db) .Handle(new CreateRoleCommand("Old", "旧"), CancellationToken.None); var result = await new UpdateRoleCommandHandler(db) .Handle(new UpdateRoleCommand(role.Id, "New", "新"), CancellationToken.None); result.Name.Should().Be("New"); result.Description.Should().Be("新"); } [Fact] public async Task UpdateRole_NonExistent_ThrowsNotFound() { var db = CreateDb(); var act = async () => await new UpdateRoleCommandHandler(db) .Handle(new UpdateRoleCommand(Guid.NewGuid(), "X", null), CancellationToken.None); var ex = await act.Should().ThrowAsync(); ex.Which.Code.Should().Be(ErrorCode.NotFound); } #endregion #region DeleteRole [Fact] public async Task DeleteRole_Existing_Removes() { var db = CreateDb(); var role = await new CreateRoleCommandHandler(db) .Handle(new CreateRoleCommand("Tmp", null), CancellationToken.None); await new DeleteRoleCommandHandler(db).Handle(new DeleteRoleCommand(role.Id), CancellationToken.None); (await db.Roles.CountAsync()).Should().Be(0); } [Fact] public async Task DeleteRole_NonExistent_ThrowsNotFound() { var db = CreateDb(); var act = async () => await new DeleteRoleCommandHandler(db) .Handle(new DeleteRoleCommand(Guid.NewGuid()), CancellationToken.None); var ex = await act.Should().ThrowAsync(); ex.Which.Code.Should().Be(ErrorCode.NotFound); } #endregion }