90 lines
2.9 KiB
C#
90 lines
2.9 KiB
C#
using BuildFlow.Shared.Domain.Errors;
|
|
using BuildFlow.Shared.Domain.Exceptions;
|
|
using FluentAssertions;
|
|
using System.Text.Json.Nodes;
|
|
using Workflow.Application.Form.Derivation;
|
|
using Workflow.Application.Form.Schema;
|
|
using Xunit;
|
|
|
|
namespace BuildFlow.Workflow.Tests.Performance;
|
|
|
|
/// <summary>
|
|
/// 预解析表单 Schema 在批量校验和派生中的复用测试。
|
|
/// </summary>
|
|
public class PreparedFormSchemaTests
|
|
{
|
|
[Fact]
|
|
public async Task PreparedSchemaCanBeReusedForValidationAndDerivation()
|
|
{
|
|
var prepared = PreparedFormSchema.Create(ComputedSchema);
|
|
var derivation = new FormValueDerivationService([], []);
|
|
|
|
var firstValidation = FormDataValidator.Validate(
|
|
prepared,
|
|
"""{"quantity":2,"unitPrice":10}""");
|
|
var first = await derivation.DeriveAsync(
|
|
prepared,
|
|
"""{"quantity":2,"unitPrice":10}""",
|
|
new FormDerivationContext(Guid.NewGuid(), Guid.NewGuid(), null),
|
|
CancellationToken.None);
|
|
var second = await derivation.DeriveAsync(
|
|
prepared,
|
|
"""{"quantity":3,"unitPrice":5}""",
|
|
new FormDerivationContext(Guid.NewGuid(), Guid.NewGuid(), null),
|
|
CancellationToken.None);
|
|
|
|
firstValidation.IsValid.Should().BeTrue();
|
|
ReadTotal(first.DataJson).Should().Be(20);
|
|
ReadTotal(second.DataJson).Should().Be(15);
|
|
prepared.Validation.Fields.Should().HaveCount(3);
|
|
}
|
|
|
|
[Fact]
|
|
public void InvalidSchemaCannotBePrepared()
|
|
{
|
|
var act = () => PreparedFormSchema.Create("""
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"supplier": {
|
|
"type": "object",
|
|
"x-component": "RelationPicker",
|
|
"x-field-kind": "relation",
|
|
"x-relation": { "idField": "id" }
|
|
}
|
|
}
|
|
}
|
|
""");
|
|
|
|
var exception = act.Should().Throw<BusinessException>().Which;
|
|
exception.Code.Should().Be(ErrorCode.InvalidParam);
|
|
}
|
|
|
|
private static decimal ReadTotal(string dataJson)
|
|
=> JsonNode.Parse(dataJson)!["total"]!.GetValue<decimal>();
|
|
|
|
private const string ComputedSchema = """
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"quantity": { "type": "number", "x-component": "InputNumber" },
|
|
"unitPrice": { "type": "number", "x-component": "InputNumber" },
|
|
"total": {
|
|
"type": "number",
|
|
"x-component": "InputNumber",
|
|
"x-field-kind": "computed",
|
|
"x-derived": {
|
|
"mode": "computed",
|
|
"writePolicy": "overwrite",
|
|
"expression": {
|
|
"operator": "multiply",
|
|
"left": { "type": "field", "path": "quantity" },
|
|
"right": { "type": "field", "path": "unitPrice" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
""";
|
|
}
|