XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEWorkflow

【WinUI】XFE基于windows的工作流

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Text.Json;
using System.Text.Json.Nodes;
using XFEExtension.NetCore.XUnit.Assertions;
using XFEExtension.NetCore.XUnit.Attributes;
using XFEWorkflow.Abstractions;
using XFEWorkflow.Infrastructure.Compilation;
using XFEWorkflow.Infrastructure.Execution;
using XFEWorkflow.Infrastructure.Plugins;
using XFEWorkflow.Infrastructure.Storage;
using XFEWorkflow.Plugins.WeCom;

namespace XFEWorkflow.Test;

[TestFixture]
public sealed class WeComContactSampleTests
{
    [Test]
    public async Task JsonAndPackageImportTraverseEveryCachedContactThroughRealRunner()
    {
        await using var workspace = new TestWorkspace();
        var plugins = new PluginManager(workspace.Paths, workspace.State);
        await plugins.InstallAsync(TestSupport.Package(workspace.Paths.Temp, new WeComPlugin().Manifest));
        await using var runs = new RunCoordinator(workspace.Paths, plugins, new CredentialVault(workspace.State), new(),
            TestSupport.FindOutput("XFEWorkflow.Runner", "XFEWorkflow.Runner.exe"));
        var repository = new WorkflowRepository(workspace.Paths); var calls = 0;
        var contacts = JsonNode.Parse("""[{"id":"1001","displayName":"张三","note":" 原始内容\n换行 😀 ","extra":{"$var":"不要解析或修改"}},{"id":"1002","displayName":"李四","tags":["同事",null,2]},{"id":"1003","displayName":"王五","message":{"content":"¥var 和 $var 都是原文","quoted":{"id":"original"}}}]""")!.AsArray();
        runs.Host = (_, operation, input, _) =>
        {
            Assert.Equal("wecom.contacts", operation); Assert.Equal("", input.String("query")); calls++;
            return ValueTask.FromResult(new JsonObject { ["contacts"] = contacts.DeepClone(), ["completeRoster"] = false });
        };
        foreach (var extension in new[] { "json", "xfeworkflow", "generated-csharp" })
        {
            var source = Path.Combine(TestSupport.Root, "samples/workflows/wecom-contacts-foreach-log." + (extension == "generated-csharp" ? "json" : extension));
            var workflow = await repository.ImportAsync(source);
            Assert.Equal(false, workflow.Enabled); Assert.Equal("3.0.0", workflow.PluginVersions["xfe.wecom"]);
            Assert.False(workflow.Id == "sample-wecom-contacts-foreach-log");
            var body = workflow.Graph.Nodes.Single(x => x.CapabilityId == "core.foreach").Children["body"];
            Assert.Equal(0, body.Nodes.Single(x => x.CapabilityId == "core.log").Parameters.Count);
            Assert.True(body.Edges.Any(x => x.Kind == PortKind.Data && x.FromPort == "item" && x.ToPort == "message"));
            Assert.False(JsonSerializer.Serialize(workflow, WorkflowJson.Options).Contains("\"$var\""));
            if (extension == "generated-csharp") { GraphCodeGenerator.Update(workflow, true); workflow.Kind = WorkflowKind.CSharp; }
            var run = await runs.RunAsync(workflow).WaitAsync(TimeSpan.FromSeconds(15));
            Assert.Equal(RunStatus.Succeeded, run.Status, run.Error);
            var logs = WorkflowLogService.RunEntries(run); Assert.Equal(3, logs.Count);
            for (var i = 0; i < contacts.Count; i++)
            {
                var logged = JsonNode.Parse(logs[i].LogText)!;
                Assert.True(JsonNode.DeepEquals(contacts[i], logged), "日志应完整保留联系人原始字段和值");
                Assert.True(JsonNode.DeepEquals(contacts[i], run.Outputs["result"]![i]!["result"]));
            }
            Assert.False(run.Outputs.Boolean("completeRoster"));
            var export = Path.Combine(workspace.Paths.Temp, "contacts-" + extension + ".xfeworkflow");
            await repository.ExportAsync(workflow, export);
            var restored = await repository.ImportAsync(export); Assert.Equal(workflow.Graph.Edges.Count, restored.Graph.Edges.Count);
        }
        Assert.Equal(3, calls);
    }

    [Test]
    public async Task EmptyCacheProducesNoPerItemLogAndAnEmptyResult()
    {
        await using var workspace = new TestWorkspace(); var plugins = new PluginManager(workspace.Paths, workspace.State);
        await plugins.InstallAsync(TestSupport.Package(workspace.Paths.Temp, new WeComPlugin().Manifest));
        await using var runs = new RunCoordinator(workspace.Paths, plugins, new CredentialVault(workspace.State), new(),
            TestSupport.FindOutput("XFEWorkflow.Runner", "XFEWorkflow.Runner.exe"));
        runs.Host = (_, operation, _, _) =>
        {
            Assert.Equal("wecom.contacts", operation);
            return ValueTask.FromResult(new JsonObject { ["contacts"] = new JsonArray(), ["completeRoster"] = false });
        };
        var workflow = await new WorkflowRepository(workspace.Paths).ImportAsync(Path.Combine(TestSupport.Root, "samples/workflows/wecom-contacts-foreach-log.xfeworkflow"));
        var result = await runs.RunAsync(workflow).WaitAsync(TimeSpan.FromSeconds(15));
        Assert.Equal(RunStatus.Succeeded, result.Status, result.Error);
        Assert.Equal(0, result.Outputs["result"]!.AsArray().Count); Assert.Equal(0, WorkflowLogService.RunEntries(result).Count);
    }
}