* Unit test coverage for SendHttpRequest + useful extensions * Update src/modules/Elsa.Workflows.Core/Extensions/ActivityExecutionContextExtensions.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Improvements on unit test and documentation for http * Update doc/qa/test-guidelines.md Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com> * Improvements on maintainability of sendhttprequest unit tests * Improving tests and scheduled activity evaluation for activity context * Refactor and splitting unnecessary grouped tests * Improvements on SendHttp Unit tests * Improvements on tests * Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Small suggestions from copilot * Update test/unit/Elsa.Activities.UnitTests/HTTP/SendHttpRequestTests.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * small copilot suggestion * Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts (#6984) * Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts - Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces. - Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows. - Refactored scheduling logic to utilize the new scheduler strategies. - Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes. - Adjusted background execution scheduling and improved extensibility for custom scheduler strategies. * Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic. * Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing - Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities. - Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services. - Updated test guidelines and unit tests to use the new fixture and extensions. - Removed `ActivityTestHelper`. * Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites - Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`. - Updated namespaces and imports across unit tests to reflect new structure. - Enhanced `AssertActivityAttributes` and added fluent configuration APIs. - Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`. * Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup. * Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters. * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add XML documentation for scheduler strategies and their methods - Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods. - Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity. * Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions. * Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports. * Add `ParallelTests` for unit and integration testing with various scenarios (#6988) - Added unit tests for `Parallel` activity to ensure proper scheduling of child activities, including empty and mixed activity cases. - Added integration tests to validate execution flow and edge cases for `Parallel` activities (e.g., nested parallelism, fault handling). - Enhanced `ScheduleChildrenAsync` in `Parallel` to handle no activity scenario by completing immediately. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add new unit and integration tests for activity input and expression evaluation (#6990) * Introduce Scheduler Strategy Interfaces and Implementations for Workflow and Activity Execution Contexts - Added `IWorkflowExecutionContextSchedulerStrategy` and `IActivityExecutionContextSchedulerStrategy` interfaces. - Implemented `WorkflowExecutionContextSchedulerStrategy` and `ActivityExecutionContextSchedulerStrategy` for scheduling activities in workflows. - Refactored scheduling logic to utilize the new scheduler strategies. - Updated unit tests and test helpers to reflect refactoring, introducing fake implementations for testing purposes. - Adjusted background execution scheduling and improved extensibility for custom scheduler strategies. * Refactor `SendHttpRequestTests`: simplify scheduling assertions, use shared extensions, and standardize method naming. Streamline helper methods and remove unused test logic. * Refactor: Replace `ActivityTestHelper` with `ActivityTestFixture` in unit tests for streamlined activity testing - Introduced `ActivityTestFixture` with a fluent API for better test setup and execution of activities. - Added extension methods `ActivityTestFixtureExtensions` and `ActivityTestFixtureHttpExtensions` for configuring attributes and HTTP services. - Updated test guidelines and unit tests to use the new fixture and extensions. - Removed `ActivityTestHelper`. * Refactor: Move `ActivityTestFixture` and related extensions to shared project for reuse across test suites - Consolidated `ActivityTestFixture`, `ActivityTestFixtureExtensions`, and `ActivityTestFixtureHttpExtensions` into `Elsa.Testing.Shared`. - Updated namespaces and imports across unit tests to reflect new structure. - Enhanced `AssertActivityAttributes` and added fluent configuration APIs. - Adjusted `Directory.Packages.props` with new dependencies, including `NSubstitute` and `xunit.assert`. * Refactor `SetVariableTests`: inline `ActivityTestFixture` initialization to simplify test setup. * Refactor `ActivityTestFixture`: eliminate redundant field `_services`, add `UsedImplicitly` attributes, and improve service collection management * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add XML documentation for `ActivityExecutionContextExtensions`, detailing methods and parameters. * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Add XML documentation for scheduler strategies and their methods - Updated `IActivityExecutionContextSchedulerStrategy` and `IWorkflowExecutionContextSchedulerStrategy` interfaces with XML summaries for methods. - Added XML documentation to implementations (`ActivityExecutionContextSchedulerStrategy`, `WorkflowExecutionContextSchedulerStrategy`) and test fakes for clarity. * Refactor `WriteLineTests`: consolidate duplicate test logic, simplify setup with shared helper method, and enhance readability in assertions. * Refactor `WriteLineTests` and `SetVariableTests`: replace `WriteLineAsync` assertions with synchronous `WriteLine`, streamline exception recording in `SetVariableTests`, and remove unused imports. * Add new unit and integration tests for activity input and expression evaluation - Introduced comprehensive test suites covering activity input evaluation, expression handling, and fault scenarios. - Added unit tests for `ExpressionDescriptorRegistry`, `ExpressionEvaluator`, and activity execution context extensions. - Added integration tests: `CustomInputEvaluatorTests`, `InputEvaluationErrorTests`, and `InputPropertyEvaluationTests`. - Enhanced code coverage for edge cases and async evaluation logic. * Remove unused `RunWorkflowAsync` extension method from `RunActivityExtensions`. * Rename `CustomInputEvaluatorTests` to `InputEvaluationTests` for consistency with naming conventions. * Remove unused `Elsa.Workflows.Activities` import from `RunActivityExtensions`. * Remove redundant comments from `InputEvaluationErrorTests` for clarity. * Refactor unit tests to streamline activity and expression evaluations - Refactored `ExecuteActivityAsync` and `ExecuteWriteLineAsync` into shared helpers for consistency and reuse across tests. - Replaced redundant mock setups with helper methods in `ExpressionDescriptorRegistryTests`. - Simplified test setup for expression and activity evaluation by removing unused imports and consolidating configuration logic. - Enhanced readability by reducing duplicate code and leveraging shared utility methods. * Refactor activity input evaluation tests - Extracted `CreateContextAsync` helper into `EvaluationTestHelpers` for reuse across evaluation test suites. - Replaced inline activity context setup with shared helper in `InputPropertyEvaluationTests`, `WrappedInputEvaluationTests`, and related test suites. - Simplified test method names for clarity and consistency. - Updated test annotations to enhance readability and align with naming conventions. * Remove redundant test cases and unused imports - Deleted duplicated and non-essential test cases across evaluation test suites. - Removed unused imports to improve code cleanliness and readability. - Streamlined variable initializations and method calls within test setups. * Remove redundant test case from `InputEvaluationErrorTests` - Deleted the `ContinuesEvaluationForMultipleInputs` test, as it overlaps with existing tests and does not provide additional coverage. * Remove redundant assertion from `InputPropertyEvaluationTests` - Deleted `Assert.True(context.GetHasEvaluatedProperties())`, as it is unnecessary for verifying test outcomes. * Remove redundant test cases from `WrappedInputEvaluationTests` - Deleted `UsesDefaultValueWhenInputIsNull` and `EvaluatesExpression` tests as they are either duplicated or unnecessary for current test coverage. * Add unit test projects for `Elsa.Workflows.Management` and `Elsa.Expressions` - Introduced new test projects to separate and organize unit tests for `Elsa.Workflows.Management` and `Elsa.Expressions`. - Updated `Elsa.sln` to include references to the newly added test projects. - Adjusted namespaces in affected test classes for consistency with the updated project structure. * Refactor `ExpressionEvaluatorTests` for clarity and consistency - Simplified test method names and annotations for improved readability. - Replaced duplicate mock setups with helper functions (`CreateContextAsync`, `CreateContextWithMockHandlerAsync`, and related methods). - Streamlined test setups by removing redundant code and consolidating context creation logic. - Updated test annotations to include descriptive `DisplayName` attributes. * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Remove redundant comment from `ExpressionEvaluatorTests` for clarity * Remove redundant blank lines from unit test classes - Eliminated unnecessary blank lines across `ActivityExecutionContextExtensions` test suites to improve code readability and consistency. * Update src/modules/Elsa.Expressions/Services/ExpressionEvaluator.cs Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Expand `test-guidelines.md` with testing best practices, helper references, and example snippets - Added detailed guidance on test project organization, updated helper documentation, and streamlined example code for activity unit testing. - Introduced scheduler strategy information and integration test patterns for deterministic tests. - Clarified usage of shared infrastructure like `ActivityTestFixture` and `AsyncWorkflowRunner`. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --------- Co-authored-by: lucas.hipolito <lukhipolito@yahoo.com.br> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Sipke Schoorstra <sipkeschoorstra@outlook.com>
142 lines
5.6 KiB
C#
142 lines
5.6 KiB
C#
using System.Net;
|
|
using System.Text;
|
|
using Elsa.Http;
|
|
using Elsa.Http.ContentWriters;
|
|
using Elsa.Http.Parsers;
|
|
using Elsa.Resilience;
|
|
using Elsa.Testing.Shared;
|
|
using Elsa.Workflows;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using NSubstitute;
|
|
|
|
namespace Elsa.Activities.UnitTests.Helpers;
|
|
|
|
/// <summary>
|
|
/// Extension methods for configuring HTTP-related services in ActivityTestFixture.
|
|
/// </summary>
|
|
public static class ActivityTestFixtureHttpExtensions
|
|
{
|
|
/// <summary>
|
|
/// Configures services commonly needed for HTTP activity testing.
|
|
/// This is a convenience method that combines HTTP services, mock HTTP client factory, and mock resilient invoker.
|
|
/// </summary>
|
|
/// <param name="fixture">The test fixture to configure</param>
|
|
/// <param name="responseHandler">Handler for HTTP requests, or null to use a default OK response</param>
|
|
/// <returns>The fixture instance for method chaining</returns>
|
|
public static ActivityTestFixture WithHttpServices(
|
|
this ActivityTestFixture fixture,
|
|
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>>? responseHandler = null)
|
|
{
|
|
fixture.ConfigureServices(services =>
|
|
{
|
|
var defaultHandler = responseHandler ?? ((_, _) => Task.FromResult(CreateHttpResponse(HttpStatusCode.OK)));
|
|
var mockHttpClientFactory = CreateMockHttpClientFactory(defaultHandler);
|
|
|
|
services.AddSingleton(mockHttpClientFactory);
|
|
services.AddSingleton(CreateMockResilientActivityInvoker());
|
|
AddHttpServices(services);
|
|
services.AddLogging();
|
|
});
|
|
|
|
return fixture;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a simple HTTP response message with specified status code and optional JSON content.
|
|
/// </summary>
|
|
/// <param name="statusCode">The HTTP status code for the response</param>
|
|
/// <param name="jsonContent">Optional JSON content for the response body</param>
|
|
/// <param name="additionalHeaders">Optional additional headers to add to the response</param>
|
|
/// <returns>An HttpResponseMessage configured with the specified parameters</returns>
|
|
public static HttpResponseMessage CreateHttpResponse(
|
|
HttpStatusCode statusCode,
|
|
string? jsonContent = null,
|
|
Dictionary<string, string>? additionalHeaders = null)
|
|
{
|
|
var response = new HttpResponseMessage(statusCode);
|
|
|
|
if (jsonContent != null)
|
|
{
|
|
response.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json");
|
|
}
|
|
|
|
if (additionalHeaders != null)
|
|
{
|
|
foreach (var header in additionalHeaders)
|
|
{
|
|
response.Headers.Add(header.Key, header.Value);
|
|
}
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds all HTTP-related services to the service collection.
|
|
/// This includes content factories, parsers, and HTTP client services.
|
|
/// </summary>
|
|
private static void AddHttpServices(IServiceCollection services)
|
|
{
|
|
// Add all required HTTP services
|
|
services.AddSingleton<IHttpContentFactory, JsonContentFactory>();
|
|
services.AddSingleton<IHttpContentFactory, TextContentFactory>();
|
|
services.AddSingleton<IHttpContentFactory, XmlContentFactory>();
|
|
services.AddSingleton<IHttpContentFactory, FormUrlEncodedHttpContentFactory>();
|
|
|
|
// Add HTTP content parsers
|
|
AddHttpContentParsers(services);
|
|
|
|
// Add other required services
|
|
services.AddHttpClient();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds HTTP content parsers to the service collection.
|
|
/// These parsers are responsible for parsing different content types in HTTP responses.
|
|
/// </summary>
|
|
private static void AddHttpContentParsers(IServiceCollection services)
|
|
{
|
|
services.AddSingleton<IHttpContentParser, JsonHttpContentParser>();
|
|
services.AddSingleton<IHttpContentParser, PlainTextHttpContentParser>();
|
|
services.AddSingleton<IHttpContentParser, XmlHttpContentParser>();
|
|
services.AddSingleton<IHttpContentParser, TextHtmlHttpContentParser>();
|
|
services.AddSingleton<IHttpContentParser, FileHttpContentParser>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a mock IResilientActivityInvoker that directly executes the provided action.
|
|
/// Useful for testing activities that depend on resilient execution without the complexity of retry policies.
|
|
/// </summary>
|
|
private static IResilientActivityInvoker CreateMockResilientActivityInvoker()
|
|
{
|
|
var mock = Substitute.For<IResilientActivityInvoker>();
|
|
|
|
// Configure the mock to simply execute the provided action directly
|
|
mock.InvokeAsync(
|
|
Arg.Any<IResilientActivity>(),
|
|
Arg.Any<ActivityExecutionContext>(),
|
|
Arg.Any<Func<Task<HttpResponseMessage>>>(),
|
|
Arg.Any<CancellationToken>())
|
|
.Returns(callInfo =>
|
|
{
|
|
var action = callInfo.ArgAt<Func<Task<HttpResponseMessage>>>(2);
|
|
return action.Invoke();
|
|
});
|
|
|
|
return mock;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a mock HTTP client factory with a test handler for controlled HTTP responses.
|
|
/// </summary>
|
|
private static IHttpClientFactory CreateMockHttpClientFactory(
|
|
Func<HttpRequestMessage, CancellationToken, Task<HttpResponseMessage>> responseHandler)
|
|
{
|
|
var mockHttpClientFactory = Substitute.For<IHttpClientFactory>();
|
|
var testHandler = new TestHttpMessageHandler(responseHandler);
|
|
var httpClient = new HttpClient(testHandler);
|
|
mockHttpClientFactory.CreateClient(Arg.Any<string>()).Returns(httpClient);
|
|
return mockHttpClientFactory;
|
|
}
|
|
}
|