180 lines
7.5 KiB
C#

using FluentAssertions;
using Microsoft.EntityFrameworkCore;
using Workflow.Application.BuildFlow.Applications.Commands;
using Workflow.Application.BuildFlow.Applications.Handlers;
using Workflow.Application.BuildFlow.Applications.Queries;
using Workflow.Application.BuildFlow.Buttons.Commands;
using Workflow.Application.BuildFlow.Buttons.Handlers;
using Workflow.Application.BuildFlow.Buttons.Queries;
using Workflow.Application.BuildFlow.CustomFunctions.Commands;
using Workflow.Application.BuildFlow.CustomFunctions.Handlers;
using Workflow.Application.BuildFlow.CustomFunctions.Queries;
using Workflow.Application.BuildFlow.Pages.Commands;
using Workflow.Application.BuildFlow.Pages.Handlers;
using Workflow.Application.BuildFlow.Pages.Queries;
using Workflow.Domain.Enums;
using Xunit;
namespace BuildFlow.Workflow.Tests.BuildFlow;
/// <summary>
/// BuildFlow 应用元数据测试,约束应用和页面定义作为低代码平台顶层归属存在。
/// </summary>
public class BuildFlowApplicationTests
{
[Fact]
public async Task CreateApplicationAndPage_PersistsMetadata()
{
await using var db = TestDbFactory.Create();
var appHandler = new CreateBuildFlowApplicationCommandHandler(db);
var pageHandler = new CreateBuildFlowPageDefinitionCommandHandler(db);
var app = await appHandler.Handle(
new CreateBuildFlowApplicationCommand("leave", "请假应用", "员工请假流程"),
CancellationToken.None);
var page = await pageHandler.Handle(
new CreateBuildFlowPageDefinitionCommand(
app.Id,
"leave-form",
"请假申请页",
BuildFlowPageType.Form,
"""{"type":"form","formCode":"leave-request"}"""),
CancellationToken.None);
app.Code.Should().Be("leave");
app.Status.Should().Be(BuildFlowMetadataStatus.Draft);
page.ApplicationId.Should().Be(app.Id);
page.SchemaJson.Should().Contain("leave-request");
}
[Fact]
public async Task GetApplicationList_FiltersByStatus()
{
await using var db = TestDbFactory.Create();
var appHandler = new CreateBuildFlowApplicationCommandHandler(db);
var draft = await appHandler.Handle(
new CreateBuildFlowApplicationCommand("draft-app", "草稿应用", null),
CancellationToken.None);
await appHandler.Handle(
new CreateBuildFlowApplicationCommand("published-app", "已发布应用", null),
CancellationToken.None);
var published = await db.BuildFlowApplications.SingleAsync(x => x.Code == "published-app");
published.Status = BuildFlowMetadataStatus.Published;
await db.SaveChangesAsync();
var handler = new GetBuildFlowApplicationListQueryHandler(db);
var result = await handler.Handle(
new GetBuildFlowApplicationListQuery(1, 20, BuildFlowMetadataStatus.Draft, null),
CancellationToken.None);
result.Total.Should().Be(1);
result.Items.Should().ContainSingle(x => x.Id == draft.Id && x.Code == "draft-app");
}
[Fact]
public async Task GetPageList_FiltersByApplication()
{
await using var db = TestDbFactory.Create();
var appHandler = new CreateBuildFlowApplicationCommandHandler(db);
var pageHandler = new CreateBuildFlowPageDefinitionCommandHandler(db);
var leaveApp = await appHandler.Handle(new CreateBuildFlowApplicationCommand("leave", "请假应用", null), CancellationToken.None);
var purchaseApp = await appHandler.Handle(new CreateBuildFlowApplicationCommand("purchase", "采购应用", null), CancellationToken.None);
await pageHandler.Handle(
new CreateBuildFlowPageDefinitionCommand(leaveApp.Id, "leave-list", "请假列表", BuildFlowPageType.List, "{}"),
CancellationToken.None);
await pageHandler.Handle(
new CreateBuildFlowPageDefinitionCommand(purchaseApp.Id, "purchase-list", "采购列表", BuildFlowPageType.List, "{}"),
CancellationToken.None);
var handler = new GetBuildFlowPageDefinitionListQueryHandler(db);
var result = await handler.Handle(
new GetBuildFlowPageDefinitionListQuery(1, 20, leaveApp.Id, null, null),
CancellationToken.None);
result.Total.Should().Be(1);
result.Items.Should().ContainSingle(x => x.ApplicationId == leaveApp.Id && x.Code == "leave-list");
}
[Fact]
public async Task GetButtonList_FiltersByFormAndPlacement()
{
await using var db = TestDbFactory.Create();
var formDefinitionId = Guid.NewGuid();
var buttonHandler = new CreateBuildFlowButtonDefinitionCommandHandler(db);
await buttonHandler.Handle(
new CreateBuildFlowButtonDefinitionCommand(
null,
null,
formDefinitionId,
null,
"submit",
"提交",
"lucide:send",
BuildFlowButtonPlacement.FormToolbar,
"buildflow:button:submit",
null,
null,
null,
"[]",
10),
CancellationToken.None);
await buttonHandler.Handle(
new CreateBuildFlowButtonDefinitionCommand(
null,
null,
Guid.NewGuid(),
null,
"approve",
"审批",
"lucide:check",
BuildFlowButtonPlacement.RowAction,
"buildflow:button:approve",
null,
null,
null,
"[]",
20),
CancellationToken.None);
var handler = new GetBuildFlowButtonDefinitionListQueryHandler(db);
var result = await handler.Handle(
new GetBuildFlowButtonDefinitionListQuery(
1,
20,
null,
null,
formDefinitionId,
null,
BuildFlowButtonPlacement.FormToolbar,
null),
CancellationToken.None);
result.Total.Should().Be(1);
result.Items.Should().ContainSingle(x => x.Code == "submit" && x.FormDefinitionId == formDefinitionId);
}
[Fact]
public async Task GetCustomFunctionList_FiltersPublishedFunctions()
{
await using var db = TestDbFactory.Create();
var createHandler = new CreateCustomFunctionCommandHandler(db);
var publishHandler = new PublishCustomFunctionCommandHandler(db);
var draft = await createHandler.Handle(
new CreateCustomFunctionCommand("draftRule", "草稿规则", null, "1", null, null, 1000),
CancellationToken.None);
var published = await createHandler.Handle(
new CreateCustomFunctionCommand("publishedRule", "已发布规则", null, "2", null, null, 1000),
CancellationToken.None);
await publishHandler.Handle(new PublishCustomFunctionCommand(published.Id), CancellationToken.None);
var handler = new GetCustomFunctionListQueryHandler(db);
var result = await handler.Handle(
new GetCustomFunctionListQuery(1, 20, BuildFlowMetadataStatus.Published, null),
CancellationToken.None);
result.Total.Should().Be(1);
result.Items.Should().ContainSingle(x => x.Id == published.Id && x.Name == "publishedRule");
result.Items.Should().NotContain(x => x.Id == draft.Id);
}
}