From a30f81def298c39d8d692e5a51aa312952073c1d Mon Sep 17 00:00:00 2001 From: Joel Oliveira Date: Wed, 6 Sep 2023 11:36:09 +0100 Subject: [PATCH] feat: add support for customizing JsonWriterOptions in JsonCoreSerializer --- .../JsonCoreSerializer.cs | 35 +++++++++++--- .../KafkaFlow.UnitTests.csproj | 1 + .../Serializers/JsonCoreSerializerTests.cs | 48 +++++++++++++++++++ 3 files changed, 77 insertions(+), 7 deletions(-) create mode 100644 src/KafkaFlow.UnitTests/Serializers/JsonCoreSerializerTests.cs diff --git a/src/KafkaFlow.Serializer.JsonCore/JsonCoreSerializer.cs b/src/KafkaFlow.Serializer.JsonCore/JsonCoreSerializer.cs index b29a082b1..5bb840360 100644 --- a/src/KafkaFlow.Serializer.JsonCore/JsonCoreSerializer.cs +++ b/src/KafkaFlow.Serializer.JsonCore/JsonCoreSerializer.cs @@ -10,7 +10,8 @@ /// public class JsonCoreSerializer : ISerializer { - private readonly JsonSerializerOptions options; + private readonly JsonSerializerOptions serializerOptions; + private readonly JsonWriterOptions writerOptions; /// /// Initializes a new instance of the class. @@ -18,23 +19,43 @@ public class JsonCoreSerializer : ISerializer /// Json serializer options public JsonCoreSerializer(JsonSerializerOptions options) { - this.options = options; + this.serializerOptions = options; + } + + /// + /// Initializes a new instance of the class. + /// + /// Json writer options + public JsonCoreSerializer(JsonWriterOptions writerOptions) + { + this.writerOptions = writerOptions; + } + + /// + /// Initializes a new instance of the class. + /// + /// Json serializer options + /// Json writer options + public JsonCoreSerializer(JsonSerializerOptions serializerOptions, JsonWriterOptions writerOptions) + { + this.serializerOptions = serializerOptions; + this.writerOptions = writerOptions; } /// /// Initializes a new instance of the class. /// public JsonCoreSerializer() - : this(new JsonSerializerOptions()) + : this(new JsonSerializerOptions(), default) { } /// public Task SerializeAsync(object message, Stream output, ISerializerContext context) { - using var writer = new Utf8JsonWriter(output); + using var writer = new Utf8JsonWriter(output, this.writerOptions); - JsonSerializer.Serialize(writer, message, this.options); + JsonSerializer.Serialize(writer, message, this.serializerOptions); return Task.CompletedTask; } @@ -43,8 +64,8 @@ public Task SerializeAsync(object message, Stream output, ISerializerContext con public async Task DeserializeAsync(Stream input, Type type, ISerializerContext context) { return await JsonSerializer - .DeserializeAsync(input, type, this.options) + .DeserializeAsync(input, type, this.serializerOptions) .ConfigureAwait(false); } } -} +} \ No newline at end of file diff --git a/src/KafkaFlow.UnitTests/KafkaFlow.UnitTests.csproj b/src/KafkaFlow.UnitTests/KafkaFlow.UnitTests.csproj index 92605b7dd..cfba1c2c7 100644 --- a/src/KafkaFlow.UnitTests/KafkaFlow.UnitTests.csproj +++ b/src/KafkaFlow.UnitTests/KafkaFlow.UnitTests.csproj @@ -32,6 +32,7 @@ + diff --git a/src/KafkaFlow.UnitTests/Serializers/JsonCoreSerializerTests.cs b/src/KafkaFlow.UnitTests/Serializers/JsonCoreSerializerTests.cs new file mode 100644 index 000000000..eb17adf0c --- /dev/null +++ b/src/KafkaFlow.UnitTests/Serializers/JsonCoreSerializerTests.cs @@ -0,0 +1,48 @@ +namespace KafkaFlow.UnitTests.Serializers +{ + using System.IO; + using System.Text.Encodings.Web; + using System.Text.Json; + using System.Threading.Tasks; + using FluentAssertions; + using KafkaFlow.Serializer; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using Moq; + + [TestClass] + public class JsonCoreSerializerTests + { + private readonly Mock contextMock = new(); + + [TestMethod] + public async Task SerializeAsync_PreventEscapeOfAccentedCharacter_SerializedObjectDoesNotHaveAccentedCharacterEscaped() + { + // Arrange + var message = new TestMessage { Text = "Café Façade" }; + using var output = new MemoryStream(); + + var writerOptions = new JsonWriterOptions { Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping }; + + var target = new JsonCoreSerializer(writerOptions); + + // Act + await target.SerializeAsync(message, output, this.contextMock.Object); + + // Assert + var result = GetStreamText(output); + result.Should().Contain("Café Façade"); + } + + private static string GetStreamText(MemoryStream output) + { + output.Position = 0; + var reader = new StreamReader(output); + return reader.ReadToEnd(); + } + + private class TestMessage + { + public string Text { get; set; } + } + } +} \ No newline at end of file