using Elsa.Expressions.Models; using Elsa.Testing.Shared; using Elsa.Workflows; using NSubstitute; namespace Elsa.Activities.UnitTests.Branching; public class SwitchTests { [Theory] [InlineData(SwitchMode.MatchFirst, true)] [InlineData(SwitchMode.MatchAny, true)] [InlineData(SwitchMode.MatchFirst, false)] [InlineData(SwitchMode.MatchAny, false)] public async Task Should_Handle_No_Matching_Cases_Correctly(SwitchMode mode, bool hasDefault) { // Arrange var defaultActivity = hasDefault ? Substitute.For() : null; var switchActivity = new Switch { Mode = new(mode), Cases = new List { new("False Case", Expression.LiteralExpression(false), Substitute.For()) }, Default = defaultActivity }; // Act var context = await ExecuteAsync(switchActivity); // Assert var scheduledActivities = context.WorkflowExecutionContext.Scheduler.List().ToList(); if (hasDefault) { Assert.Single(scheduledActivities); Assert.Equal(defaultActivity, scheduledActivities.First().Activity); } else { Assert.Empty(scheduledActivities); } } [Theory] [InlineData(SwitchMode.MatchFirst, 1)] [InlineData(SwitchMode.MatchAny, 2)] public async Task Should_Handle_Multiple_Matching_Cases_According_To_Mode(SwitchMode mode, int expectedScheduledCount) { // Arrange var firstTrueActivity = Substitute.For(); var secondTrueActivity = Substitute.For(); var switchActivity = new Switch { Mode = new(mode), Cases = new List { new("False", Expression.LiteralExpression(false), Substitute.For()), new("First True", Expression.LiteralExpression(true), firstTrueActivity), new("Second True", Expression.LiteralExpression(true), secondTrueActivity) } }; // Act var context = await ExecuteAsync(switchActivity); // Assert var scheduledActivities = context.WorkflowExecutionContext.Scheduler.List().ToList(); Assert.Equal(expectedScheduledCount, scheduledActivities.Count); if (mode == SwitchMode.MatchFirst) { Assert.Equal(firstTrueActivity, scheduledActivities.First().Activity); } else // MatchAny { Assert.Contains(scheduledActivities, s => s.Activity == firstTrueActivity); Assert.Contains(scheduledActivities, s => s.Activity == secondTrueActivity); } } [Fact] public async Task Should_Use_MatchFirst_As_Default_Mode() { // Arrange var firstTrueActivity = Substitute.For(); var secondTrueActivity = Substitute.For(); var switchActivity = new Switch { // No Mode explicitly set - should default to MatchFirst Cases = new List { new("First True", Expression.LiteralExpression(true), firstTrueActivity), new("Second True", Expression.LiteralExpression(true), secondTrueActivity) } }; // Act var context = await ExecuteAsync(switchActivity); // Assert var scheduledActivities = context.WorkflowExecutionContext.Scheduler.List().ToList(); Assert.Single(scheduledActivities); Assert.Equal(firstTrueActivity, scheduledActivities.First().Activity); } [Theory] [InlineData(SwitchMode.MatchFirst)] [InlineData(SwitchMode.MatchAny)] public async Task Should_Schedule_Default_When_Null_Case_Condition_Evaluates_False(SwitchMode mode) { // Arrange var defaultActivity = Substitute.For(); var switchActivity = new Switch { Mode = new(mode), Cases = new List { new("Null condition", Expression.LiteralExpression(null), Substitute.For()) }, Default = defaultActivity }; // Act var context = await ExecuteAsync(switchActivity); // Assert var scheduledActivities = context.WorkflowExecutionContext.Scheduler.List().ToList(); Assert.Single(scheduledActivities); Assert.Equal(defaultActivity, scheduledActivities.First().Activity); } [Theory] [InlineData(SwitchMode.MatchFirst, true)] [InlineData(SwitchMode.MatchAny, true)] [InlineData(SwitchMode.MatchFirst, false)] [InlineData(SwitchMode.MatchAny, false)] public async Task Should_Handle_Empty_Cases_Correctly(SwitchMode mode, bool hasDefault) { // Arrange var defaultActivity = hasDefault ? Substitute.For() : null; var switchActivity = new Switch { Mode = new(mode), Cases = new List(), Default = defaultActivity }; // Act var context = await ExecuteAsync(switchActivity); // Assert var scheduledActivities = context.WorkflowExecutionContext.Scheduler.List().ToList(); if (hasDefault) { Assert.Single(scheduledActivities); Assert.Equal(defaultActivity, scheduledActivities.First().Activity); } else { Assert.Empty(scheduledActivities); } } [Fact] public void Should_Initialize_Cases_Collection_By_Default() { // Arrange & Act var switchActivity = new Switch(); // Assert Assert.NotNull(switchActivity.Cases); Assert.Empty(switchActivity.Cases); switchActivity.Cases.Add(new("Test", Expression.LiteralExpression(true), Substitute.For())); Assert.Single(switchActivity.Cases); } [Fact] public void Should_Initialize_Mode_To_MatchFirst_By_Default() { // Arrange var switchActivity = new Switch(); // Assert Assert.NotNull(switchActivity.Mode); // The actual default value verification is handled by the mode-specific behavior tests } private static Task ExecuteAsync(IActivity activity) { return new ActivityTestFixture(activity).ExecuteAsync(); } }