Add Unicode string serialization tests (#5064)

Added tests in `Elsa.Workflows.Core.UnitTests` and `Elsa.JavaScript.UnitTests` to ensure unicode string serialization works correctly. Added a shared `UnicodeRangeGenerator` for test data generation and updated project references accordingly. Renamed `WorkflowDefinitionActivityJavaScriptHandlerTests.cs` to `ToJsonTests.cs` to reflect the focused test purpose.
This commit is contained in:
Sipke Schoorstra 2024-03-12 19:31:39 +01:00 committed by GitHub
parent cef0cceef0
commit f7b010a518
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 205 additions and 13 deletions

View file

@ -0,0 +1,70 @@
namespace Elsa.Testing.Shared;
/// <summary>
/// Generates Unicode ranges.
/// </summary>
public static class UnicodeRangeGenerator
{
/// <summary>
/// Generates a range of Unicode characters.
/// </summary>
public static string GenerateUnicodeString()
{
// This method generates a string containing characters from various Unicode ranges.
var sb = new System.Text.StringBuilder();
// Add some characters from various ranges
sb.Append('a'); // Basic Latin
sb.Append('\u0370'); // Greek and Coptic
sb.Append('\u200B'); // Zero width space
sb.Append('\u4E00'); // CJK Unified Ideographs
// German umlauts (in unicode):
sb.Append('\u00E4'); // ä
sb.Append('\u00F6'); // ö
sb.Append('\u00FC'); // ü
sb.Append('\u00DF'); // ß
// French characters (in unicode):
sb.Append('\u00E0'); // à
sb.Append('\u00E2'); // â
sb.Append('\u00E7'); // ç
sb.Append('\u00E8'); // è
// Chinese characters (in unicode):
sb.Append('\u4E00'); // 一
sb.Append('\u4E01'); // 丁
sb.Append('\u4E02'); // 丂
sb.Append('\u4E03'); // 七
// Russian characters (in unicode):
sb.Append('\u0410'); // А
sb.Append('\u0411'); // Б
sb.Append('\u0412'); // В
sb.Append('\u0413'); // Г
sb.Append('\u0414'); // Д
sb.Append('\u0415'); // Е
// Arabic characters (in unicode):
sb.Append('\u0627'); // ا
sb.Append('\u0628'); // ب
sb.Append('\u0629'); // ة
sb.Append('\u062A'); // ت
// Syriac characters (in unicode):
sb.Append('\u0710'); // ܐ
sb.Append('\u0711'); // ܑ
sb.Append('\u0712'); // ܒ
sb.Append('\u0713'); // ܓ
sb.Append('\u0714'); // ܔ
// Hebrew characters (in unicode):
sb.Append('\u05D0'); // א
sb.Append('\u05D1'); // ב
sb.Append('\u05D2'); // ג
sb.Append('\u05D3'); // ד
return sb.ToString();
}
}

View file

@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\common\Elsa.Testing.Shared\Elsa.Testing.Shared.csproj" />
<ProjectReference Include="..\..\..\src\modules\Elsa.JavaScript\Elsa.JavaScript.csproj" />
</ItemGroup>

View file

@ -0,0 +1,48 @@
using System.Text.Json;
using Elsa.Expressions.Models;
using Elsa.JavaScript.Contracts;
using Elsa.Testing.Shared;
using Elsa.Workflows.Memory;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
using Xunit.Abstractions;
namespace Elsa.JavaScript.UnitTests;
public class ToJsonTests(ITestOutputHelper testOutputHelper)
{
private readonly IServiceProvider _serviceProvider = new TestApplicationBuilder(testOutputHelper).Build();
[Fact(DisplayName = "Serialize large unicode string using JavaScript's toJson function")]
public async Task Test1()
{
var javaScriptEvaluator = _serviceProvider.GetRequiredService<IJavaScriptEvaluator>();
var unicodeString = UnicodeRangeGenerator.GenerateUnicodeString();
var script = $"toJson({{ text: '{unicodeString}' }})";
var expressionExecutionContext = new ExpressionExecutionContext(_serviceProvider, new MemoryRegister());
var result = (string)(await javaScriptEvaluator.EvaluateAsync(script, typeof(string), expressionExecutionContext))!;
var serializedText = JsonDocument.Parse(result).RootElement.GetProperty("text").GetString();
Assert.Equal(unicodeString, serializedText);
}
[Fact(DisplayName = "Serialize large unicode string using JavaScript's toJson function from a workflow variable")]
public async Task Test2()
{
var javaScriptEvaluator = _serviceProvider.GetRequiredService<IJavaScriptEvaluator>();
var expressionExecutionContext = new ExpressionExecutionContext(_serviceProvider, new MemoryRegister());
var unicodeString = UnicodeRangeGenerator.GenerateUnicodeString();
var payloadVariable = new Variable<object>
{
Name = "Payload"
};
var payload = new
{
Text = unicodeString
};
payloadVariable.Set(expressionExecutionContext, payload);
var script = "toJson(getPayload())";
var result = (string)(await javaScriptEvaluator.EvaluateAsync(script, typeof(string), expressionExecutionContext))!;
var serializedText = JsonDocument.Parse(result).RootElement.GetProperty("Text").GetString();
Assert.Equal(unicodeString, serializedText);
}
}

View file

@ -1,13 +0,0 @@
using Xunit;
namespace Elsa.JavaScript.UnitTests;
public class WorkflowDefinitionActivityJavaScriptHandlerTests
{
[Fact]
public void Test1()
{
}
}

View file

@ -5,6 +5,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\common\Elsa.Testing.Shared\Elsa.Testing.Shared.csproj" />
<ProjectReference Include="..\..\..\src\modules\Elsa.Workflows.Core\Elsa.Workflows.Core.csproj" />
</ItemGroup>

View file

@ -0,0 +1,85 @@
using System.Text.Json;
using Elsa.Testing.Shared;
using Elsa.Workflows.Contracts;
using Microsoft.Extensions.DependencyInjection;
using Xunit.Abstractions;
namespace Elsa.Workflows.Core.UnitTests;
public class SerializerUnicodeEncodingTests(ITestOutputHelper testOutputHelper)
{
private readonly IServiceProvider _serviceProvider = new TestApplicationBuilder(testOutputHelper).Build();
[Fact]
public void TestPayloadSerializer()
{
var serializer = _serviceProvider.GetRequiredService<IPayloadSerializer>();
TestSerializer(input => serializer.Serialize(input));
}
[Fact]
public void TestApiSerializer()
{
var serializer = _serviceProvider.GetRequiredService<IApiSerializer>();
TestSerializer(input => serializer.Serialize(input));
}
[Fact]
public void TestBookmarkPayloadSerializer()
{
var serializer = _serviceProvider.GetRequiredService<IBookmarkPayloadSerializer>();
TestSerializer(input => serializer.Serialize(input));
}
[Fact]
public async Task TestSafeSerializer()
{
var serializer = _serviceProvider.GetRequiredService<ISafeSerializer>();
await TestSerializerAsync(input => serializer.SerializeAsync(input).AsTask());
}
[Fact]
public async Task TestWorkflowStateSerializer()
{
var serializer = _serviceProvider.GetRequiredService<IWorkflowStateSerializer>();
await TestSerializerAsync(input => serializer.SerializeAsync(input));
}
private void TestSerializer(Func<object, string> serialize)
{
var unicodeString = UnicodeRangeGenerator.GenerateUnicodeString();
var anonymousObject = new
{
Text = unicodeString
};
var serializedJson = serialize(anonymousObject);
var serializedStringValue = GetSerializedTextValue(serializedJson);
Assert.Equal(unicodeString, serializedStringValue);
}
private async Task TestSerializerAsync(Func<object, Task<string>> serialize)
{
var unicodeString = UnicodeRangeGenerator.GenerateUnicodeString();
var anonymousObject = new
{
Text = unicodeString
};
var serializedJson = await serialize(anonymousObject);
var serializedStringValue = GetSerializedTextValue(serializedJson);
Assert.Equal(unicodeString, serializedStringValue);
}
private string GetSerializedTextValue(string serializedJson)
{
var rootElement = JsonDocument.Parse(serializedJson).RootElement;
return GetCaseInsensitiveSerializedTextValue(rootElement, "text", "Text");
}
private string GetCaseInsensitiveSerializedTextValue(JsonElement jsonElement, params string[] propertyNames)
{
foreach (string propertyName in propertyNames)
if (jsonElement.TryGetProperty(propertyName, out var property))
return property.GetString()!;
throw new KeyNotFoundException($"None of the following properties were found: {string.Join(", ", propertyNames)}");
}
}