Add project files.
This commit is contained in:
+7
@@ -0,0 +1,7 @@
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityNotificationsMiddleware;
|
||||
|
||||
public class Spy
|
||||
{
|
||||
public bool ActivityExecutingWasCalled { get; set; }
|
||||
public bool ActivityExecutedWasCalled { get; set; }
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
using Elsa.Mediator.Contracts;
|
||||
using Elsa.Workflows.Notifications;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityNotificationsMiddleware;
|
||||
|
||||
public class TestHandler : INotificationHandler<ActivityExecuting>, INotificationHandler<ActivityExecuted>
|
||||
{
|
||||
private readonly Spy _spy;
|
||||
|
||||
public TestHandler(Spy spy)
|
||||
{
|
||||
_spy = spy;
|
||||
}
|
||||
|
||||
public Task HandleAsync(ActivityExecuting notification, CancellationToken cancellationToken)
|
||||
{
|
||||
_spy.ActivityExecutingWasCalled = true;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task HandleAsync(ActivityExecuted notification, CancellationToken cancellationToken)
|
||||
{
|
||||
_spy.ActivityExecutedWasCalled = true;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Notifications;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityNotificationsMiddleware;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly Spy _spy;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
var services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.ConfigureServices(s =>
|
||||
{
|
||||
s.AddSingleton<Spy>();
|
||||
s.AddNotificationHandler<TestHandler, ActivityExecuting>();
|
||||
s.AddNotificationHandler<TestHandler, ActivityExecuted>();
|
||||
})
|
||||
|
||||
.Build();
|
||||
|
||||
_workflowRunner = services.GetRequiredService<IWorkflowRunner>();
|
||||
_spy = services.GetRequiredService<Spy>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Running workflow with activity notifications middleware results in notifications being published")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _workflowRunner.RunAsync<HelloWorldWorkflow>();
|
||||
Assert.True(_spy.ActivityExecutingWasCalled);
|
||||
Assert.True(_spy.ActivityExecutedWasCalled);
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityNotificationsMiddleware;
|
||||
|
||||
class HelloWorldWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow.Root = new WriteLine("Hello World!");
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityOutputs;
|
||||
|
||||
public class LoopingWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
var readCurrentValue = new Inline<string>(context => context.GetVariable<string>("CurrentValue")!);
|
||||
|
||||
builder.Root = new ForEach<string>(
|
||||
[
|
||||
"Item 1",
|
||||
"Item 2",
|
||||
"Item 3"
|
||||
])
|
||||
{
|
||||
Body = new Sequence
|
||||
{
|
||||
Activities =
|
||||
[
|
||||
readCurrentValue,
|
||||
new WriteLine(context =>
|
||||
{
|
||||
var currentValue = context.GetVariable<string>("CurrentValue");
|
||||
var activityResult = context.GetActivityExecutionContext().GetResult(readCurrentValue);
|
||||
return $"Current value: {currentValue}, Activity result: {activityResult}";
|
||||
})
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityOutputs;
|
||||
|
||||
public class SumActivity : CodeActivity<int>
|
||||
{
|
||||
public SumActivity(Variable<int> a, Variable<int> b)
|
||||
{
|
||||
A = new(a);
|
||||
B = new(b);
|
||||
}
|
||||
|
||||
public Input<int> A { get; set; }
|
||||
public Input<int> B { get; set; }
|
||||
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
var input1 = A.Get(context);
|
||||
var input2 = B.Get(context);
|
||||
var result = input1 + input2;
|
||||
|
||||
// All three work.
|
||||
Result.Set(context, result);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityOutputs;
|
||||
|
||||
public class SumWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var a = new Variable<int>("A", 0);
|
||||
var b = new Variable<int>("B", 0);
|
||||
|
||||
var sumActivity = new SumActivity(a, b);
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Variables = { a, b },
|
||||
Activities =
|
||||
{
|
||||
new Inline(context => a.Set(context, 4)),
|
||||
new Inline(context => b.Set(context, 6)),
|
||||
sumActivity,
|
||||
new WriteLine(context => $"The result of {a.Get(context)} and {b.Get(context)} is {sumActivity.GetResult<int>(context)}."),
|
||||
new WriteLine(context => $"The last result is {context.GetLastResult<int>()}."),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ActivityOutputs;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Activity outputs can be accessed from other activities.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<SumWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[]
|
||||
{
|
||||
"The result of 4 and 6 is 10.", "The last result is 10."
|
||||
}, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "The last activity output is returned.")]
|
||||
public async Task Test2()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<LoopingWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[]
|
||||
{
|
||||
"Current value: Item 1, Activity result: Item 1",
|
||||
"Current value: Item 2, Activity result: Item 2",
|
||||
"Current value: Item 3, Activity result: Item 3"
|
||||
}, lines);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Blocking;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IWorkflowBuilderFactory _workflowBuilderFactory;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_workflowBuilderFactory = _services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Subsequent activity does not get scheduled when previous activity created a bookmark")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<BlockingSequentialWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Line 1" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Subsequent activities are scheduled when resuming workflow using bookmark")]
|
||||
public async Task Test2()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflow = await _workflowBuilderFactory.CreateBuilder().BuildWorkflowAsync<BlockingSequentialWorkflow>();
|
||||
|
||||
// Start workflow.
|
||||
var result = await _workflowRunner.RunAsync(workflow);
|
||||
var bookmark = result.WorkflowState.Bookmarks.FirstOrDefault(x => x.ActivityId == "Resume");
|
||||
|
||||
// Resume workflow.
|
||||
var runOptions = new RunWorkflowOptions { BookmarkId = bookmark!.Id };
|
||||
await _workflowRunner.RunAsync(workflow, result.WorkflowState, runOptions);
|
||||
|
||||
// Verify expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Line 1", "Line 2", "Line 3" }, lines);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Runtime.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Blocking;
|
||||
|
||||
class BlockingSequentialWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Line 1"),
|
||||
new Event("Resume"){ Id = "Resume"},
|
||||
new WriteLine("Line 2"),
|
||||
new WriteLine("Line 3")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.BlockingAndBreaking.Workflows;
|
||||
using Elsa.Workflows.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.BlockingAndBreaking;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IWorkflowBuilderFactory _workflowBuilderFactory;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_workflowBuilderFactory = _services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Fork completes after all branches complete.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflow = await _workflowBuilderFactory.CreateBuilder().BuildWorkflowAsync<WaitAllForkWorkflow>();
|
||||
|
||||
// Start workflow.
|
||||
var result1 = await _workflowRunner.RunAsync(workflow);
|
||||
|
||||
// Resume the first branch.
|
||||
var bookmark = result1.WorkflowState.Bookmarks.FirstOrDefault(x => x.ActivityId == "Branch 1");
|
||||
var runOptions = new RunWorkflowOptions { BookmarkId = bookmark!.Id };
|
||||
var result2 = await _workflowRunner.RunAsync(workflow, result1.WorkflowState, runOptions);
|
||||
|
||||
// Resume the second branch.
|
||||
bookmark = result2.WorkflowState.Bookmarks.FirstOrDefault(x => x.ActivityId == "Branch 2");
|
||||
runOptions = new RunWorkflowOptions { BookmarkId = bookmark!.Id };
|
||||
var result3 = await _workflowRunner.RunAsync(workflow, result2.WorkflowState, runOptions);
|
||||
|
||||
// Verify expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Start", "Branch 1", "Branch 2", "Branch 1 - Resumed", "Branch 2 - Resumed", "End" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Fork completes after any branch completes.")]
|
||||
public async Task Test2()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflow = await _workflowBuilderFactory.CreateBuilder().BuildWorkflowAsync<WaitAnyForkWorkflow>();
|
||||
|
||||
// Start workflow.
|
||||
var result1 = await _workflowRunner.RunAsync(workflow);
|
||||
|
||||
// Resume the first branch.
|
||||
var bookmark = result1.WorkflowState.Bookmarks.FirstOrDefault(x => x.ActivityId == "Branch 1");
|
||||
var runOptions = new RunWorkflowOptions { BookmarkId = bookmark!.Id };
|
||||
var result2 = await _workflowRunner.RunAsync(workflow, result1.WorkflowState, runOptions);
|
||||
|
||||
// Verify expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Start", "Branch 1", "Branch 2", "Branch 1 - Resumed", "End" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Break breaks out of While loop.")]
|
||||
public async Task Test3()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflow = await _workflowBuilderFactory.CreateBuilder().BuildWorkflowAsync<BreakWhileFromForkWorkflow>();
|
||||
|
||||
// Start workflow.
|
||||
var result1 = await _workflowRunner.RunAsync(workflow);
|
||||
|
||||
// Resume the first branch.
|
||||
var bookmark = result1.WorkflowState.Bookmarks.FirstOrDefault(x => x.ActivityId == "Branch 1");
|
||||
var runOptions = new RunWorkflowOptions { BookmarkId = bookmark!.Id };
|
||||
var result2 = await _workflowRunner.RunAsync(workflow, result1.WorkflowState, runOptions);
|
||||
|
||||
// There should be no bookmarks left, since the while loop was broken out of.
|
||||
Assert.Empty(result2.WorkflowState.Bookmarks);
|
||||
|
||||
// Verify expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Start", "Branch 1", "Branch 2", "Branch 1 - Resumed", "End" }, lines);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Runtime.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.BlockingAndBreaking.Workflows;
|
||||
|
||||
public class BreakWhileFromForkWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var currentValue = new Variable<int?>("CurrentValue", 0);
|
||||
|
||||
workflow.WithVariable(currentValue);
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Start"),
|
||||
new While(() => true)
|
||||
{
|
||||
Body = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new Fork
|
||||
{
|
||||
JoinMode = ForkJoinMode.WaitAll,
|
||||
Branches =
|
||||
{
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Branch 1"),
|
||||
new Event("Branch 1") { Id = "Branch 1" },
|
||||
new WriteLine("Branch 1 - Resumed"),
|
||||
|
||||
// This should break the while loop, not matter how high up in the tree it is.
|
||||
new Break()
|
||||
}
|
||||
},
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Branch 2"),
|
||||
new Event("Branch 2") { Id = "Branch 2" },
|
||||
new WriteLine("Branch 2 - Resumed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new WriteLine("End")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Runtime.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.BlockingAndBreaking.Workflows;
|
||||
|
||||
public class WaitAllForkWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var currentValue = new Variable<int?>("CurrentValue", 0);
|
||||
|
||||
workflow.WithVariable(currentValue);
|
||||
|
||||
workflow.Root =
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Start"),
|
||||
new Fork
|
||||
{
|
||||
JoinMode = ForkJoinMode.WaitAll,
|
||||
Branches =
|
||||
{
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Branch 1"),
|
||||
new Event("Branch 1") { Id = "Branch 1" },
|
||||
new WriteLine("Branch 1 - Resumed"),
|
||||
}
|
||||
},
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Branch 2"),
|
||||
new Event("Branch 2") { Id = "Branch 2" },
|
||||
new WriteLine("Branch 2 - Resumed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new WriteLine("End")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Runtime.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.BlockingAndBreaking.Workflows;
|
||||
|
||||
public class WaitAnyForkWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var currentValue = new Variable<int?>("CurrentValue", 0);
|
||||
|
||||
workflow.WithVariable(currentValue);
|
||||
|
||||
workflow.Root =
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Start"),
|
||||
new Fork
|
||||
{
|
||||
JoinMode = ForkJoinMode.WaitAny,
|
||||
Branches =
|
||||
{
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Branch 1"),
|
||||
new Event("Branch 1") { Id = "Branch 1" },
|
||||
new WriteLine("Branch 1 - Resumed"),
|
||||
}
|
||||
},
|
||||
new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Branch 2"),
|
||||
new Event("Branch 2") { Id = "Branch 2" },
|
||||
new WriteLine("Branch 2 - Resumed"),
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
new WriteLine("End")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.CanExecute.Activities;
|
||||
|
||||
public class CustomActivity : CodeActivity
|
||||
{
|
||||
public CustomActivity(int magicNumber)
|
||||
{
|
||||
MagicNumber = new (magicNumber);
|
||||
}
|
||||
|
||||
public CustomActivity(Func<ExpressionExecutionContext, int> magicNumber)
|
||||
{
|
||||
MagicNumber = new (magicNumber);
|
||||
}
|
||||
|
||||
public Input<int> MagicNumber { get; set; }
|
||||
|
||||
protected override bool CanExecute(ActivityExecutionContext context)
|
||||
{
|
||||
var magicNumber = MagicNumber.Get(context);
|
||||
return magicNumber == 42;
|
||||
}
|
||||
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
var provider = context.GetService<IStandardOutStreamProvider>() ?? new StandardOutStreamProvider(Console.Out);
|
||||
var textWriter = provider.GetTextWriter();
|
||||
textWriter.WriteLine("Welcome to the world of Might and Magic!");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.CanExecute.Activities;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.CanExecute.Workflows;
|
||||
using Elsa.Workflows.Options;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.CanExecute;
|
||||
|
||||
public class CanExecuteTests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
|
||||
public CanExecuteTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.AddActivitiesFrom<CustomActivity>()
|
||||
.Build();
|
||||
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Activities are executed only when they report that they can execute.")]
|
||||
[InlineData(12, "Magic number is 12")]
|
||||
[InlineData(42, "Magic number is 42\nWelcome to the world of Might and Magic!\nDone")]
|
||||
public async Task Test1(int magicNumber, string expectedLines)
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var runOptions = new RunWorkflowOptions
|
||||
{
|
||||
Input = new Dictionary<string, object>
|
||||
{
|
||||
["MagicNumber"] = magicNumber
|
||||
}
|
||||
};
|
||||
await _workflowRunner.RunAsync<MagicWorkflow>(runOptions);
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(expectedLines.Split('\n', StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries), lines);
|
||||
}
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.CanExecute.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.CanExecute.Workflows;
|
||||
|
||||
public class MagicWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
var magicNumberVariable = builder.WithVariable<int>();
|
||||
|
||||
builder.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new SetVariable<int>(magicNumberVariable, context => context.GetInput<int>("MagicNumber")),
|
||||
new WriteLine(context => $"Magic number is {magicNumberVariable.Get(context)}"),
|
||||
new CustomActivity(context => magicNumberVariable.Get(context)),
|
||||
new WriteLine("Done")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Composites;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IWorkflowBuilderFactory _workflowBuilderFactory;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.ConfigureElsa(elsa => elsa.UseJavaScript())
|
||||
.Build();
|
||||
_workflowBuilderFactory = _services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "The main workflow can capture the result of the composite activity")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflow = await _workflowBuilderFactory.CreateBuilder().BuildWorkflowAsync<SumWorkflow>();
|
||||
|
||||
// Start workflow.
|
||||
await _workflowRunner.RunAsync(workflow);
|
||||
|
||||
// Verify expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Sum: 3" }, lines);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Activities;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Composites;
|
||||
|
||||
/// <summary>
|
||||
/// A composite activity that sums two inputs and returns the result.
|
||||
/// </summary>
|
||||
public class Sum : Composite<int>
|
||||
{
|
||||
private readonly RunJavaScript _runJavaScript;
|
||||
|
||||
public Input<int> A { get; set; } = null!;
|
||||
public Input<int> B { get; set; } = null!;
|
||||
|
||||
public Sum()
|
||||
{
|
||||
_runJavaScript = new()
|
||||
{
|
||||
Script = new("getA() + getB();"),
|
||||
};
|
||||
|
||||
Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
_runJavaScript
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override void ConfigureActivities(ActivityExecutionContext context)
|
||||
{
|
||||
// Copy input into variables so that JS activity can access them.
|
||||
var a = A.Get(context);
|
||||
var b = B.Get(context);
|
||||
Variables.Add(new Variable<int>("A", a));
|
||||
Variables.Add(new Variable<int>("B", b));
|
||||
|
||||
// If the call site set a result variable, assign it to the JavaScript activity's result.
|
||||
if (Result != null)
|
||||
_runJavaScript.Result = new(Result.MemoryBlockReference)!;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A workflow that uses the <see cref="Sum"/> composite activity.
|
||||
/// </summary>
|
||||
public class SumWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var sum = workflow.WithVariable<int>("Sum", 0);
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new Sum
|
||||
{
|
||||
A = new(1),
|
||||
B = new(2),
|
||||
Result = new(sum)
|
||||
},
|
||||
new WriteLine(context => $"Sum: {sum.Get(context)}")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.CompositesAndOutcomes;
|
||||
|
||||
public class ExplicitJoinWaitAnyTests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public ExplicitJoinWaitAnyTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.WithWorkflowsFromDirectory("Scenarios", "CompositesAndOutcomes", "Workflows")
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Complete activity must not cascade.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Execute.
|
||||
var workflowState = await _services.RunWorkflowUntilEndAsync("tester");
|
||||
|
||||
// Assert expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
var expectedLinesArray = new[] { "Start", "End" };
|
||||
Assert.Equal(expectedLinesArray, lines);
|
||||
|
||||
// Assert expected workflow status.
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowState.Status);
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"id": "3457460b3fd74daa8f898564cf96fe48",
|
||||
"definitionId": "99c1c6cf2fec47b3b4916a01425ec989",
|
||||
"name": "Completor",
|
||||
"createdAt": "2023-09-14T13:49:38.017111+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [
|
||||
"Success",
|
||||
"Failure"
|
||||
],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true,
|
||||
"activityCategory": "Testing"
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Gn-5gEC2-UCmmzWTgvYCmw",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"outcomes": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Success"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "tyDvLNGiYkCbUabhgzcSdw:input-0"
|
||||
}
|
||||
},
|
||||
"id": "tyDvLNGiYkCbUabhgzcSdw",
|
||||
"name": "Complete1",
|
||||
"type": "Elsa.Complete",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -186.5,
|
||||
"y": -263
|
||||
},
|
||||
"size": {
|
||||
"width": 136.8125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"id": "9b6b4d4a6a8741c58ccbe3911eed7821",
|
||||
"definitionId": "bc7f148b2a5b4f55811537a0d762e137",
|
||||
"name": "Consumer",
|
||||
"createdAt": "2023-09-14T13:50:13.31251+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true,
|
||||
"activityCategory": "Testing"
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "v-ii0Vp0yUCPWReLNUiosg",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "99c1c6cf2fec47b3b4916a01425ec989",
|
||||
"workflowDefinitionVersionId": "3457460b3fd74daa8f898564cf96fe48",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "3457460b3fd74daa8f898564cf96fe48",
|
||||
"id": "ctusr1Uv40uFqIws9Ymt9A",
|
||||
"name": "Completor1",
|
||||
"type": "Completor",
|
||||
"version": 2,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 20,
|
||||
"y": -260
|
||||
},
|
||||
"size": {
|
||||
"width": 106.859375,
|
||||
"height": 116.015625
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+145
@@ -0,0 +1,145 @@
|
||||
{
|
||||
"id": "74144d614208497380a7bae783b78626",
|
||||
"definitionId": "tester",
|
||||
"name": "Tester",
|
||||
"createdAt": "2023-09-14T13:50:38.720025+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "k0HQeDE_gk-OxcsjGj3tbQ",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Start"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "35MeNlWlAUKXd5JFDJtJ3w:input-0"
|
||||
}
|
||||
},
|
||||
"id": "35MeNlWlAUKXd5JFDJtJ3w",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -198,
|
||||
"y": -246.9921875
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "End"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "CvdSrKs5DESezhkLjb0YIw:input-0"
|
||||
}
|
||||
},
|
||||
"id": "CvdSrKs5DESezhkLjb0YIw",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 253,
|
||||
"y": -246.9921875
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "bc7f148b2a5b4f55811537a0d762e137",
|
||||
"workflowDefinitionVersionId": "9b6b4d4a6a8741c58ccbe3911eed7821",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "9b6b4d4a6a8741c58ccbe3911eed7821",
|
||||
"id": "QfkYnRZDxEO0rtBTIbTXzg",
|
||||
"name": "Consumer1",
|
||||
"type": "Consumer",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 20,
|
||||
"y": -280
|
||||
},
|
||||
"size": {
|
||||
"width": 105.5625,
|
||||
"height": 116.015625
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "35MeNlWlAUKXd5JFDJtJ3w",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "QfkYnRZDxEO0rtBTIbTXzg",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "QfkYnRZDxEO0rtBTIbTXzg",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "CvdSrKs5DESezhkLjb0YIw",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.CompositesPassingData;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IWorkflowBuilderFactory _workflowBuilderFactory;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.ConfigureElsa(elsa => elsa.UseJavaScript())
|
||||
.Build();
|
||||
_workflowBuilderFactory = _services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "The main workflow can capture the result of the composite activity")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflow = await _workflowBuilderFactory.CreateBuilder().BuildWorkflowAsync<AddTextMainWorkflow>();
|
||||
|
||||
// Start workflow.
|
||||
await _workflowRunner.RunAsync(workflow);
|
||||
|
||||
// Verify expected output.
|
||||
var line = _capturingTextWriter.Lines.ToList().Last();
|
||||
Assert.Equal("hi there obi wan", line);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Management.Activities.SetOutput;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.CompositesPassingData;
|
||||
|
||||
/// <summary>
|
||||
/// A composite activity that adds text to a string
|
||||
/// </summary>
|
||||
public class AddTextSubWorkflow : Composite
|
||||
{
|
||||
public Input<string> A { get; set; } = default!;
|
||||
public Output<string> B { get; set; } = default!;
|
||||
|
||||
public AddTextSubWorkflow()
|
||||
{
|
||||
var setOutput = new SetOutput()
|
||||
{
|
||||
OutputName = new Input<string>("B"),
|
||||
OutputValue = new Input<object?>(context => "hi there " + A.Get(context))
|
||||
};
|
||||
|
||||
Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
setOutput
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A workflow that uses the <see cref="AddTextSubWorkflow"/> composite activity.
|
||||
/// </summary>
|
||||
public class AddTextMainWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var outVariable = new Variable<string>("out", "test");
|
||||
|
||||
var subWorkflow = new AddTextSubWorkflow()
|
||||
{
|
||||
A = new("obi wan"),
|
||||
B = new (outVariable)
|
||||
};
|
||||
|
||||
workflow.Variables.Add(outVariable);
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
subWorkflow,
|
||||
new WriteLine(context => outVariable.Get(context))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.DependencyWorkflows;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.WithWorkflowsFromDirectory("Scenarios", "DependencyWorkflows", "Workflows")
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Workflows provided from JSON files that depend on other workflows are executed correctly.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Run the "matter" workflow.
|
||||
await _services.RunWorkflowUntilEndAsync("matter-workflow");
|
||||
|
||||
// Assert.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
|
||||
Assert.Equal(new[] { "Atom", "Atom", "Atom", "Atom", "Atom", "Atom", "Atom", "Atom", "Atom" }, lines);
|
||||
}
|
||||
}
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"id": "82b53ccf2a4e4ced966b85fb3cc13eed",
|
||||
"definitionId": "40a40a0cdf5448acbc899391b2c50458",
|
||||
"name": "AtomActivity",
|
||||
"createdAt": "2023-06-01T14:00:29.374132+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"usableAsActivity": true,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": [],
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"start": "Atom",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Atom"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "65ee0198-2051-491d-9035-6d05e73fbd08"
|
||||
}
|
||||
},
|
||||
"id": "Atom",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2394,
|
||||
"y": 2472
|
||||
}
|
||||
},
|
||||
"displayText": "Atom"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+105
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"id": "matter-workflow-v1",
|
||||
"definitionId": "matter-workflow",
|
||||
"name": "Matter Workflow",
|
||||
"createdAt": "2023-06-01T14:06:25.895316+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": [],
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"start": "MoleculeActivity2",
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "86e355d944764f15872f8cfdcc1e9cec",
|
||||
"workflowDefinitionVersionId": "fec9de7279a440f693a5901507140a77",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "fec9de7279a440f693a5901507140a77",
|
||||
"id": "MoleculeActivity1",
|
||||
"type": "MoleculeActivity",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2347,
|
||||
"y": 2407
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "86e355d944764f15872f8cfdcc1e9cec",
|
||||
"workflowDefinitionVersionId": "fec9de7279a440f693a5901507140a77",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "fec9de7279a440f693a5901507140a77",
|
||||
"id": "MoleculeActivity3",
|
||||
"type": "MoleculeActivity",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2560,
|
||||
"y": 2560
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "86e355d944764f15872f8cfdcc1e9cec",
|
||||
"workflowDefinitionVersionId": "fec9de7279a440f693a5901507140a77",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "fec9de7279a440f693a5901507140a77",
|
||||
"id": "MoleculeActivity2",
|
||||
"type": "MoleculeActivity",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2140,
|
||||
"y": 2560
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": "MoleculeActivity2",
|
||||
"target": "MoleculeActivity1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "MoleculeActivity1",
|
||||
"target": "MoleculeActivity3",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"id": "fec9de7279a440f693a5901507140a77",
|
||||
"definitionId": "86e355d944764f15872f8cfdcc1e9cec",
|
||||
"name": "MoleculeActivity",
|
||||
"createdAt": "2023-06-01T14:05:32.409643+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": [],
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"start": "AtomActivity1",
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "40a40a0cdf5448acbc899391b2c50458",
|
||||
"workflowDefinitionVersionId": "82b53ccf2a4e4ced966b85fb3cc13eed",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "82b53ccf2a4e4ced966b85fb3cc13eed",
|
||||
"id": "AtomActivity1",
|
||||
"type": "AtomActivity",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2228,
|
||||
"y": 2418
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "40a40a0cdf5448acbc899391b2c50458",
|
||||
"workflowDefinitionVersionId": "82b53ccf2a4e4ced966b85fb3cc13eed",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "82b53ccf2a4e4ced966b85fb3cc13eed",
|
||||
"id": "AtomActivity2",
|
||||
"type": "AtomActivity",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2458,
|
||||
"y": 2487
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "40a40a0cdf5448acbc899391b2c50458",
|
||||
"workflowDefinitionVersionId": "82b53ccf2a4e4ced966b85fb3cc13eed",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "82b53ccf2a4e4ced966b85fb3cc13eed",
|
||||
"id": "AtomActivity3",
|
||||
"type": "AtomActivity",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"CanStartWorkflow": false,
|
||||
"RunAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2660,
|
||||
"y": 2560
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": "AtomActivity1",
|
||||
"target": "AtomActivity2",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "AtomActivity2",
|
||||
"target": "AtomActivity3",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
using Elsa.Common.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Management;
|
||||
using Elsa.Workflows.Management.Activities.WorkflowDefinitionActivity;
|
||||
using Elsa.Workflows.Management.Entities;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.DependencyWorkflowsPublishing;
|
||||
|
||||
/// <summary>
|
||||
/// Contains tests for the "DependencyWorkflowsPublishing" scenario.
|
||||
/// </summary>
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IWorkflowDefinitionPublisher _workflowDefinitionPublisher;
|
||||
private readonly IActivitySerializer _activitySerializer;
|
||||
private readonly IActivityVisitor _activityVisitor;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Tests"/> class.
|
||||
/// </summary>
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.WithWorkflowsFromDirectory("Scenarios", "DependencyWorkflowsPublishing", "Workflows")
|
||||
.Build();
|
||||
|
||||
_workflowDefinitionPublisher = _services.GetRequiredService<IWorkflowDefinitionPublisher>();
|
||||
_activitySerializer = _services.GetRequiredService<IActivitySerializer>();
|
||||
_activityVisitor = _services.GetRequiredService<IActivityVisitor>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// When a dependency workflow is published, all consuming workflows are updated to point to the new version of the dependency.
|
||||
/// </summary>
|
||||
[Fact(DisplayName = "When a dependency workflow is published, all consuming workflows are updated to point to the new version of the dependency.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var childDefinitionV1 = await _services.GetWorkflowDefinitionAsync("child", VersionOptions.Latest);
|
||||
var parentDefinition = await _services.GetWorkflowDefinitionAsync("parent", VersionOptions.Latest);
|
||||
var childActivityV1 = await GetChildActivityAsync(parentDefinition);
|
||||
|
||||
// Assert initial state.
|
||||
Assert.Equal(1, childDefinitionV1.Version);
|
||||
Assert.False(parentDefinition.IsPublished);
|
||||
Assert.Equal(1, childActivityV1.Version);
|
||||
|
||||
// Create a new draft for the child workflow and publish it.
|
||||
var childDefinitionV2 = (await _workflowDefinitionPublisher.GetDraftAsync(childDefinitionV1.DefinitionId, VersionOptions.Published))!;
|
||||
await _workflowDefinitionPublisher.PublishAsync(childDefinitionV2);
|
||||
|
||||
// Assert that the parent workflow now points to the new version of the child workflow.
|
||||
parentDefinition = await _services.GetWorkflowDefinitionAsync("parent", VersionOptions.Latest);
|
||||
var childActivityV2 = await GetChildActivityAsync(parentDefinition);
|
||||
Assert.Equal(2, childActivityV2.Version);
|
||||
}
|
||||
|
||||
private async Task<WorkflowDefinitionActivity> GetChildActivityAsync(WorkflowDefinition parent)
|
||||
{
|
||||
var root = _activitySerializer.Deserialize(parent.StringData!);
|
||||
var graph = await _activityVisitor.VisitAsync(root);
|
||||
var flattenedList = graph.Flatten().ToList();
|
||||
return (WorkflowDefinitionActivity)flattenedList.Single(x => x.Activity is WorkflowDefinitionActivity { WorkflowDefinitionId: "child" }).Activity;
|
||||
}
|
||||
}
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"id": "child-v1",
|
||||
"definitionId": "child",
|
||||
"name": "Child",
|
||||
"createdAt": "2024-02-07T14:57:47.115341+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "c22918340b6cb7cd",
|
||||
"nodeId": "Workflow1:c22918340b6cb7cd",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
{
|
||||
"id": "ffd312ccf7a2af4f",
|
||||
"definitionId": "parent",
|
||||
"name": "Parent",
|
||||
"createdAt": "2024-02-07T14:58:12.954939+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "3535b9598a0962f0",
|
||||
"nodeId": "Workflow1:3535b9598a0962f0",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "child",
|
||||
"workflowDefinitionVersionId": "child-v1",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "child-v1",
|
||||
"id": "35525d3b78b8e518",
|
||||
"nodeId": "Workflow1:3535b9598a0962f0:35525d3b78b8e518",
|
||||
"name": "Child1",
|
||||
"type": "Child",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -95.17782592773438,
|
||||
"y": -137.3333282470703
|
||||
},
|
||||
"size": {
|
||||
"width": 67.78125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ExplicitJoins;
|
||||
|
||||
public class ExplicitJoinWaitAnyTests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public ExplicitJoinWaitAnyTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Workflows with explicit joins complete the workflow.")]
|
||||
[InlineData("join-any-1.json", "Start; End")]
|
||||
[InlineData("join-all-1.json", "Start; Line 1; Line 2; End")]
|
||||
[InlineData("join-all-2.json", "Start; Line 1; Line 2; End")]
|
||||
public async Task Test1(string filename, string expectedLines)
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import workflow.
|
||||
var fileName = $"Scenarios/ExplicitJoins/Workflows/{filename}";
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync(fileName);
|
||||
|
||||
// Execute.
|
||||
var workflowState = await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
var expectedLinesArray = expectedLines.Split(";", StringSplitOptions.TrimEntries | StringSplitOptions.RemoveEmptyEntries).ToList();
|
||||
Assert.Equal(expectedLinesArray, lines);
|
||||
|
||||
// Assert expected workflow status.
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowState.Status);
|
||||
}
|
||||
}
|
||||
+248
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"id": "9948e541b0e540c384c6eb9fdcf1d544",
|
||||
"definitionId": "296428cc22bd4f309e858f4b461dbb3d",
|
||||
"name": "Join 1",
|
||||
"createdAt": "2023-09-12T18:12:54.370149+00:00",
|
||||
"version": 2,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "sL581qWiIEOpRncv5Ez33A",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"mode": {
|
||||
"typeName": "Elsa.Workflows.Core.Activities.Flowchart.Models.FlowJoinMode, Elsa.Workflows.Core",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WaitAll"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "aA4pfJOzyEqmLOY3U3vCoQ:input-0"
|
||||
}
|
||||
},
|
||||
"id": "aA4pfJOzyEqmLOY3U3vCoQ",
|
||||
"name": "FlowJoin1",
|
||||
"type": "Elsa.FlowJoin",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 198,
|
||||
"y": -266
|
||||
},
|
||||
"size": {
|
||||
"width": 136.859375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Start"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "FRXh0PlHekejZiWANAplUg:input-0"
|
||||
}
|
||||
},
|
||||
"id": "FRXh0PlHekejZiWANAplUg",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -287,
|
||||
"y": -266
|
||||
},
|
||||
"size": {
|
||||
"width": 102.21875,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": "Start"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Line 1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "GaVrCWqBDkS6YrvydxKvFA:input-0"
|
||||
}
|
||||
},
|
||||
"id": "GaVrCWqBDkS6YrvydxKvFA",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -40,
|
||||
"y": -316
|
||||
},
|
||||
"size": {
|
||||
"width": 110.65625,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": "Line 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Line 2"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "9Z7bt98j00uRMt9TS2FD0g:input-0"
|
||||
}
|
||||
},
|
||||
"id": "9Z7bt98j00uRMt9TS2FD0g",
|
||||
"name": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -40,
|
||||
"y": -207
|
||||
},
|
||||
"size": {
|
||||
"width": 110.65625,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": "Line 2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "End"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "MplDrS_bUE-8td-XBUvWmA:input-0"
|
||||
}
|
||||
},
|
||||
"id": "MplDrS_bUE-8td-XBUvWmA",
|
||||
"name": "WriteLine4",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 430,
|
||||
"y": -266
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "FRXh0PlHekejZiWANAplUg",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "GaVrCWqBDkS6YrvydxKvFA",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "FRXh0PlHekejZiWANAplUg",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "9Z7bt98j00uRMt9TS2FD0g",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "9Z7bt98j00uRMt9TS2FD0g",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "aA4pfJOzyEqmLOY3U3vCoQ",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "GaVrCWqBDkS6YrvydxKvFA",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "aA4pfJOzyEqmLOY3U3vCoQ",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "aA4pfJOzyEqmLOY3U3vCoQ",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "MplDrS_bUE-8td-XBUvWmA",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+287
@@ -0,0 +1,287 @@
|
||||
{
|
||||
"id": "14984c048db34cceaf5e15ece80f9703",
|
||||
"definitionId": "64f8f2c852f04dc28f60707034d7a906",
|
||||
"name": "Join 2",
|
||||
"createdAt": "2023-09-12T18:12:43.392272+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "B2jpPDriPEe-zSOhVuAGeQ",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Start"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "2yPLgUudQEGPaschdLdkGg:input-0"
|
||||
}
|
||||
},
|
||||
"id": "2yPLgUudQEGPaschdLdkGg",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -358.5,
|
||||
"y": -229
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": "Start"
|
||||
}
|
||||
},
|
||||
{
|
||||
"body": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "zaAIlUtQDEaPqeITeRJ4_w",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Line 2"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "g3jVTdvU3EK7V5JqRqfqjQ:input-0"
|
||||
}
|
||||
},
|
||||
"id": "g3jVTdvU3EK7V5JqRqfqjQ",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -279.5,
|
||||
"y": -294
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": "Line 2"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
},
|
||||
"id": "eHAEEQ-Iu0GwM3mRxZin0Q",
|
||||
"name": "FlowNode1",
|
||||
"type": "Elsa.FlowNode",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -120,
|
||||
"y": -179
|
||||
},
|
||||
"size": {
|
||||
"width": 211.15625,
|
||||
"height": 120
|
||||
}
|
||||
},
|
||||
"displayText": "Line 2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Line 1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "7RQ2sbVHo0SxsyK0dvTKEA:input-0"
|
||||
}
|
||||
},
|
||||
"id": "7RQ2sbVHo0SxsyK0dvTKEA",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -120,
|
||||
"y": -279
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": "Line 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": {
|
||||
"typeName": "Elsa.Workflows.Core.Activities.Flowchart.Models.FlowJoinMode, Elsa.Workflows.Core",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WaitAll"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "dVUuwMm5XUiYpiYoGo5JKA:input-0"
|
||||
}
|
||||
},
|
||||
"id": "dVUuwMm5XUiYpiYoGo5JKA",
|
||||
"name": "FlowJoin1",
|
||||
"type": "Elsa.FlowJoin",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 180.5,
|
||||
"y": -229
|
||||
},
|
||||
"size": {
|
||||
"width": 136.859375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "End"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "NpZ_yT_irUuE9ASEfYLxbw:input-0"
|
||||
}
|
||||
},
|
||||
"id": "NpZ_yT_irUuE9ASEfYLxbw",
|
||||
"name": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 400,
|
||||
"y": -229
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": "End"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "2yPLgUudQEGPaschdLdkGg",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "7RQ2sbVHo0SxsyK0dvTKEA",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "2yPLgUudQEGPaschdLdkGg",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "eHAEEQ-Iu0GwM3mRxZin0Q",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "7RQ2sbVHo0SxsyK0dvTKEA",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "dVUuwMm5XUiYpiYoGo5JKA",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "eHAEEQ-Iu0GwM3mRxZin0Q",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "dVUuwMm5XUiYpiYoGo5JKA",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "dVUuwMm5XUiYpiYoGo5JKA",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "NpZ_yT_irUuE9ASEfYLxbw",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+245
@@ -0,0 +1,245 @@
|
||||
{
|
||||
"id": "2484d1b14e2348f7a916ecef042536e6",
|
||||
"definitionId": "7204b870946b4968aa786a2c91431242",
|
||||
"name": "Flow Join Any",
|
||||
"createdAt": "2023-09-08T19:07:08.435872+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "F44h770hvkSaOWI_jjbM_A",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"mode": {
|
||||
"typeName": "Elsa.Workflows.Core.Activities.Flowchart.Models.FlowJoinMode, Elsa.Workflows.Core",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WaitAny"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "ImdIbHXtHkiLlrExFlW51A:input-0"
|
||||
}
|
||||
},
|
||||
"id": "ImdIbHXtHkiLlrExFlW51A",
|
||||
"name": "FlowJoin1",
|
||||
"type": "Elsa.FlowJoin",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -180,
|
||||
"y": -320
|
||||
},
|
||||
"size": {
|
||||
"width": 136.859375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": {
|
||||
"typeName": "Elsa.Workflows.Core.Activities.Flowchart.Models.FlowJoinMode, Elsa.Workflows.Core",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WaitAny"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "cxnS1whoCESvwwPyBnno_Q:input-0"
|
||||
}
|
||||
},
|
||||
"id": "cxnS1whoCESvwwPyBnno_Q",
|
||||
"name": "FlowJoin2",
|
||||
"type": "Elsa.FlowJoin",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -180,
|
||||
"y": -80
|
||||
},
|
||||
"size": {
|
||||
"width": 136.859375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": {
|
||||
"typeName": "Elsa.Workflows.Core.Activities.Flowchart.Models.FlowJoinMode, Elsa.Workflows.Core",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WaitAny"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "H0apwXYdoESn2TJ5T_3xAg:input-0"
|
||||
}
|
||||
},
|
||||
"id": "H0apwXYdoESn2TJ5T_3xAg",
|
||||
"name": "FlowJoin3",
|
||||
"type": "Elsa.FlowJoin",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 40,
|
||||
"y": -194
|
||||
},
|
||||
"size": {
|
||||
"width": 136.859375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Start"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Kn9d-EVn2EiaYJqHd8VcmQ:input-0"
|
||||
}
|
||||
},
|
||||
"id": "Kn9d-EVn2EiaYJqHd8VcmQ",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -393.5,
|
||||
"y": -194
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "End"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "haHoM3A5EU6aYu_8dCYaYg:input-0"
|
||||
}
|
||||
},
|
||||
"id": "haHoM3A5EU6aYu_8dCYaYg",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 310.5,
|
||||
"y": -194
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "Kn9d-EVn2EiaYJqHd8VcmQ",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "ImdIbHXtHkiLlrExFlW51A",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "Kn9d-EVn2EiaYJqHd8VcmQ",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "cxnS1whoCESvwwPyBnno_Q",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "ImdIbHXtHkiLlrExFlW51A",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "H0apwXYdoESn2TJ5T_3xAg",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "cxnS1whoCESvwwPyBnno_Q",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "H0apwXYdoESn2TJ5T_3xAg",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "H0apwXYdoESn2TJ5T_3xAg",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "haHoM3A5EU6aYu_8dCYaYg",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.FlowchartCompletion;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for the flowchart completion feature using various workflow setups.
|
||||
/// </summary>
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Workflows should complete successfully.")]
|
||||
[InlineData("workflow1.json")]
|
||||
[InlineData("workflow2.json")]
|
||||
[InlineData("workflow3.json")]
|
||||
[InlineData("workflow4.json")]
|
||||
[InlineData("workflow5.json")]
|
||||
[InlineData("workflow6.json")]
|
||||
public async Task Test1(string workflowFileName)
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import workflow.
|
||||
var fileName = $"Scenarios/FlowchartCompletion/Workflows/{workflowFileName}";
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync(fileName);
|
||||
|
||||
// Execute.
|
||||
var workflowState = await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert that the workflow has completed.
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowState.Status);
|
||||
}
|
||||
}
|
||||
+127
@@ -0,0 +1,127 @@
|
||||
{
|
||||
"id": "f7f7563b32de444797363df61e5109d3",
|
||||
"definitionId": "d91eff09eaad43efb9d58332f1f22c82",
|
||||
"name": "Flows",
|
||||
"createdAt": "2023-04-18T13:32:26.294066+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"metadata": {},
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": []
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2020,
|
||||
"y": 2320
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine2"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine2:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2260,
|
||||
"y": 2260
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine3"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine3:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2260,
|
||||
"y": 2380
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine3"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine2",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine3",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+361
@@ -0,0 +1,361 @@
|
||||
{
|
||||
"id": "dc6576d848aa4f46812356467575705f",
|
||||
"definitionId": "991a4f39f7074a9988465230cfdb8d81",
|
||||
"name": "Braided flow",
|
||||
"createdAt": "2023-04-18T13:45:03.454228+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"metadata": {},
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": []
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine7"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine7:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine7",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2340,
|
||||
"y": 2220
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine9"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine9:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine9",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2560,
|
||||
"y": 2320
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1600,
|
||||
"y": 2320
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine2"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine2:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1820,
|
||||
"y": 2220
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine3"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine3:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1820,
|
||||
"y": 2400
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine4"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine4:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine4",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2160
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine5"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine5:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine5",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2320
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine6"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine6:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine6",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2480
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine8"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine8:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine8",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2340,
|
||||
"y": 2400
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine8"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": "WriteLine5",
|
||||
"target": "WriteLine7",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine8",
|
||||
"target": "WriteLine9",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine7",
|
||||
"target": "WriteLine9",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine2",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine2",
|
||||
"target": "WriteLine4",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine3",
|
||||
"target": "WriteLine5",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine3",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine4",
|
||||
"target": "WriteLine7",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine2",
|
||||
"target": "WriteLine5",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine6",
|
||||
"target": "WriteLine8",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine3",
|
||||
"target": "WriteLine6",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine5",
|
||||
"target": "WriteLine8",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+469
@@ -0,0 +1,469 @@
|
||||
{
|
||||
"id": "01146119d31041c195148662710d95c7",
|
||||
"definitionId": "abb565fd716f4eb7be0510ab8ff36329",
|
||||
"name": "Braided delayed flow",
|
||||
"createdAt": "2023-04-18T14:06:58.250625+00:00",
|
||||
"version": 4,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"metadata": {},
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": []
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1600,
|
||||
"y": 2320
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine2"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine2:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1820,
|
||||
"y": 2220
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine3"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine3:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1820,
|
||||
"y": 2400
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine4"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine4:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine4",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2160
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine5"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine5:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine5",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2320
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine6"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine6:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine6",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2480
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine8"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine8:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine8",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2460,
|
||||
"y": 2400
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine7"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine7:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine7",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2460,
|
||||
"y": 2240
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine9"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine9:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine9",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2680,
|
||||
"y": 2300
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"timeSpan": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:05"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay1:input-1"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"typeName": "Elsa.Scheduling.Models.DelayBlockingStrategy, Elsa.Scheduling",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "NonBlocking"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay1:input-2"
|
||||
}
|
||||
},
|
||||
"autoBlockingThreshold": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:05"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay1:input-3"
|
||||
}
|
||||
},
|
||||
"id": "Delay1",
|
||||
"type": "Elsa.Delay",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2260,
|
||||
"y": 2240
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"timeSpan": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:10"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay2:input-1"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"typeName": "Elsa.Scheduling.Models.DelayBlockingStrategy, Elsa.Scheduling",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "NonBlocking"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay2:input-2"
|
||||
}
|
||||
},
|
||||
"autoBlockingThreshold": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:05"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay2:input-3"
|
||||
}
|
||||
},
|
||||
"id": "Delay2",
|
||||
"type": "Elsa.Delay",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2280,
|
||||
"y": 2440
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine2",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine2",
|
||||
"target": "WriteLine4",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine3",
|
||||
"target": "WriteLine5",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine3",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine5",
|
||||
"target": "WriteLine7",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine2",
|
||||
"target": "WriteLine5",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine6",
|
||||
"target": "Delay2",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine3",
|
||||
"target": "WriteLine6",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine8",
|
||||
"target": "WriteLine9",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "Delay2",
|
||||
"target": "WriteLine8",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine5",
|
||||
"target": "WriteLine8",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "Delay1",
|
||||
"target": "WriteLine7",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine7",
|
||||
"target": "WriteLine9",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine4",
|
||||
"target": "Delay1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+415
@@ -0,0 +1,415 @@
|
||||
{
|
||||
"id": "44200e995aaf429d9975bd7177e271d0",
|
||||
"definitionId": "7d0420cacaad4ae09c589a0355bbef44",
|
||||
"name": "Braided conditional delayed flow",
|
||||
"createdAt": "2023-04-18T14:37:02.902303+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"metadata": {},
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": []
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1600,
|
||||
"y": 2320
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine2"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine2:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1820,
|
||||
"y": 2220
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine2"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine3"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine3:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 1820,
|
||||
"y": 2400
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine4"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine4:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine4",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2160
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine4"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine6"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine6:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine6",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2480
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"typeName": "Boolean",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "True"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "FlowDecision1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "FlowDecision1",
|
||||
"type": "Elsa.FlowDecision",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2320
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"timeSpan": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:05"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay1:input-1"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"typeName": "Elsa.Scheduling.Models.DelayBlockingStrategy, Elsa.Scheduling",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "NonBlocking"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay1:input-2"
|
||||
}
|
||||
},
|
||||
"autoBlockingThreshold": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:05"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay1:input-3"
|
||||
}
|
||||
},
|
||||
"id": "Delay1",
|
||||
"type": "Elsa.Delay",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2320,
|
||||
"y": 2220
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine7"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine7:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine7",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2520,
|
||||
"y": 2220
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"timeSpan": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:10"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay2:input-1"
|
||||
}
|
||||
},
|
||||
"strategy": {
|
||||
"typeName": "Elsa.Scheduling.Models.DelayBlockingStrategy, Elsa.Scheduling",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "NonBlocking"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay2:input-2"
|
||||
}
|
||||
},
|
||||
"autoBlockingThreshold": {
|
||||
"typeName": "TimeSpan",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "00:00:05"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "Delay2:input-3"
|
||||
}
|
||||
},
|
||||
"id": "Delay2",
|
||||
"type": "Elsa.Delay",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2320,
|
||||
"y": 2420
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WriteLine8"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine8:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine8",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2520,
|
||||
"y": 2420
|
||||
}
|
||||
},
|
||||
"displayText": "WriteLine8"
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine2",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine2",
|
||||
"target": "WriteLine4",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine3",
|
||||
"target": "FlowDecision1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "WriteLine3",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine3",
|
||||
"target": "WriteLine6",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "FlowDecision1",
|
||||
"target": "Delay1",
|
||||
"sourcePort": "True",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine2",
|
||||
"target": "FlowDecision1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "Delay1",
|
||||
"target": "WriteLine7",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "Delay2",
|
||||
"target": "WriteLine8",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "FlowDecision1",
|
||||
"target": "Delay2",
|
||||
"sourcePort": "False",
|
||||
"targetPort": "In"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+207
@@ -0,0 +1,207 @@
|
||||
{
|
||||
"id": "3365d4c0198e459f834b799cbfe91154",
|
||||
"definitionId": "4aa1e566da264ab6b5495bedb734096d",
|
||||
"name": "Forking, Containment and Blocking",
|
||||
"description": "A combination of a fork, a containment and a blocking activity.",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "uEnFWEdaWkadgIMHT2umLA",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"id": "MLDV_altcUO5MwP7p5xJWw",
|
||||
"name": "Start1",
|
||||
"type": "Elsa.Start",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -480,
|
||||
"y": -566.046875
|
||||
},
|
||||
"size": {
|
||||
"width": 102.21875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Intermediary"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "EIh3Q0Um1U-QSCh1b3GBjQ:input-0"
|
||||
}
|
||||
},
|
||||
"id": "EIh3Q0Um1U-QSCh1b3GBjQ",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -228.5,
|
||||
"y": -476.046875
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": null,
|
||||
"id": "0Z7Velr5CEW_r7YYoeEjBQ",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 69.34375,
|
||||
"y": -476.046875
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"body": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "NJ5fh2bUWU-TxWeXsbNaSg",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"eventName": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Event4"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "8KVHRw-WpUizyxOq0C6Nvg:input-0"
|
||||
}
|
||||
},
|
||||
"result": null,
|
||||
"id": "8KVHRw-WpUizyxOq0C6Nvg",
|
||||
"name": "Event1",
|
||||
"type": "Elsa.Event",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -840,
|
||||
"y": -500
|
||||
},
|
||||
"size": {
|
||||
"width": 106.828125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
},
|
||||
"id": "HG4wfBhvlEW_149HwNyzHw",
|
||||
"name": "FlowNode1",
|
||||
"type": "Elsa.FlowNode",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -228.5,
|
||||
"y": -704.109375
|
||||
},
|
||||
"size": {
|
||||
"width": 211.15625,
|
||||
"height": 120
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "MLDV_altcUO5MwP7p5xJWw",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "HG4wfBhvlEW_149HwNyzHw",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "MLDV_altcUO5MwP7p5xJWw",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "EIh3Q0Um1U-QSCh1b3GBjQ",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "EIh3Q0Um1U-QSCh1b3GBjQ",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "0Z7Velr5CEW_r7YYoeEjBQ",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
{
|
||||
"id": "e5190066597846cc926f8ae644d706f4",
|
||||
"definitionId": "b07725956291433abee7ff229b415194",
|
||||
"name": "Parallel For Each",
|
||||
"createdAt": "2023-09-10T16:32:58.422674+00:00",
|
||||
"version": 3,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "oplDmRa_zEqH8PCdTcFh8A",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Start"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "NTW8X70bTEaBtlYyU44PcA:input-0"
|
||||
}
|
||||
},
|
||||
"id": "NTW8X70bTEaBtlYyU44PcA",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -352,
|
||||
"y": -286.9921875
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "End"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "6Bf011ZOvUWOfQ1rKJEDFA:input-0"
|
||||
}
|
||||
},
|
||||
"id": "6Bf011ZOvUWOfQ1rKJEDFA",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 169,
|
||||
"y": -286.9921875
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"items": {
|
||||
"typeName": "Object[]",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "[\u0022Apple\u0022, \u0022Banana\u0022, \u0022Cherry\u0022]"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "By4rVs_-2kSDENFO-bniRg:input-0"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "ylZLDh7FQ0WmnbdnRJHutg",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "\u0060Current fruit: ${getCurrentValue()}\u0060"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "fht2JVY0G0KURaRYB9jqlw:input-0"
|
||||
}
|
||||
},
|
||||
"id": "fht2JVY0G0KURaRYB9jqlw",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -459.5,
|
||||
"y": -374
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
},
|
||||
"id": "By4rVs_-2kSDENFO-bniRg",
|
||||
"name": "ParallelForEach1",
|
||||
"type": "Elsa.ParallelForEach",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -100,
|
||||
"y": -320
|
||||
},
|
||||
"size": {
|
||||
"width": 149.203125,
|
||||
"height": 116.015625
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "NTW8X70bTEaBtlYyU44PcA",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "By4rVs_-2kSDENFO-bniRg",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "By4rVs_-2kSDENFO-bniRg",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "6Bf011ZOvUWOfQ1rKJEDFA",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.FlowchartNextActivity.Activities;
|
||||
|
||||
public class CustomActivity : CodeActivity
|
||||
{
|
||||
protected override async ValueTask ExecuteAsync(ActivityExecutionContext context)
|
||||
{
|
||||
await context.CompleteActivityAsync();
|
||||
}
|
||||
}
|
||||
+315
@@ -0,0 +1,315 @@
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Models;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.FlowchartNextActivity.Workflows;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.FlowchartNextActivity;
|
||||
|
||||
public class FlowchartNextActivityTests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
|
||||
public FlowchartNextActivityTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.AddActivitiesFrom<FlowchartNextActivityTests>()
|
||||
.Build();
|
||||
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Flowchart only schedules next activity connected to outcome of previous activity.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<FlowchartWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Line 1" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Flowchart with backward connections and a dangling activity")]
|
||||
public async Task BackwardConnectionTest()
|
||||
{
|
||||
var workflow = new TestWorkflow(workflowBuilder =>
|
||||
{
|
||||
var loopVariable = new Variable<int>("LoopCount", 0);
|
||||
|
||||
var start = new Start();
|
||||
var dangling = new WriteLine("dangling");
|
||||
var writeLineDecision = new FlowSwitch()
|
||||
{
|
||||
Cases = {
|
||||
new FlowSwitchCase("LessThanThree", new Expression("JavaScript", "getVariable('LoopCount') < 3")),
|
||||
new FlowSwitchCase("LessThanOne", new Expression("JavaScript", "getVariable('LoopCount') < 1")),
|
||||
},
|
||||
Mode = new(SwitchMode.MatchAny)
|
||||
};
|
||||
var a = new WriteLine("A");
|
||||
var b = new WriteLine("B");
|
||||
var c = new WriteLine("C");
|
||||
var incrementLoop = new SetVariable()
|
||||
{
|
||||
Variable = loopVariable,
|
||||
Value = new Models.Input<object?>(new Expression("JavaScript", "getVariable('LoopCount') + 1"))
|
||||
};
|
||||
var loopbackDecision = new FlowSwitch()
|
||||
{
|
||||
Cases = {
|
||||
new FlowSwitchCase("EqualOne", new Expression("JavaScript", "getVariable('LoopCount') == 1")),
|
||||
new FlowSwitchCase("LessThanFour", new Expression("JavaScript", "getVariable('LoopCount') < 4")),
|
||||
},
|
||||
Mode = new(SwitchMode.MatchFirst)
|
||||
};
|
||||
var d = new WriteLine("D");
|
||||
var e = new WriteLine("E");
|
||||
var f = new WriteLine("F");
|
||||
var end = new End();
|
||||
|
||||
|
||||
workflowBuilder.Root = new Flowchart
|
||||
{
|
||||
Variables =
|
||||
{
|
||||
loopVariable
|
||||
},
|
||||
Activities =
|
||||
{
|
||||
start,
|
||||
dangling,
|
||||
writeLineDecision,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
incrementLoop,
|
||||
loopbackDecision,
|
||||
d,
|
||||
e,
|
||||
f,
|
||||
end
|
||||
},
|
||||
Connections =
|
||||
{
|
||||
new(start, writeLineDecision),
|
||||
new(dangling, writeLineDecision),
|
||||
new(new Endpoint(writeLineDecision, "LessThanThree"), new Endpoint(a)),
|
||||
new(new Endpoint(writeLineDecision, "LessThanThree"), new Endpoint(b)),
|
||||
new(new Endpoint(writeLineDecision, "LessThanOne"), new Endpoint(c)),
|
||||
new(new Endpoint(writeLineDecision, "Default"), new Endpoint(incrementLoop)),
|
||||
new(a, incrementLoop),
|
||||
new(b, incrementLoop),
|
||||
new(c, incrementLoop),
|
||||
new(incrementLoop, loopbackDecision),
|
||||
new(new Endpoint(loopbackDecision, "EqualOne"), new Endpoint(d)),
|
||||
new(d, incrementLoop),
|
||||
new(new Endpoint(loopbackDecision, "LessThanFour"), new Endpoint(e)),
|
||||
new(e, writeLineDecision),
|
||||
new(new Endpoint(loopbackDecision, "Default"), new Endpoint(f)),
|
||||
new(f, end),
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var result = await _workflowRunner.RunAsync(workflow);
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(WorkflowSubStatus.Finished, result.WorkflowState.SubStatus);
|
||||
Assert.Equal(new[] { "A", "B", "C", "D", "E", "A", "B", "E", "F" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Flowchart with an invalid backward connection")]
|
||||
public async Task InvalidBackwardConnectionTest()
|
||||
{
|
||||
var workflow = new TestWorkflow(workflowBuilder =>
|
||||
{
|
||||
var start = new Start() { Id = "Start" };
|
||||
var a = new WriteLine("A") { Id = "WriteLineA" };
|
||||
var b = new WriteLine("B") { Id = "WriteLineB" };
|
||||
var c = new WriteLine("C") { Id = "WriteLineC" };
|
||||
var d = new WriteLine("D") { Id = "WriteLineD" };
|
||||
var e = new WriteLine("E") { Id = "WriteLineE" };
|
||||
|
||||
workflowBuilder.Root = new Flowchart
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
start,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
e,
|
||||
},
|
||||
Connections =
|
||||
{
|
||||
new(start, a),
|
||||
new(a, b),
|
||||
new(b, c),
|
||||
new(b, d),
|
||||
new(c, e),
|
||||
new(d, e),
|
||||
new(e, c),
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var result = await _workflowRunner.RunAsync(workflow);
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(WorkflowSubStatus.Faulted, result.WorkflowState.SubStatus);
|
||||
Assert.Equal(1, result.WorkflowState.Incidents.Count());
|
||||
Assert.Equal("Invalid backward connection: Every path from the source ('WriteLineE') must go through the target ('WriteLineC') when tracing back to the start.", result.WorkflowState.Incidents.First().Message);
|
||||
Assert.Equal(new[] { "A", "B", "C", "D", "E" }, lines);
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Flowchart with a Join activity executed multiple times")]
|
||||
[InlineData(FlowJoinMode.WaitAll)]
|
||||
[InlineData(FlowJoinMode.WaitAny)]
|
||||
public async Task WaitAnyLoopTest(FlowJoinMode joinMode)
|
||||
{
|
||||
var workflow = new TestWorkflow(workflowBuilder =>
|
||||
{
|
||||
var loopVariable = new Variable<int>("LoopCount", 0);
|
||||
|
||||
var start = new Start();
|
||||
var a = new WriteLine("A");
|
||||
var b = new WriteLine("B");
|
||||
var c = new WriteLine("C");
|
||||
var d = new WriteLine("D");
|
||||
var join = new FlowJoin()
|
||||
{
|
||||
Mode = new(joinMode)
|
||||
};
|
||||
var incrementLoop = new SetVariable()
|
||||
{
|
||||
Variable = loopVariable,
|
||||
Value = new Models.Input<object?>(new Expression("JavaScript", "getVariable('LoopCount') + 1"))
|
||||
};
|
||||
var loopbackDecision = new FlowSwitch()
|
||||
{
|
||||
Cases = {
|
||||
new FlowSwitchCase("LessThanThree", new Expression("JavaScript", "getVariable('LoopCount') < 3")),
|
||||
},
|
||||
Mode = new(SwitchMode.MatchFirst)
|
||||
};
|
||||
var end = new End();
|
||||
|
||||
|
||||
workflowBuilder.Root = new Flowchart
|
||||
{
|
||||
Variables =
|
||||
{
|
||||
loopVariable
|
||||
},
|
||||
Activities =
|
||||
{
|
||||
start,
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
d,
|
||||
join,
|
||||
incrementLoop,
|
||||
loopbackDecision,
|
||||
end
|
||||
},
|
||||
Connections =
|
||||
{
|
||||
new(start, a),
|
||||
new(a, b),
|
||||
new(a, c),
|
||||
new(a, d),
|
||||
new(b, join),
|
||||
new(c, join),
|
||||
new(d, join),
|
||||
new(join, incrementLoop),
|
||||
new(incrementLoop,loopbackDecision),
|
||||
new(new Endpoint(loopbackDecision, "LessThanThree"), new Endpoint(a)),
|
||||
new(new Endpoint(loopbackDecision, "Default"), new Endpoint(end)),
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var result = await _workflowRunner.RunAsync(workflow);
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(WorkflowSubStatus.Finished, result.WorkflowState.SubStatus);
|
||||
Assert.Equal(new[] { "A", "B", "C", "D", "A", "B", "C", "D", "A", "B", "C", "D"}, lines);
|
||||
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Flowchart with a Join activity executed multiple times, bug 6479")]
|
||||
[InlineData(FlowJoinMode.WaitAll)]
|
||||
[InlineData(FlowJoinMode.WaitAny)]
|
||||
public async Task WaitLoopBug6479Test(FlowJoinMode joinMode)
|
||||
{
|
||||
var workflow = new TestWorkflow(workflowBuilder =>
|
||||
{
|
||||
var loopVariable = new Variable<int>("LoopCount", 0);
|
||||
|
||||
var start = new Start();
|
||||
var loopbackSwitch = new FlowSwitch()
|
||||
{
|
||||
Cases = {
|
||||
new FlowSwitchCase("DoLoopback", new Expression("JavaScript", "getVariable('LoopCount') < 3")),
|
||||
},
|
||||
Mode = new(SwitchMode.MatchFirst)
|
||||
};
|
||||
var a = new WriteLine("A");
|
||||
var incrementLoop = new SetVariable()
|
||||
{
|
||||
Variable = loopVariable,
|
||||
Value = new Models.Input<object?>(new Expression("JavaScript", "getVariable('LoopCount') + 1"))
|
||||
};
|
||||
var join = new FlowJoin()
|
||||
{
|
||||
Mode = new(joinMode)
|
||||
};
|
||||
var b = new WriteLine("B");
|
||||
var end = new End();
|
||||
|
||||
|
||||
workflowBuilder.Root = new Flowchart
|
||||
{
|
||||
Variables =
|
||||
{
|
||||
loopVariable
|
||||
},
|
||||
Activities =
|
||||
{
|
||||
start,
|
||||
loopbackSwitch,
|
||||
a,
|
||||
incrementLoop,
|
||||
join,
|
||||
b,
|
||||
end
|
||||
},
|
||||
Connections =
|
||||
{
|
||||
new(start, loopbackSwitch),
|
||||
new(new Endpoint(loopbackSwitch, "DoLoopback"), new Endpoint(a)),
|
||||
new(new Endpoint(loopbackSwitch, "DoLoopback"), new Endpoint(incrementLoop)),
|
||||
new(new Endpoint(loopbackSwitch, "Default"), new Endpoint(b)),
|
||||
new(a, join),
|
||||
new(incrementLoop, join),
|
||||
new(join, loopbackSwitch),
|
||||
new(b, end),
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var result = await _workflowRunner.RunAsync(workflow);
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(WorkflowSubStatus.Finished, result.WorkflowState.SubStatus);
|
||||
Assert.Equal(new[] { "A", "A", "A", "B" }, lines);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Models;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.FlowchartNextActivity.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.FlowchartNextActivity.Workflows;
|
||||
|
||||
public class FlowchartWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
var customActivity = new CustomActivity();
|
||||
var writeLine1 = new WriteLine("Line 1");
|
||||
var writeLine2 = new WriteLine("Line 2");
|
||||
|
||||
builder.Root = new Flowchart
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
customActivity,
|
||||
writeLine1,
|
||||
writeLine2
|
||||
},
|
||||
Connections =
|
||||
{
|
||||
new Connection(new Endpoint(customActivity, "Done"), new Endpoint(writeLine1)),
|
||||
new Connection(new Endpoint(customActivity, "Fake"), new Endpoint(writeLine2)),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.JavaScript.Activities;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.HttpRequestWithLiquid;
|
||||
|
||||
/// <summary>
|
||||
/// A workflow that use javascript to get some data, use them with some liquid expressions
|
||||
/// </summary>
|
||||
public class JavascriptAndLiquidWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
var products = new Variable<object>("Products", null!).WithStorageDriver<WorkflowInstanceStorageDriver>();
|
||||
var product = new Variable<object>("Product", null!).WithStorageDriver<WorkflowInstanceStorageDriver>();
|
||||
|
||||
builder.Root = new Sequence
|
||||
{
|
||||
Variables = { products, product },
|
||||
Activities =
|
||||
{
|
||||
new RunJavaScript
|
||||
{
|
||||
Script = new(@"setProducts([{""id"":1, ""price"":12.99}, {""id"":2, ""price"":10}, {""id"":3, ""price"":1}])")
|
||||
},
|
||||
new WriteLine(new Expression("Liquid", "First product id: {{ Variables.Products[0].id }}")),
|
||||
new WriteLine(new Expression("Liquid", "First product price rounded: {{ Variables.Products[0].price | round }}")),
|
||||
new WriteLine(new Expression("Liquid", "First product as json: {{ Variables.Products[0] | json }}")),
|
||||
new WriteLine(new Expression("Liquid", "Second product id: {{ Variables.Products[1].id }}")),
|
||||
new RunJavaScript
|
||||
{
|
||||
Script = new(@"variables.Product = {""id"":2, ""price"":10}")
|
||||
},
|
||||
new WriteLine(new Expression("Liquid", "Single product id: {{ Variables.Product.id }}")),
|
||||
new WriteLine(new Expression("Liquid", "Single product as json: {{ Variables.Product | json }}")),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Models;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.HttpRequestWithLiquid;
|
||||
|
||||
public sealed class Tests : IDisposable
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.ConfigureElsa(configure => configure.UseHttp())
|
||||
.Build();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetProducts()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
RunWorkflowResult result = await _workflowRunner.RunAsync(new JavascriptAndLiquidWorkflow());
|
||||
Assert.Equal(WorkflowStatus.Finished, result.WorkflowState.Status);
|
||||
Assert.Empty(result.WorkflowState.Incidents);
|
||||
Assert.Equal(WorkflowSubStatus.Finished, result.WorkflowState.SubStatus);
|
||||
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Contains("First product id: 1", lines);
|
||||
Assert.Contains("First product price rounded: 13", lines);
|
||||
Assert.Contains("First product as json: {\"id\":1,\"price\":12.99}", lines);
|
||||
Assert.Contains("Second product id: 2", lines);
|
||||
|
||||
Assert.Contains("Single product id: 2", lines);
|
||||
Assert.Contains("Single product as json: {\"id\":2,\"price\":10}", lines);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_capturingTextWriter.Dispose();
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins.Workflows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins;
|
||||
|
||||
public class BraidedWorkflowTests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public BraidedWorkflowTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Braided workflows are executed correctly")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<BraidedWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "WriteLine1", "WriteLine2", "WriteLine3", "WriteLine4", "WriteLine5", "WriteLine6", "WriteLine7" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Braided workflows complete the workflow")]
|
||||
public async Task Test2()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var result = await _workflowRunner.RunAsync<BraidedWorkflow>();
|
||||
Assert.Equal(WorkflowStatus.Finished, result.WorkflowState.Status);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins.Workflows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins;
|
||||
|
||||
public class ImplicitWorkflowTests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public ImplicitWorkflowTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Implicit loop workflows are executed correctly")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<ImplicitLoopWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Start", "Retry", "End" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Implicit loop workflows complete the workflow")]
|
||||
public async Task Test2()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var result = await _workflowRunner.RunAsync<ImplicitLoopWorkflow>();
|
||||
Assert.Equal(WorkflowStatus.Finished, result.WorkflowState.Status);
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using Elsa.Common.Models;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Runtime;
|
||||
using Elsa.Workflows.Runtime.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins;
|
||||
|
||||
public class JoinRunsOnceTests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public JoinRunsOnceTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "The Join activity executes only once, not twice")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import workflow.
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync($"Scenarios/ImplicitJoins/Workflows/join.json");
|
||||
|
||||
// Execute.
|
||||
var state = await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert.
|
||||
var journal = await _services.GetRequiredService<IWorkflowExecutionLogStore>().FindManyAsync(new WorkflowExecutionLogRecordFilter
|
||||
{
|
||||
WorkflowInstanceId = state.Id,
|
||||
ActivityId = "802725996be1b582",
|
||||
EventName = "Completed"
|
||||
}, PageArgs.All);
|
||||
|
||||
Assert.Single(journal.Items);
|
||||
}
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
using Elsa.Common.Models;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Runtime;
|
||||
using Elsa.Workflows.Runtime.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins;
|
||||
|
||||
public class ParallelJoinCompletesTests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public ParallelJoinCompletesTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "The ParallelForEach activity completes when its Body contains a Join activity")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import workflow.
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync("Scenarios/ImplicitJoins/Workflows/parallel-join.json");
|
||||
|
||||
// Execute.
|
||||
var state = await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert.
|
||||
var journal = await _services.GetRequiredService<IWorkflowExecutionLogStore>().FindManyAsync(new()
|
||||
{
|
||||
WorkflowInstanceId = state.Id,
|
||||
ActivityId = "70fc1183cd5800f2",
|
||||
EventName = "Completed"
|
||||
}, PageArgs.All);
|
||||
|
||||
Assert.Single(journal.Items);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins.Workflows;
|
||||
|
||||
public class BraidedWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var writeLine1 = new WriteLine("WriteLine1");
|
||||
var writeLine2 = new WriteLine("WriteLine2");
|
||||
var writeLine3 = new WriteLine("WriteLine3");
|
||||
var writeLine4 = new WriteLine("WriteLine4");
|
||||
var writeLine5 = new WriteLine("WriteLine5");
|
||||
var writeLine6 = new WriteLine("WriteLine6");
|
||||
var writeLine7 = new WriteLine("WriteLine7");
|
||||
|
||||
workflow.Root = new Flowchart
|
||||
{
|
||||
Start = writeLine1,
|
||||
|
||||
Activities =
|
||||
{
|
||||
writeLine1,
|
||||
writeLine2,
|
||||
writeLine3,
|
||||
writeLine4,
|
||||
writeLine5,
|
||||
writeLine6,
|
||||
writeLine7,
|
||||
},
|
||||
|
||||
Connections =
|
||||
{
|
||||
new Connection(writeLine1, writeLine2),
|
||||
new Connection(writeLine1, writeLine3),
|
||||
|
||||
new Connection(writeLine2, writeLine4),
|
||||
new Connection(writeLine2, writeLine5),
|
||||
|
||||
new Connection(writeLine3, writeLine5),
|
||||
new Connection(writeLine3, writeLine6),
|
||||
|
||||
new Connection(writeLine4, writeLine7),
|
||||
new Connection(writeLine5, writeLine7),
|
||||
new Connection(writeLine6, writeLine7),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ImplicitJoins.Workflows;
|
||||
|
||||
public class ImplicitLoopWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
var counterVariable = builder.WithVariable(0);
|
||||
var start = new WriteLine("Start");
|
||||
var incrementCounter = new SetVariable<int>(counterVariable, context => counterVariable.Get(context) + 1);
|
||||
var counterGreaterThanOne = new FlowDecision(context => counterVariable.Get(context) > 1);
|
||||
var retry = new WriteLine("Retry");
|
||||
var end = new WriteLine("End");
|
||||
|
||||
builder.Root = new Flowchart
|
||||
{
|
||||
Start = start,
|
||||
|
||||
Activities =
|
||||
{
|
||||
start,
|
||||
incrementCounter,
|
||||
counterGreaterThanOne,
|
||||
retry,
|
||||
end
|
||||
},
|
||||
|
||||
Connections =
|
||||
{
|
||||
new Connection(start, incrementCounter),
|
||||
new Connection(incrementCounter, counterGreaterThanOne),
|
||||
new Connection(new Endpoint(counterGreaterThanOne, "False"), new Endpoint(retry)),
|
||||
new Connection(new Endpoint(counterGreaterThanOne, "True"), new Endpoint(end)),
|
||||
new Connection(retry, incrementCounter),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
{
|
||||
"id": "825e9d347e2f3094",
|
||||
"definitionId": "f64e42304661f407",
|
||||
"name": "Joins",
|
||||
"createdAt": "2023-12-13T21:41:53.628415+00:00",
|
||||
"version": 3,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "8a03bf79d15fd48a",
|
||||
"nodeId": "Workflow1:8a03bf79d15fd48a",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"id": "c7624645ff77c7d0",
|
||||
"nodeId": "Workflow1:8a03bf79d15fd48a:c7624645ff77c7d0",
|
||||
"name": "Start1",
|
||||
"type": "Elsa.Start",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -400.5,
|
||||
"y": 212
|
||||
},
|
||||
"size": {
|
||||
"width": 102.21875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": null,
|
||||
"id": "281e9ea6d278b231",
|
||||
"nodeId": "Workflow1:8a03bf79d15fd48a:281e9ea6d278b231",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -160.5,
|
||||
"y": 305
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": {
|
||||
"typeName": "Elsa.Workflows.Core.Activities.Flowchart.Models.FlowJoinMode, Elsa.Workflows.Core",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WaitAny"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "802725996be1b582:input-0"
|
||||
}
|
||||
},
|
||||
"id": "802725996be1b582",
|
||||
"nodeId": "Workflow1:8a03bf79d15fd48a:802725996be1b582",
|
||||
"name": "FlowJoin1",
|
||||
"type": "Elsa.FlowJoin",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 80,
|
||||
"y": 200
|
||||
},
|
||||
"size": {
|
||||
"width": 98.265625,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": null,
|
||||
"id": "bfc88f064cf394ed",
|
||||
"nodeId": "Workflow1:8a03bf79d15fd48a:bfc88f064cf394ed",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -160,
|
||||
"y": 120
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "5467123c7973d011",
|
||||
"nodeId": "Workflow1:8a03bf79d15fd48a:5467123c7973d011",
|
||||
"name": "End1",
|
||||
"type": "Elsa.End",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 274.5,
|
||||
"y": 200
|
||||
},
|
||||
"size": {
|
||||
"width": 94.40625,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "c7624645ff77c7d0",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "bfc88f064cf394ed",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "bfc88f064cf394ed",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "802725996be1b582",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "c7624645ff77c7d0",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "281e9ea6d278b231",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "281e9ea6d278b231",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "802725996be1b582",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "802725996be1b582",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "5467123c7973d011",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+241
@@ -0,0 +1,241 @@
|
||||
{
|
||||
"id": "2effd8f5f4205a5b",
|
||||
"definitionId": "2da8d4cb0fcfbacd",
|
||||
"name": "Parallel \u002B Join",
|
||||
"createdAt": "2023-12-13T21:42:12.634042+00:00",
|
||||
"version": 2,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "d3350290ed96e720",
|
||||
"nodeId": "Workflow1:d3350290ed96e720",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"items": {
|
||||
"typeName": "Object[]",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "[1,2,3]"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "70fc1183cd5800f2:input-0"
|
||||
}
|
||||
},
|
||||
"body": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "b07170f2d68980cd",
|
||||
"nodeId": "Workflow1:d3350290ed96e720:70fc1183cd5800f2:b07170f2d68980cd",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"condition": {
|
||||
"typeName": "Boolean",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "false"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "33665f061d96b957:input-0"
|
||||
}
|
||||
},
|
||||
"id": "33665f061d96b957",
|
||||
"nodeId": "Workflow1:d3350290ed96e720:70fc1183cd5800f2:b07170f2d68980cd:33665f061d96b957",
|
||||
"name": "FlowDecision1",
|
||||
"type": "Elsa.FlowDecision",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -329.140625,
|
||||
"y": -78.5
|
||||
},
|
||||
"size": {
|
||||
"width": 129.515625,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": null,
|
||||
"id": "e27177eb5965bd6b",
|
||||
"nodeId": "Workflow1:d3350290ed96e720:70fc1183cd5800f2:b07170f2d68980cd:e27177eb5965bd6b",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -40,
|
||||
"y": -160
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": null,
|
||||
"id": "343d233a75d8d8e9",
|
||||
"nodeId": "Workflow1:d3350290ed96e720:70fc1183cd5800f2:b07170f2d68980cd:343d233a75d8d8e9",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 371.859375,
|
||||
"y": -78.5
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"mode": {
|
||||
"typeName": "Elsa.Workflows.Core.Activities.Flowchart.Models.FlowJoinMode, Elsa.Workflows.Core",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "WaitAny"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "1f8625e278b74aa3:input-0"
|
||||
}
|
||||
},
|
||||
"id": "1f8625e278b74aa3",
|
||||
"nodeId": "Workflow1:d3350290ed96e720:70fc1183cd5800f2:b07170f2d68980cd:1f8625e278b74aa3",
|
||||
"name": "FlowJoin1",
|
||||
"type": "Elsa.FlowJoin",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 188.859375,
|
||||
"y": -78.5
|
||||
},
|
||||
"size": {
|
||||
"width": 98.265625,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "33665f061d96b957",
|
||||
"port": "True"
|
||||
},
|
||||
"target": {
|
||||
"activity": "e27177eb5965bd6b",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "e27177eb5965bd6b",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "1f8625e278b74aa3",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "1f8625e278b74aa3",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "343d233a75d8d8e9",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "33665f061d96b957",
|
||||
"port": "False"
|
||||
},
|
||||
"target": {
|
||||
"activity": "1f8625e278b74aa3",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"id": "70fc1183cd5800f2",
|
||||
"nodeId": "Workflow1:d3350290ed96e720:70fc1183cd5800f2",
|
||||
"name": "ParallelForEach1",
|
||||
"type": "Elsa.ParallelForEach",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -260,
|
||||
"y": 140
|
||||
},
|
||||
"size": {
|
||||
"width": 185.203125,
|
||||
"height": 116.015625
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ImportAndExecute;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Workflow imported from file should execute successfully.")]
|
||||
[MemberData(memberName: nameof(GetSpecimen))]
|
||||
public async Task Test1(string workflowFileName, string[] expectedOutput)
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import workflow.
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync($"Scenarios/ImportAndExecute/Workflows/{workflowFileName}");
|
||||
|
||||
// Execute.
|
||||
await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
|
||||
Assert.Equal(expectedOutput, lines);
|
||||
}
|
||||
|
||||
public static TheoryData<string, string[]> GetSpecimen()
|
||||
{
|
||||
return new TheoryData<string, string[]>
|
||||
{
|
||||
{ "writeline.json", new[] { "Dummy Text" } },
|
||||
{ "implicit-loop.json", new[] { "Do something", "Retry", "Do something", "Done" } }
|
||||
};
|
||||
}
|
||||
}
|
||||
+243
@@ -0,0 +1,243 @@
|
||||
{
|
||||
"id": "0975a7e7cff7421ea03d1cc0247db02b",
|
||||
"definitionId": "68e6bca3d86c4a5a8dfb825f1d5c0875",
|
||||
"name": "Looping construct",
|
||||
"createdAt": "2023-04-18T19:04:50.945222+00:00",
|
||||
"version": 1,
|
||||
"variables": [
|
||||
{
|
||||
"id": "b1198ecccf3f435abe462dc37012cda9",
|
||||
"name": "Counter",
|
||||
"typeName": "Int32",
|
||||
"isArray": false,
|
||||
"value": "0",
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
}
|
||||
],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"metadata": {},
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": []
|
||||
},
|
||||
"start": "Start1",
|
||||
"activities": [
|
||||
{
|
||||
"variable": {
|
||||
"id": "b1198ecccf3f435abe462dc37012cda9",
|
||||
"name": "Counter",
|
||||
"typeName": "Int32",
|
||||
"value": "0",
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
},
|
||||
"value": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "getCounter() \u002B 1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "SetVariable1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "SetVariable1",
|
||||
"type": "Elsa.SetVariable",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2620,
|
||||
"y": 2280
|
||||
}
|
||||
},
|
||||
"displayText": "Increment counter"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Done"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine3:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 3220,
|
||||
"y": 2400
|
||||
}
|
||||
},
|
||||
"displayText": "Done"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Retry"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine2:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2460,
|
||||
"y": 2500
|
||||
}
|
||||
},
|
||||
"displayText": "Retry"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Do something"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2320,
|
||||
"y": 2280
|
||||
}
|
||||
},
|
||||
"displayText": "Do something"
|
||||
}
|
||||
},
|
||||
{
|
||||
"condition": {
|
||||
"typeName": "Boolean",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "getCounter() \u003E 1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "FlowDecision1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "FlowDecision1",
|
||||
"type": "Elsa.FlowDecision",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2940,
|
||||
"y": 2400
|
||||
}
|
||||
},
|
||||
"displayText": "Counter \u003E 1"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "Start1",
|
||||
"type": "Elsa.Start",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2060,
|
||||
"y": 2380
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": "WriteLine1",
|
||||
"target": "SetVariable1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "FlowDecision1",
|
||||
"target": "WriteLine3",
|
||||
"sourcePort": "True",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "FlowDecision1",
|
||||
"target": "WriteLine2",
|
||||
"sourcePort": "False",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "Start1",
|
||||
"target": "WriteLine1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "WriteLine2",
|
||||
"target": "WriteLine1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
},
|
||||
{
|
||||
"source": "SetVariable1",
|
||||
"target": "FlowDecision1",
|
||||
"sourcePort": "Done",
|
||||
"targetPort": "In"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"id": "3a793167cf6948c899d2f40c3c05cf0b",
|
||||
"definitionId": "11e2b350dae8485498c16d1ce3843829",
|
||||
"name": "Dummy workflow",
|
||||
"createdAt": "2023-04-04T08:35:22.841043+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"metadata": {},
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"applicationProperties": {
|
||||
"NotFoundConnectionsKey": []
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Dummy Text"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WriteLine1:input-1"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false,
|
||||
"customProperties": {},
|
||||
"source": null,
|
||||
"line": null,
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2256,
|
||||
"y": 2462
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IncidentStrategies;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.Incidents.Statics;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.Incidents.Workflows;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Incidents;
|
||||
|
||||
public class IncidentStrategyTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
|
||||
public IncidentStrategyTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.AddWorkflow<FaultyWorkflow>()
|
||||
.Build();
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Workflows with a Fault strategy do not continue after a fault")]
|
||||
[InlineData(typeof(FaultStrategy), new[] { "Start", "Step 1a", "Step 2a" }, WorkflowSubStatus.Faulted)]
|
||||
[InlineData(typeof(ContinueWithIncidentsStrategy), new[] { "Start", "Step 1a", "Step 2a", "Step 1b" }, WorkflowSubStatus.Suspended)]
|
||||
public async Task Test0(Type incidentStrategyType, string[] expectedOutput, WorkflowSubStatus expectedSubStatus)
|
||||
{
|
||||
TestSettings.IncidentStrategyType = incidentStrategyType;
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflowState = await _services.RunWorkflowUntilEndAsync<FaultyWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(expectedOutput, lines);
|
||||
Assert.Equal(expectedSubStatus, workflowState.SubStatus);
|
||||
Assert.Equal(1, workflowState.Incidents.Count);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
using Elsa.Workflows.IncidentStrategies;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Incidents.Statics;
|
||||
|
||||
public static class TestSettings
|
||||
{
|
||||
public static Type IncidentStrategyType { get; set; } = typeof(FaultStrategy);
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Activities;
|
||||
using Elsa.Workflows.Activities.Flowchart.Models;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.Incidents.Statics;
|
||||
using Elsa.Workflows.Runtime.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Incidents.Workflows;
|
||||
|
||||
public class FaultyWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
var start = new WriteLine("Start");
|
||||
var step1A = new WriteLine("Step 1a");
|
||||
var event1 = new Event("Event 1");
|
||||
var step1B = new WriteLine("Step 1b");
|
||||
var step2A = new WriteLine("Step 2a");
|
||||
var event2 = new Event("Event 2");
|
||||
var step2B = new WriteLine("Step 2b");
|
||||
var fault = Fault.Create("Whoops!", "Test", "Test");
|
||||
|
||||
builder.WorkflowOptions.IncidentStrategyType = TestSettings.IncidentStrategyType;
|
||||
|
||||
builder.Root = new Flowchart
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
start,
|
||||
step1A,
|
||||
event1,
|
||||
step1B,
|
||||
step2A,
|
||||
event2,
|
||||
step2B,
|
||||
fault
|
||||
},
|
||||
|
||||
Connections = new[]
|
||||
{
|
||||
new Connection(start, step1A),
|
||||
new Connection(step1A, event1),
|
||||
new Connection(event1, step1B),
|
||||
|
||||
new Connection(start, step2A),
|
||||
new Connection(step2A, fault),
|
||||
new Connection(fault, event2),
|
||||
new Connection(event2, step2B),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
using System.Text;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Contracts;
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JavaScriptFunctions;
|
||||
|
||||
public class BytesAndStringEncodingTests
|
||||
{
|
||||
private readonly IJavaScriptEvaluator _evaluator;
|
||||
private readonly ExpressionExecutionContext _expressionContext;
|
||||
|
||||
public BytesAndStringEncodingTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
var testOutputHelper1 = testOutputHelper ?? throw new ArgumentNullException(nameof(testOutputHelper));
|
||||
var services = new TestApplicationBuilder(testOutputHelper1).Build();
|
||||
_evaluator = services.GetRequiredService<IJavaScriptEvaluator>();
|
||||
_expressionContext = new ExpressionExecutionContext(services, new MemoryRegister());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ByteArrayToString_ConvertsTo_String()
|
||||
{
|
||||
const string data = "Hello World!";
|
||||
var bytes = Encoding.UTF8.GetBytes(data);
|
||||
var script = "bytesToString(getData())";
|
||||
_expressionContext.SetVariable("Data", bytes);
|
||||
var result = (string)(await _evaluator.EvaluateAsync(script, typeof(string), _expressionContext))!;
|
||||
|
||||
Assert.Equal(data, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ByteArrayFromString_ConvertsTo_ByteArray()
|
||||
{
|
||||
const string data = "Hello World!";
|
||||
var script = "bytesFromString(getData())";
|
||||
_expressionContext.SetVariable("Data", data);
|
||||
var result = (byte[])(await _evaluator.EvaluateAsync(script, typeof(byte[]), _expressionContext))!;
|
||||
var bytes = Encoding.UTF8.GetBytes(data);
|
||||
|
||||
Assert.Equal(bytes, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ByteArrayToBase64_ConvertsTo_Base64()
|
||||
{
|
||||
const string data = "Hello World!";
|
||||
var bytes = Encoding.UTF8.GetBytes(data);
|
||||
var base64 = Convert.ToBase64String(bytes);
|
||||
var script = "bytesToBase64(getData())";
|
||||
_expressionContext.SetVariable("Data", bytes);
|
||||
var result = (string)(await _evaluator.EvaluateAsync(script, typeof(string), _expressionContext))!;
|
||||
|
||||
Assert.Equal(base64, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ByteArrayFromBase64_ConvertsTo_ByteArray()
|
||||
{
|
||||
const string data = "Hello World!";
|
||||
var bytes = Encoding.UTF8.GetBytes(data);
|
||||
var base64 = Convert.ToBase64String(bytes);
|
||||
var script = "bytesFromBase64(getData())";
|
||||
_expressionContext.SetVariable("Data", base64);
|
||||
var result = (byte[])(await _evaluator.EvaluateAsync(script, typeof(byte[]), _expressionContext))!;
|
||||
|
||||
Assert.Equal(bytes, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task StringToBase64_ConvertsTo_Base64()
|
||||
{
|
||||
const string data = "Hello World!";
|
||||
var bytes = Encoding.UTF8.GetBytes(data);
|
||||
var base64 = Convert.ToBase64String(bytes);
|
||||
var script = "stringToBase64(getData())";
|
||||
_expressionContext.SetVariable("Data", data);
|
||||
var result = (string)(await _evaluator.EvaluateAsync(script, typeof(string), _expressionContext))!;
|
||||
|
||||
Assert.Equal(base64, result);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task StringFromBase64_ConvertsTo_String()
|
||||
{
|
||||
const string data = "Hello World!";
|
||||
var bytes = Encoding.UTF8.GetBytes(data);
|
||||
var base64 = Convert.ToBase64String(bytes);
|
||||
var script = "stringFromBase64(getData())";
|
||||
_expressionContext.SetVariable("Data", base64);
|
||||
var result = (string)(await _evaluator.EvaluateAsync(script, typeof(string), _expressionContext))!;
|
||||
|
||||
Assert.Equal(data, result);
|
||||
}
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
using System.Dynamic;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.Extensions;
|
||||
using Elsa.JavaScript.Contracts;
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JavaScriptListsAndArrays;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IJavaScriptEvaluator _evaluator;
|
||||
private readonly ExpressionExecutionContext _expressionContext;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
var testOutputHelper1 = testOutputHelper ?? throw new ArgumentNullException(nameof(testOutputHelper));
|
||||
var services = new TestApplicationBuilder(testOutputHelper1).Build();
|
||||
_evaluator = services.GetRequiredService<IJavaScriptEvaluator>();
|
||||
_expressionContext = new ExpressionExecutionContext(services, new MemoryRegister());
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Workflow inputs containing .NET lists on dynamic objects are converted to arrays for use in JavaScript.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
dynamic dynamicObject = new ExpandoObject();
|
||||
|
||||
dynamicObject.List = new List<string>
|
||||
{
|
||||
"a",
|
||||
"b",
|
||||
"c"
|
||||
};
|
||||
var script = "getObj().List.filter(x => x === 'b').length === 1";
|
||||
_expressionContext.SetVariable("obj", (object)dynamicObject);
|
||||
var result = await _evaluator.EvaluateAsync(script, typeof(bool), _expressionContext);
|
||||
|
||||
Assert.True((bool)result!);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Can access list properties as arrays")]
|
||||
public async Task Test2()
|
||||
{
|
||||
var person = new ExpandoObject();
|
||||
var magicNumbers = new[]
|
||||
{
|
||||
42, 43, 44
|
||||
};
|
||||
var order1 = new ExpandoObject();
|
||||
|
||||
order1.TryAdd("magicNumbers", magicNumbers);
|
||||
person.TryAdd("orders", new[]
|
||||
{
|
||||
order1
|
||||
});
|
||||
person.TryAdd("name", "John");
|
||||
person.TryAdd("age", 12);
|
||||
|
||||
var languages = new List<object>
|
||||
{
|
||||
"English",
|
||||
"French"
|
||||
};
|
||||
|
||||
person.TryAdd("languages", languages);
|
||||
|
||||
var obj = new ExpandoObject();
|
||||
obj.TryAdd("persons", new List<object>
|
||||
{
|
||||
person
|
||||
});
|
||||
|
||||
var name = await _evaluator.EvaluateAsync("o.persons.filter(x => x.age == 12)[0].name", typeof(string), _expressionContext, configureEngine: engine => engine.SetValue("o", obj));
|
||||
var language = await _evaluator.EvaluateAsync("o.persons[0].languages.filter(x => x == 'English')[0]", typeof(string), _expressionContext, configureEngine: engine => engine.SetValue("o", obj));
|
||||
var magicNumber = await _evaluator.EvaluateAsync("o.persons[0].orders[0].magicNumbers[1]", typeof(int), _expressionContext, configureEngine: engine => engine.SetValue("o", obj));
|
||||
Assert.Equal("John", name);
|
||||
Assert.Equal("English", language);
|
||||
Assert.Equal(43, magicNumber);
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Can sort array and list properties as mutable arrays")]
|
||||
[MemberData(nameof(ArraySortEnumerableData))]
|
||||
// See also:
|
||||
// - https://github.com/sebastienros/jint/issues/1942
|
||||
// - https://github.com/elsa-workflows/elsa-core/issues/5912
|
||||
public async Task Test5(IEnumerable<double> collection)
|
||||
{
|
||||
dynamic dynamicObject = new ExpandoObject();
|
||||
dynamicObject.Items = collection;
|
||||
var script = """
|
||||
const model = variables.Model;
|
||||
model.Items.sort((a, b) => a - b);
|
||||
return model;
|
||||
""";
|
||||
_expressionContext.SetVariable("Model", (object)dynamicObject);
|
||||
dynamicObject = (ExpandoObject)(await _evaluator.EvaluateAsync(script, typeof(ExpandoObject), _expressionContext))!;
|
||||
var items = ((object[])dynamicObject.Items).Cast<double>().ToArray();
|
||||
|
||||
Assert.Equal([2, 4, 8], items);
|
||||
}
|
||||
|
||||
public static IEnumerable<object[]> ArraySortEnumerableData = new object[][]
|
||||
{
|
||||
[
|
||||
new double[]
|
||||
{
|
||||
8, 4, 2
|
||||
}
|
||||
],
|
||||
[
|
||||
new List<double>
|
||||
{
|
||||
8,
|
||||
4,
|
||||
2
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
using System.Dynamic;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JavaScriptNativeVariables;
|
||||
|
||||
public class Data
|
||||
{
|
||||
public static ExpandoObject CreateCustomerModel()
|
||||
{
|
||||
dynamic customer = new ExpandoObject();
|
||||
customer.Name = "John Doe";
|
||||
customer.Age = 42;
|
||||
customer.Orders = new[]
|
||||
{
|
||||
new
|
||||
{
|
||||
Id = 1,
|
||||
Product = "Apple",
|
||||
Price = 10
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 3,
|
||||
Product = "Orange",
|
||||
Price = 30
|
||||
},
|
||||
new
|
||||
{
|
||||
Id = 2,
|
||||
Product = "Banana",
|
||||
Price = 20
|
||||
}
|
||||
};
|
||||
return customer;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JavaScriptNativeVariables;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IWorkflowBuilderFactory _workflowBuilderFactory;
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.ConfigureElsa(elsa => elsa.UseJavaScript())
|
||||
.Build();
|
||||
_workflowBuilderFactory = _services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "The JavaScript activity can access and modify native variables")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflow = await _workflowBuilderFactory.CreateBuilder().BuildWorkflowAsync<JavaScriptWorkflow>();
|
||||
await _workflowRunner.RunAsync(workflow);
|
||||
var line1 = _capturingTextWriter.Lines.ToList().ElementAt(0);
|
||||
var line2 = _capturingTextWriter.Lines.ToList().ElementAt(1);
|
||||
var line3 = _capturingTextWriter.Lines.ToList().ElementAt(2);
|
||||
Assert.Equal("Jane Doe", line1);
|
||||
Assert.Equal("Apple, Banana, Orange", line2);
|
||||
Assert.Equal("jane.doe@acme.com", line3);
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
using Elsa.JavaScript.Activities;
|
||||
using Elsa.JavaScript.Models;
|
||||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JavaScriptNativeVariables;
|
||||
|
||||
public class JavaScriptWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow.WithDefinitionId(Guid.NewGuid().ToString());
|
||||
var customerVariable = workflow.WithVariable("customer", Data.CreateCustomerModel());
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new RunJavaScript
|
||||
{
|
||||
Script = new("""
|
||||
const customer = variables.customer;
|
||||
customer.Name = 'Jane Doe';
|
||||
customer.Orders.sort((a, b) => a.Product.localeCompare(b.Product));
|
||||
variables.customer = {...customer, Email: 'jane.doe@acme.com'};
|
||||
""")
|
||||
},
|
||||
new WriteLine(JavaScriptExpression.Create("variables.customer.Name")),
|
||||
new WriteLine(JavaScriptExpression.Create("variables.customer.Orders.map(x => x.Product).join(', ')")),
|
||||
new WriteLine(JavaScriptExpression.Create("variables.customer.Email"))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.State;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JsonObjectSerialization;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for serializing and deserializing JSON objects containing reserved keywords such as $id.
|
||||
/// </summary>
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IWorkflowStateSerializer _workflowStateSerializer;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_workflowStateSerializer = _services.GetRequiredService<IWorkflowStateSerializer>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "User-objects containing $id don't break deserialization into ExpandoObject.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import workflow.
|
||||
var workflowFileName = "Scenarios/JsonObjectSerialization/Workflows/instance-serialization.json";
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync(workflowFileName);
|
||||
|
||||
// Execute.
|
||||
var workflowState = await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Serialize workflow state.
|
||||
var serializedWorkflowState = _workflowStateSerializer.Serialize(workflowState);
|
||||
|
||||
// Attempt to deserialize workflow state.
|
||||
_workflowStateSerializer.Deserialize<WorkflowState>(serializedWorkflowState);
|
||||
|
||||
// If we reach this point, the test has passed. Otherwise, an exception would have been thrown.
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"id": "b78e443339b5bf1e",
|
||||
"definitionId": "861e51cdbe07931",
|
||||
"name": "Instance Serialization",
|
||||
"description": "This workflow stores a user-JSON object containing $id as a field, which should not affect the deserialization process form JSON back into ExpandoObject.",
|
||||
"createdAt": "2023-11-23T15:18:12.805077+00:00",
|
||||
"version": 13,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [
|
||||
{
|
||||
"id": "d4f37df0c6781767",
|
||||
"name": "Variable1",
|
||||
"typeName": "Object",
|
||||
"isArray": false,
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
},
|
||||
{
|
||||
"id": "4e256dab27d33eac",
|
||||
"name": "Variable2",
|
||||
"typeName": "Object",
|
||||
"isArray": false,
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
}
|
||||
],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "35cdc2a3529d9b55",
|
||||
"nodeId": "Workflow1:35cdc2a3529d9b55",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"variable": {
|
||||
"id": "d4f37df0c6781767",
|
||||
"name": "Variable1",
|
||||
"typeName": "Object",
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
},
|
||||
"value": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "return {\n \u0022inputSchema\u0022: {\n \u0022$schema\u0022: \u0022http://json-schema.org/draft-07/schema#\u0022,\n \u0022title\u0022: \u0022Inform front-office afd 2.0 input schema\u0022,\n \u0022description\u0022: \u0022Schema of the AFD 2.0 message that is sent to the front-office\u0022,\n \u0022$id\u0022: \u0022#/definitions/inform-front-office-input-afd\u0022,\n \u0022type\u0022: \u0022object\u0022\n }\n}"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "d4f32ee0ad659ba5:input-0"
|
||||
}
|
||||
},
|
||||
"id": "d4f32ee0ad659ba5",
|
||||
"nodeId": "Workflow1:35cdc2a3529d9b55:d4f32ee0ad659ba5",
|
||||
"name": "SetVariable1",
|
||||
"type": "Elsa.SetVariable",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -456.5988464355469,
|
||||
"y": -104.93463134765625
|
||||
},
|
||||
"size": {
|
||||
"width": 153.828125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"variable": {
|
||||
"id": "4e256dab27d33eac",
|
||||
"name": "Variable2",
|
||||
"typeName": "Object",
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
},
|
||||
"value": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "return getVariable1()"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "31c60a181a1a66d8:input-0"
|
||||
}
|
||||
},
|
||||
"id": "31c60a181a1a66d8",
|
||||
"nodeId": "Workflow1:35cdc2a3529d9b55:31c60a181a1a66d8",
|
||||
"name": "SetVariable2",
|
||||
"type": "Elsa.SetVariable",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -210.69132232666016,
|
||||
"y": -104.93463134765625
|
||||
},
|
||||
"size": {
|
||||
"width": 153.828125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "d4f32ee0ad659ba5",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "31c60a181a1a66d8",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using Elsa.Extensions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JsonObjectToObjectRemainsJsonObject.Activities;
|
||||
|
||||
public class JsonObjectProducer : CodeActivity<JsonObject>
|
||||
{
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
var value = new JsonObject
|
||||
{
|
||||
["Foo"] = new JsonObject
|
||||
{
|
||||
["Bar"] = "Baz"
|
||||
}
|
||||
};
|
||||
|
||||
context.SetResult(value);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JsonObjectToObjectRemainsJsonObject.Activities;
|
||||
|
||||
public class ObjectProcessor : CodeActivity<object>
|
||||
{
|
||||
public Input<object> Value { get; set; } = default!;
|
||||
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
var value = Value.Get(context);
|
||||
context.SetResult(value);
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JsonObjectToObjectRemainsJsonObject;
|
||||
|
||||
public class JsonObjectJintTests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public JsonObjectJintTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "The produced JsonObject remains JsonObject and does not become JsonElement (which does not support index notation)")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<Workflows.TestWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Baz" }, lines);
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
using System.Text.Json.Nodes;
|
||||
using Elsa.Expressions.Models;
|
||||
using Elsa.JavaScript.Models;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.JsonObjectToObjectRemainsJsonObject.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.JsonObjectToObjectRemainsJsonObject.Workflows;
|
||||
|
||||
public class TestWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
var item = builder.WithVariable<JsonObject>("item", default!);
|
||||
|
||||
builder.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new JsonObjectProducer
|
||||
{
|
||||
Result = new(item)
|
||||
},
|
||||
new ObjectProcessor
|
||||
{
|
||||
Value = new(JavaScriptExpression.Create("getItem()"), new MemoryBlockReference()),
|
||||
Result = new(item)
|
||||
},
|
||||
new WriteLine(JavaScriptExpression.Create("getItem()['Foo']['Bar']"))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ParentChildCompletion;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for mapping an activity's output directly to the workflow's output definition.
|
||||
/// </summary>
|
||||
public class Tests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Parent workflow invoking child workflow as activity completes successfully.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import child workflow.
|
||||
var childWorkflowFilename = "Scenarios/ParentChildCompletion/Workflows/child.json";
|
||||
await _services.ImportWorkflowDefinitionAsync(childWorkflowFilename);
|
||||
|
||||
// Import parent workflow.
|
||||
var parentWorkflowFilename = "Scenarios/ParentChildCompletion/Workflows/parent.json";
|
||||
var parentWorkflowDefinition = await _services.ImportWorkflowDefinitionAsync(parentWorkflowFilename);
|
||||
|
||||
// Execute.
|
||||
var workflowState = await _services.RunWorkflowUntilEndAsync(parentWorkflowDefinition.DefinitionId);
|
||||
|
||||
// Assert expected status
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowState.Status);
|
||||
}
|
||||
}
|
||||
+303
@@ -0,0 +1,303 @@
|
||||
{
|
||||
"id": "c8109a84c584c83c",
|
||||
"definitionId": "3dcdbf22d29d6e60",
|
||||
"name": "Subworkflow test",
|
||||
"createdAt": "2023-11-10T13:03:21.734094+00:00",
|
||||
"version": 4,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [
|
||||
{
|
||||
"id": "c0dbe71ceb21ee4f",
|
||||
"name": "Variable1",
|
||||
"typeName": "Object",
|
||||
"isArray": false,
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
}
|
||||
],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [
|
||||
"Success",
|
||||
"Failure"
|
||||
],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "2492a1125f14bc2d",
|
||||
"nodeId": "Workflow1:2492a1125f14bc2d",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "test"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "a3625dd2e8405265:input-0"
|
||||
}
|
||||
},
|
||||
"id": "a3625dd2e8405265",
|
||||
"nodeId": "Workflow1:2492a1125f14bc2d:a3625dd2e8405265",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": true,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -174,
|
||||
"y": 302
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "31d29bf86b2b62cb:input-0"
|
||||
}
|
||||
},
|
||||
"id": "31d29bf86b2b62cb",
|
||||
"nodeId": "Workflow1:2492a1125f14bc2d:31d29bf86b2b62cb",
|
||||
"name": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 132.6484375,
|
||||
"y": 292
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "11"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "57576570e00a4c70:input-0"
|
||||
}
|
||||
},
|
||||
"id": "57576570e00a4c70",
|
||||
"nodeId": "Workflow1:2492a1125f14bc2d:57576570e00a4c70",
|
||||
"name": "WriteLine5",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 449.6484375,
|
||||
"y": 280
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "22"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "caa57f31b8d0e0d1:input-0"
|
||||
}
|
||||
},
|
||||
"id": "caa57f31b8d0e0d1",
|
||||
"nodeId": "Workflow1:2492a1125f14bc2d:caa57f31b8d0e0d1",
|
||||
"name": "WriteLine4",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 449.6484375,
|
||||
"y": 563
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"script": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "return {\u0022prop1\u0022:\u0022ceva\u0022}"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "fb20dbd8777282b2:input-0"
|
||||
}
|
||||
},
|
||||
"possibleOutcomes": null,
|
||||
"result": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "c0dbe71ceb21ee4f"
|
||||
}
|
||||
},
|
||||
"id": "fb20dbd8777282b2",
|
||||
"nodeId": "Workflow1:2492a1125f14bc2d:fb20dbd8777282b2",
|
||||
"name": "RunJavaScript1",
|
||||
"type": "Elsa.RunJavaScript",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 114.453125,
|
||||
"y": 563
|
||||
},
|
||||
"size": {
|
||||
"width": 175.6875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"outcomes": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Success"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "8654ab45535f4069:input-0"
|
||||
}
|
||||
},
|
||||
"id": "8654ab45535f4069",
|
||||
"nodeId": "Workflow1:2492a1125f14bc2d:8654ab45535f4069",
|
||||
"name": "Complete1",
|
||||
"type": "Elsa.Complete",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 738.7582397460938,
|
||||
"y": 690.54443359375
|
||||
},
|
||||
"size": {
|
||||
"width": 136.8125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "a3625dd2e8405265",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "31d29bf86b2b62cb",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "31d29bf86b2b62cb",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "57576570e00a4c70",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "fb20dbd8777282b2",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "caa57f31b8d0e0d1",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "a3625dd2e8405265",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "fb20dbd8777282b2",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "caa57f31b8d0e0d1",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "8654ab45535f4069",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+194
@@ -0,0 +1,194 @@
|
||||
{
|
||||
"id": "34991d27edc12ae5",
|
||||
"definitionId": "89d6fe82a11fbed6",
|
||||
"name": "Mainworkflow test",
|
||||
"createdAt": "2023-11-10T21:01:49.123204+00:00",
|
||||
"version": 2,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "f9071ee83c88d765",
|
||||
"nodeId": "Workflow1:f9071ee83c88d765",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Success"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "77069142b8b9da15:input-0"
|
||||
}
|
||||
},
|
||||
"id": "77069142b8b9da15",
|
||||
"nodeId": "Workflow1:f9071ee83c88d765:77069142b8b9da15",
|
||||
"name": "WriteLine2",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 231.8203125,
|
||||
"y": 200
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Failure"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "34e3dcda423f3c1c:input-0"
|
||||
}
|
||||
},
|
||||
"id": "34e3dcda423f3c1c",
|
||||
"nodeId": "Workflow1:f9071ee83c88d765:34e3dcda423f3c1c",
|
||||
"name": "WriteLine3",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 231.8203125,
|
||||
"y": 393
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Start"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "8b7bf9cd03c066fa:input-0"
|
||||
}
|
||||
},
|
||||
"id": "8b7bf9cd03c066fa",
|
||||
"nodeId": "Workflow1:f9071ee83c88d765:8b7bf9cd03c066fa",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -340,
|
||||
"y": 309
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "b8b45fd4dbffad5d",
|
||||
"workflowDefinitionVersionId": "24dd11bc73a881d5",
|
||||
"latestAvailablePublishedVersion": 7,
|
||||
"latestAvailablePublishedVersionId": "24dd11bc73a881d5",
|
||||
"id": "abcd6d3d391bfe10",
|
||||
"nodeId": "Workflow1:f9071ee83c88d765:abcd6d3d391bfe10",
|
||||
"name": "SubworkflowTest1",
|
||||
"type": "SubworkflowTest",
|
||||
"version": 7,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -54,
|
||||
"y": 309
|
||||
},
|
||||
"size": {
|
||||
"width": 157.09375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "8b7bf9cd03c066fa",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "abcd6d3d391bfe10",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "abcd6d3d391bfe10",
|
||||
"port": "Success"
|
||||
},
|
||||
"target": {
|
||||
"activity": "77069142b8b9da15",
|
||||
"port": "In"
|
||||
}
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"activity": "abcd6d3d391bfe10",
|
||||
"port": "Failure"
|
||||
},
|
||||
"target": {
|
||||
"activity": "34e3dcda423f3c1c",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ParentChildInputs;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for the flowchart completion feature using various workflow setups.
|
||||
/// </summary>
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Child activity receives workflow input from parent even if same name.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import child workflow.
|
||||
var childFileName = $"Scenarios/ParentChildInputs/Workflows/child.json";
|
||||
await _services.ImportWorkflowDefinitionAsync(childFileName);
|
||||
|
||||
// Import parent workflow.
|
||||
var parentFileName = $"Scenarios/ParentChildInputs/Workflows/parent1.json";
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync(parentFileName);
|
||||
|
||||
// Execute.
|
||||
var input = new Dictionary<string, object> { ["Input1"] = "Foo" };
|
||||
await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId, input);
|
||||
|
||||
// Assert expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Parent: Foo", "Child: Bar" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Child activity receives input from parent event if same name and does not use global workflow input.")]
|
||||
public async Task Test2()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import child workflow.
|
||||
var childFileName = $"Scenarios/ParentChildInputs/Workflows/child.json";
|
||||
await _services.ImportWorkflowDefinitionAsync(childFileName);
|
||||
|
||||
// Import parent workflow.
|
||||
var parentFileName = $"Scenarios/ParentChildInputs/Workflows/parent2.json";
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync(parentFileName);
|
||||
|
||||
// Execute.
|
||||
var input = new Dictionary<string, object> { ["Input1"] = "Foo" };
|
||||
await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId, input);
|
||||
|
||||
// Assert expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Parent: Foo", "Child: Foo" }, lines);
|
||||
}
|
||||
}
|
||||
+139
@@ -0,0 +1,139 @@
|
||||
{
|
||||
"id": "228c0150ab7b4745b038b950be574935",
|
||||
"definitionId": "25b097966de245818e9a5c0d04f3323e",
|
||||
"name": "Child",
|
||||
"createdAt": "2023-09-06T09:57:32.944622+00:00",
|
||||
"version": 5,
|
||||
"variables": [],
|
||||
"inputs": [
|
||||
{
|
||||
"uiHint": "singleline",
|
||||
"storageDriverType": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core",
|
||||
"type": "Object",
|
||||
"name": "Input1",
|
||||
"displayName": "Input1",
|
||||
"description": "",
|
||||
"category": "",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output1",
|
||||
"displayName": "Output1",
|
||||
"description": "",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"outputName": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Output1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "ca8473b5-83ec-4f75-a2f1-dfba71f349d1"
|
||||
}
|
||||
},
|
||||
"outputValue": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "return getInput1();"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "06c6243d-8a57-45e3-ae54-f209b95d2bb2"
|
||||
}
|
||||
},
|
||||
"id": "SetOutput1",
|
||||
"name": null,
|
||||
"type": "Elsa.SetOutput",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 636,
|
||||
"y": 250.01388549804688
|
||||
},
|
||||
"size": {
|
||||
"width": 107.734375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "\u0022Child: \u0022 \u002B getInput1();"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "3f726554-0fa1-4e54-b5e7-74b18807437b"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"name": null,
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 332.01385498046875,
|
||||
"y": 222.01388549804688
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "WriteLine1",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "SetOutput1",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"id": "e49f81715e29460187671ee298bbd0b2",
|
||||
"definitionId": "6a4f5aeecbf94fc09dbba65363c5cb57",
|
||||
"name": "Parent1",
|
||||
"createdAt": "2023-09-06T11:38:10.701838+00:00",
|
||||
"version": 8,
|
||||
"variables": [],
|
||||
"inputs": [
|
||||
{
|
||||
"uiHint": "singleline",
|
||||
"storageDriverType": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core",
|
||||
"type": "Object",
|
||||
"name": "Input1",
|
||||
"displayName": "Input1",
|
||||
"description": "",
|
||||
"category": "",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output1",
|
||||
"displayName": "Output1",
|
||||
"description": "",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": false,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "\u0022Parent: \u0022 \u002B getInput1();"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "3070bee4-8309-44e3-a805-a9ec7fdd7ac2"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"name": null,
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 160,
|
||||
"y": 280
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "25b097966de245818e9a5c0d04f3323e",
|
||||
"workflowDefinitionVersionId": "228c0150ab7b4745b038b950be574935",
|
||||
"latestAvailablePublishedVersion": 5,
|
||||
"latestAvailablePublishedVersionId": "228c0150ab7b4745b038b950be574935",
|
||||
"id": "22jW7xiYM0K30H99EDWztQ",
|
||||
"name": "Child1",
|
||||
"type": "Child",
|
||||
"version": 5,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 405.3984375,
|
||||
"y": 204.0078125
|
||||
},
|
||||
"size": {
|
||||
"width": 94.765625,
|
||||
"height": 116.015625
|
||||
}
|
||||
}
|
||||
},
|
||||
"input1": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "\u0060Bar\u0060"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "22jW7xiYM0K30H99EDWztQ:input-0"
|
||||
}
|
||||
},
|
||||
"output1": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "Output1"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "WriteLine1",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "22jW7xiYM0K30H99EDWztQ",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
{
|
||||
"id": "c5aa339e124f4486b14dbfdc133a45d1",
|
||||
"definitionId": "8ad20b5ff9ee4ff59b8dfcfb6d4e29a0",
|
||||
"name": "Parent2",
|
||||
"createdAt": "2023-09-06T11:38:30.217265+00:00",
|
||||
"version": 1,
|
||||
"variables": [],
|
||||
"inputs": [
|
||||
{
|
||||
"uiHint": "singleline",
|
||||
"storageDriverType": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core",
|
||||
"type": "Object",
|
||||
"name": "Input1",
|
||||
"displayName": "Input1",
|
||||
"description": "",
|
||||
"category": "",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output1",
|
||||
"displayName": "Output1",
|
||||
"description": "",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "Flowchart1",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:45",
|
||||
"NotFoundConnectionsKey": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"start": "WriteLine1",
|
||||
"activities": [
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "\u0022Parent: \u0022 \u002B getInput1();"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "3070bee4-8309-44e3-a805-a9ec7fdd7ac2"
|
||||
}
|
||||
},
|
||||
"id": "WriteLine1",
|
||||
"name": null,
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 160,
|
||||
"y": 280
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "25b097966de245818e9a5c0d04f3323e",
|
||||
"workflowDefinitionVersionId": "228c0150ab7b4745b038b950be574935",
|
||||
"latestAvailablePublishedVersion": 5,
|
||||
"latestAvailablePublishedVersionId": "228c0150ab7b4745b038b950be574935",
|
||||
"id": "22jW7xiYM0K30H99EDWztQ",
|
||||
"name": "Child1",
|
||||
"type": "Child",
|
||||
"version": 5,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 405.3984375,
|
||||
"y": 204.0078125
|
||||
},
|
||||
"size": {
|
||||
"width": 135.390625,
|
||||
"height": 120
|
||||
}
|
||||
}
|
||||
},
|
||||
"input1": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "getInput1()"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "22jW7xiYM0K30H99EDWztQ:input-0"
|
||||
}
|
||||
},
|
||||
"output1": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "Output1"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "WriteLine1",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "22jW7xiYM0K30H99EDWztQ",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.ParentChildOutputMapping;
|
||||
|
||||
/// <summary>
|
||||
/// Tests for mapping an activity's output directly to the workflow's output definition.
|
||||
/// </summary>
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Parent workflow receives output from child workflow.")]
|
||||
public async Task Test1()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import child workflow.
|
||||
var sumFileName = "Scenarios/ParentChildOutputMapping/Workflows/sum.json";
|
||||
await _services.ImportWorkflowDefinitionAsync(sumFileName);
|
||||
|
||||
// Import parent workflow.
|
||||
var calculatorFileName = "Scenarios/ParentChildOutputMapping/Workflows/calculator.json";
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync(calculatorFileName);
|
||||
|
||||
// Execute.
|
||||
await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Result: 9" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Multiple parent/child workflows receive output from child workflows even when using same output names.")]
|
||||
public async Task Test2()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import workflows.
|
||||
await _services.ImportWorkflowDefinitionAsync("Scenarios/ParentChildOutputMapping/Workflows/a.json");
|
||||
await _services.ImportWorkflowDefinitionAsync("Scenarios/ParentChildOutputMapping/Workflows/b.json");
|
||||
await _services.ImportWorkflowDefinitionAsync("Scenarios/ParentChildOutputMapping/Workflows/c.json");
|
||||
|
||||
// Import root workflow.
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync("Scenarios/ParentChildOutputMapping/Workflows/d.json");
|
||||
|
||||
// Execute.
|
||||
await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "FooBar" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Parent workflow receives output from child workflow when using SetOutput activity.")]
|
||||
public async Task Test3()
|
||||
{
|
||||
// Populate registries.
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
// Import child workflow.
|
||||
var producerFileName = "Scenarios/ParentChildOutputMapping/Workflows/producer.json";
|
||||
await _services.ImportWorkflowDefinitionAsync(producerFileName);
|
||||
|
||||
// Import parent workflow.
|
||||
var consumerFileName = "Scenarios/ParentChildOutputMapping/Workflows/consumer.json";
|
||||
var workflowDefinition = await _services.ImportWorkflowDefinitionAsync(consumerFileName);
|
||||
|
||||
// Execute.
|
||||
await _services.RunWorkflowUntilEndAsync(workflowDefinition.DefinitionId);
|
||||
|
||||
// Assert expected output.
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Foo" }, lines);
|
||||
}
|
||||
}
|
||||
+89
@@ -0,0 +1,89 @@
|
||||
{
|
||||
"id": "5d8015cea7b44c96",
|
||||
"definitionId": "7fe314161d2d2ac6",
|
||||
"name": "A",
|
||||
"createdAt": "2023-11-15T13:55:38.86581+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output1",
|
||||
"displayName": "Output 1",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "d84ccfca1b90bc0c",
|
||||
"nodeId": "Workflow1:d84ccfca1b90bc0c",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"outputName": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Output1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "a6389a28e986c6ff:input-0"
|
||||
}
|
||||
},
|
||||
"outputValue": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Foo"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "a6389a28e986c6ff:input-1"
|
||||
}
|
||||
},
|
||||
"id": "a6389a28e986c6ff",
|
||||
"nodeId": "Workflow1:d84ccfca1b90bc0c:a6389a28e986c6ff",
|
||||
"name": "SetOutput1",
|
||||
"type": "Elsa.SetOutput",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -60,
|
||||
"y": 240
|
||||
},
|
||||
"size": {
|
||||
"width": 107.734375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
{
|
||||
"id": "d5221501eeb78037",
|
||||
"definitionId": "8c751e0c53821439",
|
||||
"name": "B",
|
||||
"createdAt": "2023-11-15T13:59:18.773434+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output1",
|
||||
"displayName": "Output 1",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "49a24a01a4c318de",
|
||||
"nodeId": "Workflow1:49a24a01a4c318de",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"script": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "return \u0022Bar\u0022;"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "247da1e267d76f80:input-0"
|
||||
}
|
||||
},
|
||||
"possibleOutcomes": null,
|
||||
"result": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "Output1"
|
||||
}
|
||||
},
|
||||
"id": "247da1e267d76f80",
|
||||
"nodeId": "Workflow1:49a24a01a4c318de:247da1e267d76f80",
|
||||
"name": "RunCSharp1",
|
||||
"type": "Elsa.RunCSharp",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -200,
|
||||
"y": -140
|
||||
},
|
||||
"size": {
|
||||
"width": 83.640625,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+130
@@ -0,0 +1,130 @@
|
||||
{
|
||||
"id": "c4041d72854d317c",
|
||||
"definitionId": "8472bcf9ca261e55",
|
||||
"name": "C",
|
||||
"createdAt": "2023-11-15T14:05:30.708042+00:00",
|
||||
"version": 6,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output1",
|
||||
"displayName": "Output 1",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output2",
|
||||
"displayName": "Output 2",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "6ee60c9988b58904",
|
||||
"nodeId": "Workflow1:6ee60c9988b58904",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "7fe314161d2d2ac6",
|
||||
"workflowDefinitionVersionId": "5d8015cea7b44c96",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "5d8015cea7b44c96",
|
||||
"id": "67daca2a2fc729b6",
|
||||
"nodeId": "Workflow1:6ee60c9988b58904:67daca2a2fc729b6",
|
||||
"name": "A1",
|
||||
"type": "A",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -311.5,
|
||||
"y": -145
|
||||
},
|
||||
"size": {
|
||||
"width": 41.59375,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
},
|
||||
"output1": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "Output1"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"workflowDefinitionId": "8c751e0c53821439",
|
||||
"workflowDefinitionVersionId": "d5221501eeb78037",
|
||||
"latestAvailablePublishedVersion": 1,
|
||||
"latestAvailablePublishedVersionId": "d5221501eeb78037",
|
||||
"id": "d152d5815dcdea0d",
|
||||
"nodeId": "Workflow1:6ee60c9988b58904:d152d5815dcdea0d",
|
||||
"name": "B1",
|
||||
"type": "B",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -194.5,
|
||||
"y": -145
|
||||
},
|
||||
"size": {
|
||||
"width": 41.125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
},
|
||||
"output1": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "Output2"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "67daca2a2fc729b6",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "d152d5815dcdea0d",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+137
@@ -0,0 +1,137 @@
|
||||
{
|
||||
"id": "Wv2qJngeBUy6nauIj3WZxg",
|
||||
"definitionId": "g-yf4Gck40S_T1E5pW8OVA",
|
||||
"name": "Calculator",
|
||||
"createdAt": "2023-10-18T17:22:19.425264+00:00",
|
||||
"version": 5,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [
|
||||
{
|
||||
"id": "1a3c8e08fbf04b42b01f5df8e6296b74",
|
||||
"name": "TheSum",
|
||||
"typeName": "Int32",
|
||||
"isArray": false,
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
}
|
||||
],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "GGOfdS1e60-vuDvSskzt6A",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "P4X-srRSDUeKpFHiDXMW-w",
|
||||
"workflowDefinitionVersionId": "E02197RyVk6VyofGoO6YJQ",
|
||||
"latestAvailablePublishedVersion": 3,
|
||||
"latestAvailablePublishedVersionId": "E02197RyVk6VyofGoO6YJQ",
|
||||
"id": "WDS8owJicUuwae0D5GPbZw",
|
||||
"name": "Sum1",
|
||||
"type": "Sum",
|
||||
"version": 3,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -150.5,
|
||||
"y": -173
|
||||
},
|
||||
"size": {
|
||||
"width": 94.765625,
|
||||
"height": 116.015625
|
||||
}
|
||||
}
|
||||
},
|
||||
"a": {
|
||||
"typeName": "Int32",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "4"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WDS8owJicUuwae0D5GPbZw:input-0"
|
||||
}
|
||||
},
|
||||
"b": {
|
||||
"typeName": "Int32",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "5"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "WDS8owJicUuwae0D5GPbZw:input-1"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"typeName": "Int32",
|
||||
"memoryReference": {
|
||||
"id": "1a3c8e08fbf04b42b01f5df8e6296b74"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "JavaScript",
|
||||
"value": "\u0060Result: ${getTheSum()}\u0060"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "NDqbEDwcIUu7zJ0FDxbHdg:input-0"
|
||||
}
|
||||
},
|
||||
"id": "NDqbEDwcIUu7zJ0FDxbHdg",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 80,
|
||||
"y": -139.9921875
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "WDS8owJicUuwae0D5GPbZw",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "NDqbEDwcIUu7zJ0FDxbHdg",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"id": "cae99c483081a2c",
|
||||
"definitionId": "a7e44620e65e7184",
|
||||
"name": "Consumer",
|
||||
"createdAt": "2023-11-17T19:47:21.937582+00:00",
|
||||
"version": 3,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [
|
||||
{
|
||||
"id": "137ac38a229059f0",
|
||||
"name": "Variable1",
|
||||
"typeName": "Object",
|
||||
"isArray": false,
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
}
|
||||
],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": false,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "cv7o3nnxp1dkxp1n",
|
||||
"nodeId": "Workflow1:cv7o3nnxp1dkxp1n",
|
||||
"metadata": {
|
||||
"displayText": "Flowchart1"
|
||||
},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "69d6496437ff9d33",
|
||||
"workflowDefinitionVersionId": "5c020d0052fb2860",
|
||||
"latestAvailablePublishedVersion": 2,
|
||||
"latestAvailablePublishedVersionId": "5c020d0052fb2860",
|
||||
"id": "xcyl3fg7gg2uxcd4",
|
||||
"nodeId": "Workflow1:cv7o3nnxp1dkxp1n:xcyl3fg7gg2uxcd4",
|
||||
"name": "InternalPremiumCalculationGeneric1",
|
||||
"type": "Producer",
|
||||
"version": 2,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2280,
|
||||
"y": 2420
|
||||
},
|
||||
"size": {
|
||||
"width": 318.140625,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
},
|
||||
"output1": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "137ac38a229059f0"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "CSharp",
|
||||
"value": "return Variables.Variable1.ToString();"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "b3b9071594676f52:input-0"
|
||||
}
|
||||
},
|
||||
"id": "b3b9071594676f52",
|
||||
"nodeId": "Workflow1:cv7o3nnxp1dkxp1n:b3b9071594676f52",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 2695.5703125,
|
||||
"y": 2420
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "xcyl3fg7gg2uxcd4",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "b3b9071594676f52",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
{
|
||||
"id": "cbf12a4a3d1a52ef",
|
||||
"definitionId": "133353946cd83e1d",
|
||||
"name": "D",
|
||||
"createdAt": "2023-11-15T14:07:04.052579+00:00",
|
||||
"version": 1,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [
|
||||
{
|
||||
"id": "f1106ece80fd17a8",
|
||||
"name": "Variable1",
|
||||
"typeName": "Object",
|
||||
"isArray": false,
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
},
|
||||
{
|
||||
"id": "3a8b25edc9bf109",
|
||||
"name": "Variable2",
|
||||
"typeName": "Object",
|
||||
"isArray": false,
|
||||
"storageDriverTypeName": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core"
|
||||
}
|
||||
],
|
||||
"inputs": [],
|
||||
"outputs": [],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"autoUpdateConsumingWorkflows": false
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "26838161a6f32e2e",
|
||||
"nodeId": "Workflow1:26838161a6f32e2e",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"workflowDefinitionId": "8472bcf9ca261e55",
|
||||
"workflowDefinitionVersionId": "c4041d72854d317c",
|
||||
"latestAvailablePublishedVersion": 6,
|
||||
"latestAvailablePublishedVersionId": "c4041d72854d317c",
|
||||
"id": "db7bda6a28d8de82",
|
||||
"nodeId": "Workflow1:26838161a6f32e2e:db7bda6a28d8de82",
|
||||
"name": "C1",
|
||||
"type": "C",
|
||||
"version": 6,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -298.5,
|
||||
"y": -168
|
||||
},
|
||||
"size": {
|
||||
"width": 41.578125,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
},
|
||||
"output1": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "f1106ece80fd17a8"
|
||||
}
|
||||
},
|
||||
"output2": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "3a8b25edc9bf109"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "CSharp",
|
||||
"value": "return $\u0022{Variables.Variable1}{Variables.Variable2}\u0022;"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "a815c4cf1e668419:input-0"
|
||||
}
|
||||
},
|
||||
"id": "a815c4cf1e668419",
|
||||
"nodeId": "Workflow1:26838161a6f32e2e:a815c4cf1e668419",
|
||||
"name": "WriteLine1",
|
||||
"type": "Elsa.WriteLine",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -139.5,
|
||||
"y": -168
|
||||
},
|
||||
"size": {
|
||||
"width": 139.296875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": [
|
||||
{
|
||||
"source": {
|
||||
"activity": "db7bda6a28d8de82",
|
||||
"port": "Done"
|
||||
},
|
||||
"target": {
|
||||
"activity": "a815c4cf1e668419",
|
||||
"port": "In"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
{
|
||||
"id": "5c020d0052fb2860",
|
||||
"definitionId": "69d6496437ff9d33",
|
||||
"name": "Producer",
|
||||
"createdAt": "2023-11-17T19:45:52.798011+00:00",
|
||||
"version": 2,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Object",
|
||||
"name": "Output1",
|
||||
"displayName": "Output 1",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {
|
||||
"Elsa:WorkflowContextProviderTypes": []
|
||||
},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "nn98bbdkmvkbkuda",
|
||||
"nodeId": "Workflow1:nn98bbdkmvkbkuda",
|
||||
"metadata": {
|
||||
"displayText": "Flowchart1"
|
||||
},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:47",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"outputName": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Output1"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "825749ed-b1ad-48f0-aa51-f739c71420a4"
|
||||
}
|
||||
},
|
||||
"outputValue": {
|
||||
"typeName": "Object",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "Foo"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "427d771a-a3e2-4a1c-bb40-c1f4ccf3d0c7"
|
||||
}
|
||||
},
|
||||
"id": "4c9j38qta2bmc096",
|
||||
"nodeId": "Workflow1:nn98bbdkmvkbkuda:4c9j38qta2bmc096",
|
||||
"name": "SetOutput1",
|
||||
"type": "Elsa.SetOutput",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": 400,
|
||||
"y": 40
|
||||
},
|
||||
"size": {
|
||||
"width": 175.578125,
|
||||
"height": 50
|
||||
}
|
||||
},
|
||||
"displayText": ""
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
{
|
||||
"id": "E02197RyVk6VyofGoO6YJQ",
|
||||
"definitionId": "P4X-srRSDUeKpFHiDXMW-w",
|
||||
"name": "Sum",
|
||||
"createdAt": "2023-10-18T16:37:20.670222+00:00",
|
||||
"version": 3,
|
||||
"toolVersion": "3.0.0.0",
|
||||
"variables": [],
|
||||
"inputs": [
|
||||
{
|
||||
"uiHint": "singleline",
|
||||
"storageDriverType": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core",
|
||||
"type": "Int32",
|
||||
"name": "A",
|
||||
"displayName": "A",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
},
|
||||
{
|
||||
"uiHint": "singleline",
|
||||
"storageDriverType": "Elsa.Workflows.Services.WorkflowStorageDriver, Elsa.Workflows.Core",
|
||||
"type": "Int32",
|
||||
"name": "B",
|
||||
"displayName": "B",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
{
|
||||
"type": "Int32",
|
||||
"name": "Result",
|
||||
"displayName": "Result",
|
||||
"category": "Primitives",
|
||||
"isArray": false
|
||||
}
|
||||
],
|
||||
"outcomes": [],
|
||||
"customProperties": {},
|
||||
"isReadonly": false,
|
||||
"isLatest": true,
|
||||
"isPublished": true,
|
||||
"options": {
|
||||
"usableAsActivity": true,
|
||||
"autoUpdateConsumingWorkflows": true,
|
||||
"activityCategory": "Custom"
|
||||
},
|
||||
"root": {
|
||||
"type": "Elsa.Flowchart",
|
||||
"version": 1,
|
||||
"id": "4FUOkS0zNUGe8JyVY3Sqmw",
|
||||
"metadata": {},
|
||||
"customProperties": {
|
||||
"source": "FlowchartJsonConverter.cs:46",
|
||||
"notFoundConnections": [],
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"activities": [
|
||||
{
|
||||
"possibleOutcomes": null,
|
||||
"script": {
|
||||
"typeName": "String",
|
||||
"expression": {
|
||||
"type": "Literal",
|
||||
"value": "getA() \u002B getB()"
|
||||
},
|
||||
"memoryReference": {
|
||||
"id": "weO38K8Dfk-cSK8KVIiQMg:input-1"
|
||||
}
|
||||
},
|
||||
"result": {
|
||||
"typeName": "Object",
|
||||
"memoryReference": {
|
||||
"id": "Result"
|
||||
}
|
||||
},
|
||||
"id": "weO38K8Dfk-cSK8KVIiQMg",
|
||||
"name": "RunJavaScript1",
|
||||
"type": "Elsa.RunJavaScript",
|
||||
"version": 1,
|
||||
"customProperties": {
|
||||
"canStartWorkflow": false,
|
||||
"runAsynchronously": false
|
||||
},
|
||||
"metadata": {
|
||||
"designer": {
|
||||
"position": {
|
||||
"x": -240,
|
||||
"y": 300
|
||||
},
|
||||
"size": {
|
||||
"width": 175.6875,
|
||||
"height": 50
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"connections": []
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
using Elsa.Workflows.Attributes;
|
||||
using Elsa.Workflows.Models;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.RunAsynchronousActivityOutput.Activities;
|
||||
|
||||
[Activity("Elsa.Test", Kind = ActivityKind.Task)]
|
||||
internal class SampleActivity : CodeActivity
|
||||
{
|
||||
public SampleActivity()
|
||||
{
|
||||
RunAsynchronously = true;
|
||||
}
|
||||
|
||||
public Input<int>? Number1 { get; set; } = null;
|
||||
public Input<int>? Number2 { get; set; } = null;
|
||||
public Output<int>? Sum { get; set; } = null;
|
||||
public Output<int>? Product { get; set; } = null;
|
||||
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
var number1 = context.Get(Number1);
|
||||
var number2 = context.Get(Number2);
|
||||
|
||||
context.Set(Sum, number1 + number2);
|
||||
context.Set(Product, number1 * number2);
|
||||
}
|
||||
}
|
||||
+155
@@ -0,0 +1,155 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.RunAsynchronousActivityOutput.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
using Elsa.Workflows.Runtime.Distributed;
|
||||
using Elsa.Workflows.Runtime.Stores;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.RunAsynchronousActivityOutput;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
[Theory(DisplayName = "Activity outputs captured in activity execution record")]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task ActivityOutputCaptureTest(bool runAsynchronously)
|
||||
{
|
||||
// Arrange
|
||||
var workflow = new TestWorkflow(workflowBuilder =>
|
||||
{
|
||||
var variable1 = new Variable<int>();
|
||||
workflowBuilder.Root = new Sequence
|
||||
{
|
||||
Variables =
|
||||
{
|
||||
variable1
|
||||
},
|
||||
Activities =
|
||||
{
|
||||
new SampleActivity
|
||||
{
|
||||
Id = "SampleActivity1",
|
||||
RunAsynchronously = runAsynchronously,
|
||||
Number1 = new(4),
|
||||
Number2 = new(8),
|
||||
Sum = new(variable1),
|
||||
Product = null
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var activityExecutionStore = new MemoryActivityExecutionStore(new());
|
||||
|
||||
// Act
|
||||
var workflowFinishedRecord = await workflow.DispatchWorkflowAndRunToCompletion(
|
||||
configureElsa: elsa =>
|
||||
{
|
||||
elsa.UseWorkflowRuntime(workflowRuntime =>
|
||||
{
|
||||
workflowRuntime.ActivityExecutionLogStore = sp => activityExecutionStore;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(workflowFinishedRecord);
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowFinishedRecord.WorkflowState.Status);
|
||||
Assert.Equal(WorkflowSubStatus.Finished, workflowFinishedRecord.WorkflowState.SubStatus);
|
||||
|
||||
var activityExecutionRecord = await activityExecutionStore.FindAsync(new()
|
||||
{
|
||||
ActivityId = "SampleActivity1"
|
||||
});
|
||||
Assert.NotNull(activityExecutionRecord?.Outputs);
|
||||
Assert.Equal(2, activityExecutionRecord.Outputs!.Count);
|
||||
Assert.Equal(12, activityExecutionRecord.Outputs!.GetValue<int>("Sum"));
|
||||
Assert.Equal(32, activityExecutionRecord.Outputs!.GetValue<int>("Product"));
|
||||
|
||||
var activityOutputRegister = workflowFinishedRecord.WorkflowExecutionContext.GetActivityOutputRegister();
|
||||
Assert.Equal(12, activityOutputRegister.FindOutputByActivityId("SampleActivity1", "Sum"));
|
||||
Assert.Equal(32, activityOutputRegister.FindOutputByActivityId("SampleActivity1", "Product"));
|
||||
}
|
||||
|
||||
[Theory(DisplayName = "Activity outputs captured in activity execution record")]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public async Task ActivityOutputCaptureParallelTest(bool runAsynchronously)
|
||||
{
|
||||
// Arrange
|
||||
var workflow = new TestWorkflow(workflowBuilder =>
|
||||
{
|
||||
var variable1 = new Variable<int>();
|
||||
var variable2 = new Variable<int>();
|
||||
workflowBuilder.Root = new Elsa.Workflows.Activities.Parallel
|
||||
{
|
||||
Variables =
|
||||
{
|
||||
variable1,
|
||||
variable2,
|
||||
},
|
||||
Activities =
|
||||
{
|
||||
new SampleActivity
|
||||
{
|
||||
Id = "SampleActivity1",
|
||||
RunAsynchronously = runAsynchronously,
|
||||
Number1 = new(4),
|
||||
Number2 = new(8),
|
||||
Sum = new(variable1),
|
||||
},
|
||||
new SampleActivity
|
||||
{
|
||||
Id = "SampleActivity2",
|
||||
RunAsynchronously = runAsynchronously,
|
||||
Number1 = new(2),
|
||||
Number2 = new(7),
|
||||
Product = new(variable2),
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
var activityExecutionStore = new MemoryActivityExecutionStore(new());
|
||||
|
||||
// Act
|
||||
var workflowFinishedRecord = await workflow.DispatchWorkflowAndRunToCompletion(
|
||||
configureServices: services =>
|
||||
{
|
||||
services.AddScoped<DistributedWorkflowRuntime>();
|
||||
},
|
||||
configureElsa: elsa =>
|
||||
{
|
||||
elsa.UseWorkflowRuntime(workflowRuntime =>
|
||||
{
|
||||
workflowRuntime.ActivityExecutionLogStore = sp => activityExecutionStore;
|
||||
workflowRuntime.WorkflowRuntime = sp => sp.GetRequiredService<DistributedWorkflowRuntime>();
|
||||
});
|
||||
});
|
||||
|
||||
// Assert
|
||||
Assert.NotNull(workflowFinishedRecord);
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowFinishedRecord.WorkflowState.Status);
|
||||
Assert.Equal(WorkflowSubStatus.Finished, workflowFinishedRecord.WorkflowState.SubStatus);
|
||||
|
||||
var activityExecutionRecord1 = await activityExecutionStore.FindAsync(new()
|
||||
{
|
||||
ActivityId = "SampleActivity1"
|
||||
});
|
||||
Assert.NotNull(activityExecutionRecord1?.Outputs);
|
||||
Assert.Equal(2, activityExecutionRecord1.Outputs!.Count);
|
||||
Assert.Equal(12, activityExecutionRecord1.Outputs!.GetValue<int>("Sum"));
|
||||
Assert.Equal(32, activityExecutionRecord1.Outputs!.GetValue<int>("Product"));
|
||||
|
||||
var activityExecutionRecord2 = await activityExecutionStore.FindAsync(new()
|
||||
{
|
||||
ActivityId = "SampleActivity2"
|
||||
});
|
||||
Assert.NotNull(activityExecutionRecord2?.Outputs);
|
||||
Assert.Equal(2, activityExecutionRecord2.Outputs!.Count);
|
||||
Assert.Equal(9, activityExecutionRecord2.Outputs!.GetValue<int>("Sum"));
|
||||
Assert.Equal(14, activityExecutionRecord2.Outputs!.GetValue<int>("Product"));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.Management;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.Serialization;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly IWorkflowDefinitionPublisher _publisher;
|
||||
private readonly IActivitySerializer _serializer;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_publisher = _services.GetRequiredService<IWorkflowDefinitionPublisher>();
|
||||
_serializer = _services.GetRequiredService<IActivitySerializer>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Can serialize newly created workflow definition")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
var workflowDefinition = _publisher.New();
|
||||
var root = _serializer.Deserialize(workflowDefinition.StringData);
|
||||
Assert.NotNull(root);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariables;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Workflow can set variable")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<SetGetVariableWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Line 5" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Workflow can reference variables set in previous activities")]
|
||||
public async Task Test2()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<SetGetVariablesWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Variable 2: The value of variable 1" }, lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Workflow can set and get named variables")]
|
||||
public async Task Test3()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<SetGetNamedVariableWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[]
|
||||
{
|
||||
"Foo = Bar",
|
||||
"Foo = Baz"
|
||||
}, lines);
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
using Elsa.Extensions;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariables;
|
||||
|
||||
class SetGetVariableWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var variable1 = new Variable<string>("Variable1", "");
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Variables =
|
||||
{
|
||||
variable1
|
||||
},
|
||||
|
||||
Activities =
|
||||
{
|
||||
new SetVariable<string>(variable1, "Line 5"),
|
||||
new WriteLine(variable1)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class SetGetVariablesWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var variable1 = new Variable<string>("Variable1", "");
|
||||
var variable2 = new Variable<string>("Variable2", "");
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Variables = { variable1, variable2 },
|
||||
|
||||
Activities =
|
||||
{
|
||||
new SetVariable
|
||||
{
|
||||
Variable = variable1,
|
||||
Value = new("The value of variable 1")
|
||||
},
|
||||
new SetVariable
|
||||
{
|
||||
Variable = variable2,
|
||||
Value = new(variable1)
|
||||
},
|
||||
new WriteLine(context => $"Variable 2: {variable2.Get(context)}")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
class SetGetNamedVariableWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Variables = { new Variable<string>("Foo", "Bar") },
|
||||
|
||||
Activities =
|
||||
{
|
||||
new WriteLine(context => $"Foo = {context.GetVariable<string>("Foo")}"),
|
||||
Inline.From(context => context.SetVariable("Foo", "Baz")),
|
||||
new WriteLine(context => $"Foo = {context.GetVariable<string>("Foo")}"),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
using Elsa.Extensions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariablesFromActivities.Activities;
|
||||
|
||||
public class CreateVariableActivity : CodeActivity
|
||||
{
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
context.SetVariable("Foo", "Bar");
|
||||
}
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
using Elsa.Extensions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariablesFromActivities.Activities;
|
||||
|
||||
public class ReadVariableActivity : CodeActivity<string>
|
||||
{
|
||||
protected override void Execute(ActivityExecutionContext context)
|
||||
{
|
||||
var foo = context.GetVariable<string>("Foo");
|
||||
Result.Set(context, foo);
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariablesFromActivities.Workflows;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariablesFromActivities;
|
||||
|
||||
public class Tests
|
||||
{
|
||||
private readonly IWorkflowRunner _workflowRunner;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IServiceProvider _services;
|
||||
|
||||
public Tests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper).WithCapturingTextWriter(_capturingTextWriter).Build();
|
||||
_services.GetRequiredService<IWorkflowBuilderFactory>();
|
||||
_workflowRunner = _services.GetRequiredService<IWorkflowRunner>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Activities can set and get variables internally")]
|
||||
public async Task Test1()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
await _workflowRunner.RunAsync<SampleWorkflow>();
|
||||
var lines = _capturingTextWriter.Lines.ToList();
|
||||
Assert.Equal(new[] { "Bar" }, lines);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariablesFromActivities.Activities;
|
||||
using Elsa.Workflows.Memory;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.SetGetVariablesFromActivities.Workflows;
|
||||
|
||||
class SampleWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
var variable1 = new Variable<string>("Variable1", "");
|
||||
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Variables =
|
||||
{
|
||||
variable1
|
||||
},
|
||||
|
||||
Activities =
|
||||
{
|
||||
new CreateVariableActivity(),
|
||||
new ReadVariableActivity
|
||||
{
|
||||
Result = new(variable1)
|
||||
},
|
||||
new WriteLine(variable1)
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
using Elsa.Common.Models;
|
||||
using Elsa.Mediator.HostedServices;
|
||||
using Elsa.Mediator.Options;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows.IntegrationTests.Scenarios.WorkflowCancellation.Workflows;
|
||||
using Elsa.Workflows.Models;
|
||||
using Elsa.Workflows.Runtime;
|
||||
using Elsa.Workflows.Runtime.Messages;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.WorkflowCancellation;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a class containing unit tests for the DefaultRuntime class.
|
||||
/// </summary>
|
||||
public class DefaultRuntimeTests
|
||||
{
|
||||
private readonly IServiceProvider _services;
|
||||
private readonly CapturingTextWriter _capturingTextWriter = new();
|
||||
private readonly IWorkflowRuntime _workflowRuntime;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="DefaultRuntimeTests"/> class.
|
||||
/// </summary>
|
||||
public DefaultRuntimeTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
_services = new TestApplicationBuilder(testOutputHelper)
|
||||
.WithCapturingTextWriter(_capturingTextWriter)
|
||||
.AddWorkflow<BulkSuspendedWorkflow>()
|
||||
.AddWorkflow<ResumeDispatchWorkflow>()
|
||||
.AddWorkflow<SimpleChildWorkflow>()
|
||||
.AddWorkflow<SimpleSuspendedWorkflow>()
|
||||
.ConfigureServices(services =>
|
||||
{
|
||||
services
|
||||
.AddSingleton(sp =>
|
||||
{
|
||||
var options = sp.GetRequiredService<IOptions<MediatorOptions>>().Value;
|
||||
return ActivatorUtilities.CreateInstance<BackgroundCommandSenderHostedService>(sp, options.CommandWorkerCount);
|
||||
})
|
||||
.AddSingleton(sp =>
|
||||
{
|
||||
var options = sp.GetRequiredService<IOptions<MediatorOptions>>().Value;
|
||||
return ActivatorUtilities.CreateInstance<BackgroundEventPublisherHostedService>(sp, options.NotificationWorkerCount);
|
||||
})
|
||||
;
|
||||
})
|
||||
.Build();
|
||||
|
||||
_workflowRuntime = _services.GetRequiredService<IWorkflowRuntime>();
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Cancelling a suspended workflow")]
|
||||
public async Task SuspendedCancelTest()
|
||||
{
|
||||
await _services.PopulateRegistriesAsync();
|
||||
|
||||
const string workflowDefinitionId = nameof(SimpleSuspendedWorkflow);
|
||||
var workflowClient = await _workflowRuntime.CreateClientAsync();
|
||||
await workflowClient.CreateInstanceAsync(new()
|
||||
{
|
||||
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionId(workflowDefinitionId, VersionOptions.Published)
|
||||
});
|
||||
var runWorkflowInstanceResponse = await workflowClient.RunInstanceAsync(RunWorkflowInstanceRequest.Empty);
|
||||
|
||||
Assert.Equal(WorkflowStatus.Running, runWorkflowInstanceResponse.Status);
|
||||
Assert.Equal(WorkflowSubStatus.Suspended, runWorkflowInstanceResponse.SubStatus);
|
||||
|
||||
await workflowClient.CancelAsync();
|
||||
var lastWorkflowState = await workflowClient.ExportStateAsync();
|
||||
|
||||
Assert.Equal(WorkflowStatus.Finished, lastWorkflowState!.Status);
|
||||
Assert.Equal(WorkflowSubStatus.Cancelled, lastWorkflowState.SubStatus);
|
||||
Assert.Empty(_capturingTextWriter.Lines);
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
using Elsa.Scheduling.Activities;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Elsa.Workflows.Runtime.Activities;
|
||||
|
||||
namespace Elsa.Workflows.IntegrationTests.Scenarios.WorkflowCancellation.Workflows;
|
||||
|
||||
public class BulkSuspendedWorkflow : WorkflowBase
|
||||
{
|
||||
protected override void Build(IWorkflowBuilder builder)
|
||||
{
|
||||
object[] items = Enumerable.Range(0, 1500).Select(x => (object)x).ToArray();
|
||||
|
||||
builder.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new Start(),
|
||||
new Delay(TimeSpan.FromSeconds(10)),
|
||||
new BulkDispatchWorkflows
|
||||
{
|
||||
WorkflowDefinitionId = new(nameof(SimpleChildWorkflow)),
|
||||
Items = new(items)
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user