using Elsa.Extensions; using Elsa.Testing.Shared; using Elsa.Workflows; using Microsoft.Extensions.DependencyInjection; using NSubstitute; namespace Elsa.Activities.UnitTests.Console; /// /// Unit tests for the activity. /// public class ReadLineTests { private readonly TextReader _mockTextReader; private readonly IStandardInStreamProvider _mockProvider; public ReadLineTests() { _mockTextReader = Substitute.For(); _mockProvider = Substitute.For(); _mockProvider.GetTextReader().Returns(_mockTextReader); } [Theory(DisplayName = "ReadLine reads text from input and completes successfully")] [InlineData("Hello, World!")] [InlineData("Test input")] [InlineData("")] [InlineData(" ")] [InlineData("\t")] public async Task Should_Read_Text_From_Input_And_Complete(string inputText) { // Arrange var readLine = new ReadLine(); // Act var context = await ExecuteAsync(readLine, inputText); // Assert Assert.Equal(ActivityStatus.Completed, context.Status); var result = (string)context.GetActivityOutput(() => readLine.Result)!; Assert.Equal(inputText, result); } [Fact(DisplayName = "ReadLine uses provided stream provider")] public async Task Should_Use_Provided_Stream_Provider() { // Act await ExecuteAsync(new ReadLine()); // Assert _mockProvider.Received(1).GetTextReader(); _mockTextReader.Received(1).ReadLine(); } [Fact(DisplayName = "ReadLine handles null return value from stream")] public async Task Should_Handle_Null_Return_Value() { // Arrange var readLine = new ReadLine(); // Act var context = await ExecuteAsync(readLine, null); // Assert - The null-forgiving operator in ReadLine implementation means it expects non-null, // but null can occur at end of stream. Verify the behavior stores null. var result = context.GetActivityOutput(() => readLine.Result); Assert.Null(result); } [Fact(DisplayName = "ReadLine uses default provider when none is registered")] public async Task Should_Use_Default_Provider_When_None_Registered() { // Arrange var readLine = new ReadLine(); const string expectedInput = "Default provider test"; var originalConsoleIn = System.Console.In; try { // Redirect Console.In to our StringReader System.Console.SetIn(new StringReader(expectedInput)); // Act var context = await new ActivityTestFixture(readLine).ExecuteAsync(); // Assert var result = (string)context.GetActivityOutput(() => readLine.Result)!; Assert.Equal(expectedInput, result); } finally { // Restore original Console.In System.Console.SetIn(originalConsoleIn); } } private Task ExecuteAsync(ReadLine readLine, string? inputText = "Test") { _mockTextReader.ReadLine().Returns(inputText); return new ActivityTestFixture(readLine) .ConfigureServices(services => services.AddSingleton(_mockProvider)) .ExecuteAsync(); } }