xiangning 7ecd78550f test: 补充 platform/rag/file 模块单元测试
- platform: 通知与权限模块 handler 测试
- rag: Chat 端到端、知识库 CRUD、嵌入与查询测试
- file: 文件分享下载与文件夹/桶设置测试
2026-07-09 12:52:00 +08:00

191 lines
6.5 KiB
C#

using BuildFlow.Platform.Application.Permissions.Commands;
using BuildFlow.Platform.Application.Permissions.DTOs;
using BuildFlow.Platform.Application.Permissions.Handlers;
using BuildFlow.Platform.Application.Permissions.Queries;
using BuildFlow.Platform.Domain.Entities;
using BuildFlow.Platform.Infrastructure.Persistence;
using BuildFlow.Shared.Domain.Exceptions;
using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using Xunit;
namespace BuildFlow.Platform.Tests.Permissions;
/// <summary>
/// [SOP-PLATFORM] 权限管理全 Handler 覆盖测试。
/// 覆盖:Create / Update / Delete / GetList / GetById / GetTree。
/// 飞书矩阵: platform/Permissions 子域(6 Handler 零覆盖→全补)
/// </summary>
public class PermissionHandlerTests
{
private static PlatformDbContext CreateDb([System.Runtime.CompilerServices.CallerMemberName] string name = "")
=> PlatformTestDb.CreateDbContext(name);
private static Permission NewPermission(string code, string? group = "TestGroup")
=> PlatformTestDb.WithAudit(new Permission
{
Name = $"权限_{code}",
Code = code,
Description = "desc",
Group = group
});
[Fact]
public async Task Create_Valid_ReturnsDto()
{
var db = CreateDb();
var handler = new CreatePermissionCommandHandler(db);
var result = await handler.Handle(
new CreatePermissionCommand("创建用户", "user:create", "描述", "UserManagement"),
CancellationToken.None);
result.Code.Should().Be("user:create");
result.Name.Should().Be("创建用户");
(await db.Permissions.CountAsync()).Should().Be(1);
}
[Fact]
public async Task Create_DuplicateCode_ThrowsBusiness()
{
var db = CreateDb();
db.Permissions.Add(NewPermission("user:create"));
await db.SaveChangesAsync();
var handler = new CreatePermissionCommandHandler(db);
var act = async () => await handler.Handle(
new CreatePermissionCommand("重复", "user:create", null, null), CancellationToken.None);
await act.Should().ThrowAsync<BusinessException>("Code 唯一,重复应拒绝");
}
[Fact]
public async Task Update_Existing_OverwritesNullableFields()
{
var db = CreateDb();
var p = NewPermission("user:read");
db.Permissions.Add(p);
await db.SaveChangesAsync();
var handler = new UpdatePermissionCommandHandler(db);
var result = await handler.Handle(
new UpdatePermissionCommand(p.Id, "新名称", "新描述", "NewGroup"), CancellationToken.None);
result.Name.Should().Be("新名称");
result.Description.Should().Be("新描述");
result.Group.Should().Be("NewGroup");
result.Code.Should().Be("user:read", "Code 不可改");
}
[Fact]
public async Task Update_NonExistent_ThrowsNotFound()
{
var db = CreateDb();
var handler = new UpdatePermissionCommandHandler(db);
var act = async () => await handler.Handle(
new UpdatePermissionCommand(Guid.NewGuid(), "x", null, null), CancellationToken.None);
await act.Should().ThrowAsync<NotFoundException>();
}
[Fact]
public async Task Delete_Existing_RemovesAndUnlinksRoles()
{
var db = CreateDb();
var p = NewPermission("user:delete");
var role = PlatformTestDb.WithAudit(new Role { Name = "Admin" });
var link = new RolePermission { Role = role, Permission = p };
db.Permissions.Add(p);
db.Roles.Add(role);
db.RolePermissions.Add(link);
await db.SaveChangesAsync();
var handler = new DeletePermissionCommandHandler(db);
await handler.Handle(new DeletePermissionCommand(p.Id), CancellationToken.None);
(await db.Permissions.AnyAsync(x => x.Id == p.Id)).Should().BeFalse("软删后不可见");
}
[Fact]
public async Task Delete_NonExistent_ThrowsNotFound()
{
var db = CreateDb();
var handler = new DeletePermissionCommandHandler(db);
var act = async () => await handler.Handle(new DeletePermissionCommand(Guid.NewGuid()), CancellationToken.None);
await act.Should().ThrowAsync<NotFoundException>();
}
[Fact]
public async Task GetList_ReturnsAll()
{
var db = CreateDb();
db.Permissions.AddRange(NewPermission("p1"), NewPermission("p2"));
await db.SaveChangesAsync();
var handler = new GetPermissionListQueryHandler(db);
var result = await handler.Handle(new GetPermissionListQuery(), CancellationToken.None);
result.Should().HaveCount(2);
}
[Fact]
public async Task GetById_Existing_ReturnsDto()
{
var db = CreateDb();
var p = NewPermission("user:read");
db.Permissions.Add(p);
await db.SaveChangesAsync();
var handler = new GetPermissionByIdQueryHandler(db);
var result = await handler.Handle(new GetPermissionByIdQuery(p.Id), CancellationToken.None);
result.Code.Should().Be("user:read");
}
[Fact]
public async Task GetById_NonExistent_ThrowsNotFound()
{
var db = CreateDb();
var handler = new GetPermissionByIdQueryHandler(db);
var act = async () => await handler.Handle(new GetPermissionByIdQuery(Guid.NewGuid()), CancellationToken.None);
await act.Should().ThrowAsync<NotFoundException>();
}
[Fact]
public async Task GetTree_GroupsByGroupField()
{
var db = CreateDb();
db.Permissions.AddRange(
NewPermission("a:1", "GroupA"),
NewPermission("a:2", "GroupA"),
NewPermission("b:1", "GroupB"));
await db.SaveChangesAsync();
var handler = new GetPermissionTreeQueryHandler(db);
var tree = await handler.Handle(new GetPermissionTreeQuery(), CancellationToken.None);
tree.Should().HaveCount(2);
tree.First(g => g.Group == "GroupA").Permissions.Should().HaveCount(2);
tree.First(g => g.Group == "GroupB").Permissions.Should().HaveCount(1);
}
[Fact]
public async Task GetTree_NullGroup_GoesToUngrouped()
{
var db = CreateDb();
db.Permissions.Add(NewPermission("no:group", null));
await db.SaveChangesAsync();
var handler = new GetPermissionTreeQueryHandler(db);
var tree = await handler.Handle(new GetPermissionTreeQuery(), CancellationToken.None);
tree.Should().ContainSingle();
tree[0].Group.Should().Be("未分组");
}
}