* Refactor workflow instance deletion to use `IWorkflowRuntime` for enhanced coordination and separation of concerns. * Remove `EnumerableTypeConverter` and update related usages for serialization. - Deleted the `EnumerableTypeConverter` class and its JSON serialization logic. - Removed associated type descriptor attribute in `DefaultFormattersFeature`. - Updated `ObjectFormatter` to handle collection serialization directly with JSON. * Remove `EnumerableTypeConverter` tests and consolidate serialization logic into `ObjectFormatter`. - Deleted `EnumerableTypeConverterTests` as the related functionality was removed. - Added comprehensive tests in `ObjectFormatterTests` to handle serialization of collections and arrays with JSON. * Add integration tests for `TriggerIndexer` to handle workflows with failing materialization - Introduced comprehensive test scenarios verifying `DeleteTriggersAsync` behavior when workflows fail to load or partially succeed. - Enhanced error handling in `TriggerIndexer` to skip failed workflows while ensuring remaining workflows are processed. * Add exception handling in `TriggerIndexer.DeleteTriggersAsync` and integration tests - Enhanced `DeleteTriggersAsync` with exception handling to skip failed workflows while processing others. - Logged warnings for failed workflows without halting execution. - Added comprehensive integration tests to verify behavior across success, failure, and mixed scenarios. - Refactored tests for improved clarity, maintainability, and consistency. * Add exception handling for `ResumeWorkflowTask` to skip deleted workflow instances - Enhanced `ResumeWorkflowTask.ExecuteAsync` to handle `WorkflowInstanceNotFoundException` gracefully when a scheduled workflow instance is missing. - Logged warnings for skipped executions to improve observability. - Ensured remaining workflows and scheduled tasks are processed seamlessly without disruption. * Add thread safety to `LocalScheduler` to prevent race conditions during concurrent scheduling - Introduced a `lock` object to synchronize access to internal dictionaries. - Resolved `IndexOutOfRangeException` caused by concurrent modifications during startup. - Ensured thread-safe operations in `ScheduleAsync`, `ClearScheduleAsync`, and related methods. - Improved reliability and stability of scheduling under concurrent workloads. * Improve exception handling, thread safety, and workflow instance deletion - Added exception handling in `TriggerIndexer.DeleteTriggersAsync` to skip failed workflows while continuing processing. - Enhanced `ResumeWorkflowTask` to handle missing workflow instances gracefully and log warnings. - Introduced thread synchronization in `LocalScheduler` with `lock` to prevent concurrent access issues. - Implemented and refactored tests to ensure behavior consistency and improve maintainability. - Added component tests for workflow deletion scenarios, covering running, completed, and non-existent workflows. * Add component tests for workflow instance deletion and refactor bulk delete logic - Added comprehensive component tests for workflow instance deletion scenarios (running, completed, bulk, and non-existent instances). - Refactored `BulkDelete` API to use `IWorkflowInstanceManager` for proper cleanup of related records (execution logs, activity executions, bookmarks). * Add integration tests and fakes for `TriggerIndexer` to verify behavior with failing and successful workflows - Introduced `FailingMaterializer` and `WorkingMaterializer` for simulating failing and successful workflow materializations. - Added `TriggerDeletionTestScenario`, `TriggerTestDataBuilder`, and related test data classes to define comprehensive test cases. - Updated `DeleteTriggersAsync` tests with scenarios for materialization failures and mixed success. - Improved test coverage and maintainability with reusable test data builders and utilities.
108 lines
3.3 KiB
C#
108 lines
3.3 KiB
C#
using Elsa.Expressions.Helpers;
|
|
|
|
namespace Elsa.Common.IntegrationTests.Serialization;
|
|
|
|
/// <summary>
|
|
/// Tests for ObjectFormatter.Format() to ensure proper serialization of different types:
|
|
/// - Strings are preserved as-is
|
|
/// - Byte arrays are base64-encoded
|
|
/// - Arrays and collections serialize to JSON instead of "T[] Array"
|
|
/// Related to GitHub issue #7019.
|
|
/// </summary>
|
|
public class ObjectFormatterTests
|
|
{
|
|
[Fact(DisplayName = "String is preserved as-is")]
|
|
public void StringIsPreservedAsIs()
|
|
{
|
|
var testString = "Hello World";
|
|
var result = testString.Format();
|
|
|
|
Assert.Equal("Hello World", result);
|
|
}
|
|
|
|
[Fact(DisplayName = "Byte array is serialized as base64 string")]
|
|
public void ByteArrayIsSerializedAsBase64String()
|
|
{
|
|
var testByteArray = new byte[] { 0x01, 0x02, 0x03, 0x04, 0xFF };
|
|
var result = testByteArray.Format();
|
|
|
|
// Byte arrays are base64-encoded for serialization
|
|
Assert.NotNull(result);
|
|
var expectedBase64 = Convert.ToBase64String(testByteArray);
|
|
Assert.Equal(expectedBase64, result);
|
|
}
|
|
|
|
[Fact(DisplayName = "Integer array is serialized as JSON array")]
|
|
public void IntegerArrayIsSerializedAsJsonArray()
|
|
{
|
|
var testArray = new[] { 1, 2, 3, 4, 5 };
|
|
var result = testArray.Format();
|
|
|
|
Assert.Equal("[1,2,3,4,5]", result);
|
|
}
|
|
|
|
[Fact(DisplayName = "String array is serialized as JSON array")]
|
|
public void StringArrayIsSerializedAsJsonArray()
|
|
{
|
|
var testArray = new[] { "Hello", "World" };
|
|
var result = testArray.Format();
|
|
|
|
Assert.Equal("[\"Hello\",\"World\"]", result);
|
|
}
|
|
|
|
[Fact(DisplayName = "String array with multiple elements is serialized as JSON array")]
|
|
public void StringArrayWithMultipleElementsIsSerializedAsJsonArray()
|
|
{
|
|
var testArray = new[] { "Element 1", "Element 2", "Element 3" };
|
|
var result = testArray.Format();
|
|
|
|
Assert.Equal("[\"Element 1\",\"Element 2\",\"Element 3\"]", result);
|
|
}
|
|
|
|
[Fact(DisplayName = "Custom class array is serialized as JSON array")]
|
|
public void CustomClassArrayIsSerializedAsJsonArray()
|
|
{
|
|
var testArray = new[] { new TestClass { Name = "Item1" }, new TestClass { Name = "Item2" } };
|
|
var result = testArray.Format();
|
|
|
|
// Should be JSON, not "TestClass[] Array"
|
|
Assert.NotNull(result);
|
|
Assert.StartsWith("[", result);
|
|
Assert.Contains("Item1", result);
|
|
Assert.Contains("Item2", result);
|
|
}
|
|
|
|
[Fact(DisplayName = "List of integers is serialized as JSON array")]
|
|
public void ListOfIntegersIsSerializedAsJsonArray()
|
|
{
|
|
var testList = new List<int> { 1, 2, 3 };
|
|
var result = testList.Format();
|
|
|
|
Assert.Equal("[1,2,3]", result);
|
|
}
|
|
|
|
[Fact(DisplayName = "List with different values is serialized as JSON array")]
|
|
public void ListWithDifferentValuesIsSerializedAsJsonArray()
|
|
{
|
|
var testList = new List<int> { 10, 20, 30 };
|
|
var result = testList.Format();
|
|
|
|
Assert.Equal("[10,20,30]", result);
|
|
}
|
|
|
|
[Fact(DisplayName = "Null returns null")]
|
|
public void NullReturnsNull()
|
|
{
|
|
object? testValue = null;
|
|
var result = testValue.Format();
|
|
|
|
Assert.Null(result);
|
|
}
|
|
|
|
private class TestClass
|
|
{
|
|
public string Name { get; set; } = string.Empty;
|
|
}
|
|
}
|
|
|