From ad21e1604ce1a13892f35e813d699211a7ebeedf Mon Sep 17 00:00:00 2001 From: Pavel Krymets Date: Wed, 3 Jun 2020 16:35:31 -0700 Subject: [PATCH] Default to more Newtonsoft-like response encoding in TestFramework (#12482) --- .../src/RecordEntry.cs | 28 +++++++++++++------ .../Azure.Core/tests/RecordSessionTests.cs | 2 ++ 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/sdk/core/Azure.Core.TestFramework/src/RecordEntry.cs b/sdk/core/Azure.Core.TestFramework/src/RecordEntry.cs index 7d9c38527007..0484c8ce6f27 100644 --- a/sdk/core/Azure.Core.TestFramework/src/RecordEntry.cs +++ b/sdk/core/Azure.Core.TestFramework/src/RecordEntry.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Text.Encodings.Web; using System.Text.Json; using Azure.Core.Pipeline; @@ -13,6 +14,15 @@ namespace Azure.Core.TestFramework { public class RecordEntry { + private static readonly JsonWriterOptions RequestWriterOptions = new JsonWriterOptions(); + // Responses are usually formatted using Newtonsoft.Json that has more relaxed encoding rules + // To enable us to store more responses as JSON instead of string in Recording files use + // relaxed settings for roundrip + private static readonly JsonWriterOptions ResponseWriterOptions = new JsonWriterOptions() + { + Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping + }; + public RecordEntryMessage Request { get; } = new RecordEntryMessage(); public RecordEntryMessage Response { get; } = new RecordEntryMessage(); @@ -51,7 +61,7 @@ public static RecordEntry Deserialize(JsonElement element) if (element.TryGetProperty("RequestBody", out property)) { - record.Request.Body = DeserializeBody(record.Request.Headers, property); + record.Request.Body = DeserializeBody(record.Request.Headers, property, RequestWriterOptions); } if (element.TryGetProperty(nameof(StatusCode), out property) && @@ -67,13 +77,13 @@ public static RecordEntry Deserialize(JsonElement element) if (element.TryGetProperty("ResponseBody", out property)) { - record.Response.Body = DeserializeBody(record.Response.Headers, property); + record.Response.Body = DeserializeBody(record.Response.Headers, property, ResponseWriterOptions); } return record; } - private static byte[] DeserializeBody(IDictionary headers, in JsonElement property) + private static byte[] DeserializeBody(IDictionary headers, in JsonElement property, JsonWriterOptions writerOptions) { if (property.ValueKind == JsonValueKind.Null) { @@ -85,7 +95,7 @@ private static byte[] DeserializeBody(IDictionary headers, in if (property.ValueKind == JsonValueKind.Object) { using var memoryStream = new MemoryStream(); - using var writer = new Utf8JsonWriter(memoryStream); + using var writer = new Utf8JsonWriter(memoryStream, writerOptions); property.WriteTo(writer); writer.Flush(); return memoryStream.ToArray(); @@ -146,7 +156,7 @@ public void Serialize(Utf8JsonWriter jsonWriter) SerializeHeaders(jsonWriter, Request.Headers); jsonWriter.WriteEndObject(); - SerializeBody(jsonWriter, "RequestBody", Request.Body, Request.Headers); + SerializeBody(jsonWriter, "RequestBody", Request.Body, Request.Headers, RequestWriterOptions); jsonWriter.WriteNumber(nameof(StatusCode), StatusCode); @@ -154,11 +164,11 @@ public void Serialize(Utf8JsonWriter jsonWriter) SerializeHeaders(jsonWriter, Response.Headers); jsonWriter.WriteEndObject(); - SerializeBody(jsonWriter, "ResponseBody", Response.Body, Response.Headers); + SerializeBody(jsonWriter, "ResponseBody", Response.Body, Response.Headers, ResponseWriterOptions); jsonWriter.WriteEndObject(); } - private void SerializeBody(Utf8JsonWriter jsonWriter, string name, byte[] requestBody, IDictionary headers) + private void SerializeBody(Utf8JsonWriter jsonWriter, string name, byte[] requestBody, IDictionary headers, JsonWriterOptions writerOptions) { if (requestBody == null) { @@ -184,9 +194,9 @@ private void SerializeBody(Utf8JsonWriter jsonWriter, string name, byte[] reques // Make sure we can replay JSON is exactly the same as the source // for the case where service response was pre-formatted // fallback to generic string writing - var memoryStream = new MemoryStream(); + using var memoryStream = new MemoryStream(); // Settings of this writer should be in sync with the one used in deserialiation - using (var reformattedWriter = new Utf8JsonWriter(memoryStream)) + using (var reformattedWriter = new Utf8JsonWriter(memoryStream, writerOptions)) { document.RootElement.WriteTo(reformattedWriter); } diff --git a/sdk/core/Azure.Core/tests/RecordSessionTests.cs b/sdk/core/Azure.Core/tests/RecordSessionTests.cs index 22259a5630c6..197a95b8c8da 100644 --- a/sdk/core/Azure.Core/tests/RecordSessionTests.cs +++ b/sdk/core/Azure.Core/tests/RecordSessionTests.cs @@ -5,6 +5,7 @@ using System.IO; using System.Linq; using System.Text; +using System.Text.Encodings.Web; using System.Text.Json; using Azure.Core.Pipeline; using Azure.Core.TestFramework; @@ -16,6 +17,7 @@ namespace Azure.Core.Tests public class RecordSessionTests { [TestCase("{\"json\":\"value\"}", "application/json")] + [TestCase("{\"json\":\"\\\"value\\\"\"}", "application/json")] [TestCase("{\"json\":{\"json\":\"value\"}}", "application/json")] [TestCase("{\"json\"\n:\"value\"}", "application/json")] [TestCase("{\"json\" :\"value\"}", "application/json")]