build-flow.api/tests/BuildFlow.Workflow.Tests/Form/FormRelationActionTests.cs

94 lines
3.0 KiB
C#

using FluentAssertions;
using Workflow.Application.Form.Derivation;
using Workflow.Application.Form.Relation;
using Xunit;
namespace BuildFlow.Workflow.Tests.Form;
public class FormRelationActionTests
{
[Fact]
public async Task DeriveAsync_WhitelistedAction_ExecutesRegisteredHandler()
{
var action = new ReserveCreditAction();
var service = new FormValueDerivationService([new SupplierResolver()], [action]);
var instanceId = Guid.NewGuid();
await service.DeriveAsync(
RelationActionSchema,
"""{"supplier":{"id":"supplier-1"}}""",
new FormDerivationContext(null, instanceId, null),
CancellationToken.None);
action.Calls.Should().Be(1);
action.LastContext!.InstanceId.Should().Be(instanceId);
action.LastContext.SourceCode.Should().Be("supplier");
action.LastContext.ActionCode.Should().Be("reserveCredit");
}
[Fact]
public async Task DeriveAsync_WhitelistedAction_ThrowsWhenActionMissing()
{
var service = new FormValueDerivationService([new SupplierResolver()], []);
var act = () => service.DeriveAsync(
RelationActionSchema,
"""{"supplier":{"id":"supplier-1"}}""",
new FormDerivationContext(null, Guid.NewGuid(), null),
CancellationToken.None);
await act.Should().ThrowAsync<BusinessException>()
.WithMessage("*关联动作*supplier:reserveCredit*未注册*");
}
private sealed class ReserveCreditAction : IFormRelationActionHandler
{
public string SourceCode => "supplier";
public string ActionCode => "reserveCredit";
public int Calls { get; private set; }
public FormRelationActionContext? LastContext { get; private set; }
public Task ExecuteAsync(FormRelationActionContext context, CancellationToken ct)
{
Calls++;
LastContext = context;
return Task.CompletedTask;
}
}
private sealed class SupplierResolver : IFormRelationResolver
{
public string SourceCode => "supplier";
public Task<FormRelationResolveResult> ResolveAsync(
FormRelationResolveRequest request,
CancellationToken ct)
=> Task.FromResult(new FormRelationResolveResult(
request.Id,
"华东供应商",
new Dictionary<string, object?> { ["name"] = "华东供应商" }));
}
private const string RelationActionSchema = """
{
"type": "object",
"properties": {
"supplier": {
"type": "object",
"title": "供应商",
"x-component": "RelationPicker",
"x-field-kind": "relation",
"x-relation": {
"sourceCode": "supplier",
"idField": "id",
"labelField": "name",
"snapshotFields": ["name"],
"updatePolicy": "whitelistedAction",
"actionCode": "reserveCredit"
}
}
}
}
""";
}