Add unit and integration tests for Complete activity to validate composite workflows execution (#7108)
* Add unit and integration tests for `Complete` activity to validate composite workflows execution - Introduced integration and unit tests covering `Complete` activity behavior in nested and simple composite workflows. - Added `CompleteTests` for edge cases such as immediate parent completion and composite termination. - Developed new composite activities (`InnerComposite`, `OuterComposite`, `SimpleComposite`) for testing scenarios. * Remove unnecessary `Complete` constructors tests.
This commit is contained in:
parent
87dc976b5f
commit
8700036123
|
|
@ -0,0 +1,32 @@
|
|||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Activities.IntegrationTests.Composition.Activities;
|
||||
|
||||
/// <summary>
|
||||
/// Inner composite activity that uses Complete.
|
||||
/// </summary>
|
||||
public class InnerComposite : Composite
|
||||
{
|
||||
private readonly WriteLine _completedMessage = new("Inner composite completed");
|
||||
|
||||
public InnerComposite()
|
||||
{
|
||||
Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Inner composite started"),
|
||||
new Complete(),
|
||||
new WriteLine("This should not execute in inner"),
|
||||
_completedMessage
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected override async ValueTask OnCompletedAsync(ActivityCompletedContext context)
|
||||
{
|
||||
// Schedule the completion message
|
||||
await context.TargetContext.ScheduleActivityAsync(_completedMessage);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Activities.IntegrationTests.Composition.Activities;
|
||||
|
||||
/// <summary>
|
||||
/// Outer composite activity for nested composite testing.
|
||||
/// </summary>
|
||||
public class OuterComposite : Composite
|
||||
{
|
||||
public OuterComposite()
|
||||
{
|
||||
Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new InnerComposite(),
|
||||
new WriteLine("After inner composite")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Activities.IntegrationTests.Composition.Activities;
|
||||
|
||||
/// <summary>
|
||||
/// Simple composite activity that uses Complete to terminate early.
|
||||
/// </summary>
|
||||
public class SimpleComposite : Composite
|
||||
{
|
||||
public SimpleComposite()
|
||||
{
|
||||
Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Before Complete"),
|
||||
new Complete(),
|
||||
new WriteLine("This should not execute")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
using Elsa.Activities.IntegrationTests.Composition.Workflows;
|
||||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Activities;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Elsa.Activities.IntegrationTests.Composition;
|
||||
|
||||
/// <summary>
|
||||
/// Integration tests for the <see cref="Complete"/> activity.
|
||||
/// </summary>
|
||||
public class CompleteTests(ITestOutputHelper testOutputHelper)
|
||||
{
|
||||
private readonly WorkflowTestFixture _fixture = new WorkflowTestFixture(testOutputHelper)
|
||||
.AddWorkflow<CompleteTerminatesCompositeWorkflow>()
|
||||
.AddWorkflow<CompleteInNestedCompositeWorkflow>();
|
||||
|
||||
[Fact(DisplayName = "Complete terminates composite execution immediately")]
|
||||
public async Task Complete_TerminatesCompositeExecutionImmediately()
|
||||
{
|
||||
// Act
|
||||
var workflowState = await _fixture.RunWorkflowAsync(CompleteTerminatesCompositeWorkflow.DefinitionId);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowState.Status);
|
||||
var lines = _fixture.CapturingTextWriter.Lines.ToList();
|
||||
Assert.Contains("Before Complete", lines);
|
||||
Assert.DoesNotContain("This should not execute", lines);
|
||||
Assert.Contains("After composite", lines);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Complete in nested composite completes immediate parent only")]
|
||||
public async Task Complete_InNestedComposite_CompletesImmediateParentOnly()
|
||||
{
|
||||
// Act
|
||||
var workflowState = await _fixture.RunWorkflowAsync(CompleteInNestedCompositeWorkflow.DefinitionId);
|
||||
|
||||
// Assert
|
||||
Assert.Equal(WorkflowStatus.Finished, workflowState.Status);
|
||||
var lines = _fixture.CapturingTextWriter.Lines.ToList();
|
||||
Assert.Contains("Outer composite started", lines);
|
||||
Assert.Contains("Inner composite started", lines);
|
||||
Assert.Contains("Inner composite completed", lines);
|
||||
Assert.Contains("Outer composite completed", lines);
|
||||
Assert.DoesNotContain("This should not execute in inner", lines);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using Elsa.Activities.IntegrationTests.Composition.Activities;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Activities.IntegrationTests.Composition.Workflows;
|
||||
|
||||
/// <summary>
|
||||
/// Workflow with nested composite activities to verify Complete only affects immediate parent.
|
||||
/// </summary>
|
||||
public class CompleteInNestedCompositeWorkflow : WorkflowBase
|
||||
{
|
||||
public static readonly string DefinitionId = Guid.NewGuid().ToString();
|
||||
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow.WithDefinitionId(DefinitionId);
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new WriteLine("Outer composite started"),
|
||||
new OuterComposite(),
|
||||
new WriteLine("Outer composite completed")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
using Elsa.Activities.IntegrationTests.Composition.Activities;
|
||||
using Elsa.Workflows;
|
||||
using Elsa.Workflows.Activities;
|
||||
|
||||
namespace Elsa.Activities.IntegrationTests.Composition.Workflows;
|
||||
|
||||
/// <summary>
|
||||
/// Workflow demonstrating that Complete terminates composite execution immediately.
|
||||
/// </summary>
|
||||
public class CompleteTerminatesCompositeWorkflow : WorkflowBase
|
||||
{
|
||||
public static readonly string DefinitionId = Guid.NewGuid().ToString();
|
||||
|
||||
protected override void Build(IWorkflowBuilder workflow)
|
||||
{
|
||||
workflow.WithDefinitionId(DefinitionId);
|
||||
workflow.Root = new Sequence
|
||||
{
|
||||
Activities =
|
||||
{
|
||||
new SimpleComposite(),
|
||||
new WriteLine("After composite")
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
using Elsa.Testing.Shared;
|
||||
using Elsa.Workflows;
|
||||
|
||||
namespace Elsa.Activities.UnitTests.Composition;
|
||||
|
||||
/// <summary>
|
||||
/// Unit tests for the <see cref="Complete"/> activity.
|
||||
/// </summary>
|
||||
public class CompleteTests
|
||||
{
|
||||
[Fact(DisplayName = "Complete implements ITerminalNode interface")]
|
||||
public void Complete_ImplementsITerminalNode()
|
||||
{
|
||||
// Arrange
|
||||
var completeActivity = new Complete();
|
||||
|
||||
// Assert
|
||||
Assert.IsAssignableFrom<ITerminalNode>(completeActivity);
|
||||
}
|
||||
|
||||
[Fact(DisplayName = "Complete completes execution")]
|
||||
public async Task Complete_CompletesExecution()
|
||||
{
|
||||
// Arrange
|
||||
var completeActivity = new Complete();
|
||||
var fixture = new ActivityTestFixture(completeActivity);
|
||||
|
||||
// Act
|
||||
var context = await fixture.ExecuteAsync();
|
||||
|
||||
// Assert
|
||||
Assert.Equal(ActivityStatus.Completed, context.Status);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue