- 将菜单实体的 ID 类型从 Guid 改为 long,并配置为自增主键 - 添加菜单创建、删除、树形结构构建等完整的 CRUD 操作支持 - 为文件上传相关端点添加 file:upload 权限验证 - 为文件操作端点添加 file:read 和 file:write 权限控制 - 为通知功能添加 notification:read 权限限制 - 实现 BuildFlow 按钮执行的权限检查机制 - 在 IM 模块中集成 Redis 未读计数器优化性能 - 更新用户主页路径从 /workspace 到 /dashboard/workspace - 添加 SignalR Hub 授权和 WebSocket 连接安全保护 - 新增平台测试项目并完善按钮权限测试用例
77 lines
2.5 KiB
C#
77 lines
2.5 KiB
C#
using BuildFlow.Platform.Application.Menus.Commands;
|
||
using BuildFlow.Platform.Application.Menus.Handlers;
|
||
using BuildFlow.Platform.Domain.Entities;
|
||
using BuildFlow.Platform.Infrastructure.Persistence;
|
||
using FluentAssertions;
|
||
using Microsoft.EntityFrameworkCore;
|
||
using Microsoft.Extensions.DependencyInjection;
|
||
using Xunit;
|
||
|
||
namespace BuildFlow.Platform.Tests.Menus;
|
||
|
||
/// <summary>
|
||
/// 菜单管理测试。约束菜单主键使用 int64,并保证拖拽排序按 long Id 落库。
|
||
/// </summary>
|
||
public class MenuSortTests
|
||
{
|
||
[Fact]
|
||
public void MenuIdentifier_ShouldUseInt64()
|
||
{
|
||
typeof(Menu).GetProperty(nameof(Menu.Id))!.PropertyType.Should().Be(typeof(long));
|
||
typeof(Menu).GetProperty(nameof(Menu.ParentId))!.PropertyType.Should().Be(typeof(long?));
|
||
}
|
||
|
||
[Fact]
|
||
public async Task SortMenusCommand_ShouldUpdateMenusByInt64Ids()
|
||
{
|
||
await using var db = BuildInMemoryDb();
|
||
db.Menus.AddRange(
|
||
BuildMenu(1, "root", null, 0),
|
||
BuildMenu(2, "child-a", 1, 0),
|
||
BuildMenu(3, "child-b", 1, 1));
|
||
await db.SaveChangesAsync();
|
||
|
||
var handler = new SortMenusCommandHandler(db);
|
||
|
||
var affected = await handler.Handle(
|
||
new SortMenusCommand(
|
||
[
|
||
new MenuSortItem(2, null, 1),
|
||
new MenuSortItem(3, null, 0),
|
||
]),
|
||
CancellationToken.None);
|
||
|
||
affected.Should().Be(2);
|
||
var childA = await db.Menus.SingleAsync(m => m.Id == 2);
|
||
var childB = await db.Menus.SingleAsync(m => m.Id == 3);
|
||
childA.ParentId.Should().BeNull();
|
||
childA.Order.Should().Be(1);
|
||
childB.ParentId.Should().BeNull();
|
||
childB.Order.Should().Be(0);
|
||
}
|
||
|
||
private static PlatformDbContext BuildInMemoryDb()
|
||
{
|
||
var services = new ServiceCollection();
|
||
services.AddDbContext<PlatformDbContext>(o => o.UseInMemoryDatabase($"platform-menu-{Guid.NewGuid()}"));
|
||
return services.BuildServiceProvider().GetRequiredService<PlatformDbContext>();
|
||
}
|
||
|
||
private static Menu BuildMenu(long id, string code, long? parentId, int order)
|
||
=> new()
|
||
{
|
||
Id = id,
|
||
Code = code,
|
||
Name = code.Replace(".", "-", StringComparison.Ordinal),
|
||
Path = $"/{code}",
|
||
ParentId = parentId,
|
||
Title = code,
|
||
Order = order,
|
||
CreatedBy = "test",
|
||
CreatedAt = DateTime.UtcNow,
|
||
UpdatedBy = "test",
|
||
UpdatedAt = DateTime.UtcNow,
|
||
OperatorIP = "127.0.0.1",
|
||
};
|
||
}
|