From f7b7ea4d730ad49893ae200c2b720ecc472fcf03 Mon Sep 17 00:00:00 2001 From: Sipke Schoorstra Date: Tue, 21 Oct 2025 15:31:31 +0200 Subject: [PATCH] Add unit tests for `FlowFork` activity and enhance test utilities (#6995) * Add unit tests for `FlowFork` activity and enhance test utilities - Introduce `FlowForkTests` to validate activity behavior with various branch configurations. - Extend `ActivityExecutionContextExtensions` with methods to retrieve and check outcomes. - Modify `ActivityTestFixture` to ensure activities transition to `Running` status before execution. * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .../ActivityExecutionContextExtensions.cs | 12 ++++++ .../ActivityTestFixture.cs | 1 + .../Branching/FlowForkTests.cs | 40 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 test/unit/Elsa.Activities.UnitTests/Branching/FlowForkTests.cs diff --git a/src/common/Elsa.Testing.Shared/ActivityExecutionContextExtensions.cs b/src/common/Elsa.Testing.Shared/ActivityExecutionContextExtensions.cs index fc5f5bff3..6af31b080 100644 --- a/src/common/Elsa.Testing.Shared/ActivityExecutionContextExtensions.cs +++ b/src/common/Elsa.Testing.Shared/ActivityExecutionContextExtensions.cs @@ -17,4 +17,16 @@ public static class ActivityExecutionContextExtensions { return activityExecutionContext.WorkflowExecutionContext.Scheduler.Find(x => x.Activity == activity) != null; } + + public static IEnumerable GetOutcomes(this ActivityExecutionContext activityExecutionContext) + { + if (activityExecutionContext.JournalData.TryGetValue("Outcomes", out var outcomesObj) && outcomesObj is string[] outcomes) + return outcomes; + return []; + } + + public static bool HasOutcome(this ActivityExecutionContext activityExecutionContext, string outcome) + { + return activityExecutionContext.GetOutcomes().Contains(outcome); + } } \ No newline at end of file diff --git a/src/common/Elsa.Testing.Shared/ActivityTestFixture.cs b/src/common/Elsa.Testing.Shared/ActivityTestFixture.cs index 8412d2189..0b077d1c9 100644 --- a/src/common/Elsa.Testing.Shared/ActivityTestFixture.cs +++ b/src/common/Elsa.Testing.Shared/ActivityTestFixture.cs @@ -83,6 +83,7 @@ public class ActivityTestFixture // Set up variables and inputs, then execute the activity await SetupExistingVariablesAsync(Activity, context); await context.EvaluateInputPropertiesAsync(); + context.TransitionTo(ActivityStatus.Running); await Activity.ExecuteAsync(context); return context; diff --git a/test/unit/Elsa.Activities.UnitTests/Branching/FlowForkTests.cs b/test/unit/Elsa.Activities.UnitTests/Branching/FlowForkTests.cs new file mode 100644 index 000000000..8d1f74580 --- /dev/null +++ b/test/unit/Elsa.Activities.UnitTests/Branching/FlowForkTests.cs @@ -0,0 +1,40 @@ +using Elsa.Testing.Shared; +using Elsa.Workflows; +using Elsa.Workflows.Activities.Flowchart.Activities; + +namespace Elsa.Activities.UnitTests.Branching; + +public class FlowForkTests +{ + [Theory] + [MemberData(nameof(BranchTestCases))] + public async Task Should_Complete_With_Specified_Branches(string[] branches, string[] expectedOutcomes) + { + // Arrange + var flowFork = new FlowFork(); + if (branches.Length > 0) + flowFork.Branches = new(branches); + + // Act + var context = await ExecuteAsync(flowFork); + + // Assert - Activity should complete with all outcomes. + var outcomes = context.GetOutcomes().ToList(); + + Assert.Equal(expectedOutcomes.Length, outcomes.Count); + foreach (var expectedOutcome in expectedOutcomes) + Assert.Contains(expectedOutcome, outcomes); + } + + public static IEnumerable BranchTestCases() + { + yield return [Array.Empty(), new[] { "Done" }]; + yield return [new[] { "SingleBranch" }, new[] { "SingleBranch" }]; + yield return [new[] { "Branch1", "Branch2", "Branch3" }, new[] { "Branch1", "Branch2", "Branch3" }]; + } + + private static Task ExecuteAsync(IActivity activity) + { + return new ActivityTestFixture(activity).ExecuteAsync(); + } +}