diff --git a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs index 7d9e609ba3..14d405ffc6 100644 --- a/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs +++ b/Microsoft.Azure.Cosmos/src/Resource/CosmosResponseFactoryCore.cs @@ -276,6 +276,12 @@ public T ToObjectpublic(ResponseMessage responseMessage) return default; } + if (responseMessage.Content.Length == 0) + { + responseMessage.Content.Dispose(); + return default; + } + return this.serializerCore.FromStream(responseMessage.Content); } } diff --git a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs similarity index 84% rename from Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs rename to Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs index 3ff401269b..8b318ad09e 100644 --- a/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSeriliazerUnitTests.cs +++ b/Microsoft.Azure.Cosmos/tests/Microsoft.Azure.Cosmos.Tests/CosmosJsonSerializerUnitTests.cs @@ -7,7 +7,6 @@ namespace Microsoft.Azure.Cosmos.Core.Tests using System; using System.Collections.Generic; using System.IO; - using System.Linq; using System.Net; using System.Text; using Microsoft.Azure.Cosmos.CosmosElements; @@ -19,15 +18,15 @@ namespace Microsoft.Azure.Cosmos.Core.Tests using Newtonsoft.Json; [TestClass] - public class CosmosJsonSeriliazerUnitTests + public class CosmosJsonSerializerUnitTests { private readonly ToDoActivity toDoActivity = new ToDoActivity() { - id = "c1d433c1-369d-430e-91e5-14e3ce588f71", - taskNum = 42, - cost = double.MaxValue, - description = "cosmos json serializer", - status = "TBD" + Id = "c1d433c1-369d-430e-91e5-14e3ce588f71", + TaskNum = 42, + Cost = double.MaxValue, + Description = "cosmos json serializer", + Status = "TBD" }; private readonly string toDoActivityJson = @"{""id"":""c1d433c1-369d-430e-91e5-14e3ce588f71"",""taskNum"":42,""cost"":1.7976931348623157E+308,""description"":""cosmos json serializer"",""status"":""TBD""}"; @@ -41,11 +40,11 @@ public void ValidateSerializer() Assert.IsNotNull(stream); ToDoActivity result = cosmosDefaultJsonSerializer.FromStream(stream); Assert.IsNotNull(result); - Assert.AreEqual(this.toDoActivity.id, result.id); - Assert.AreEqual(this.toDoActivity.taskNum, result.taskNum); - Assert.AreEqual(this.toDoActivity.cost, result.cost); - Assert.AreEqual(this.toDoActivity.description, result.description); - Assert.AreEqual(this.toDoActivity.status, result.status); + Assert.AreEqual(this.toDoActivity.Id, result.Id); + Assert.AreEqual(this.toDoActivity.TaskNum, result.TaskNum); + Assert.AreEqual(this.toDoActivity.Cost, result.Cost); + Assert.AreEqual(this.toDoActivity.Description, result.Description); + Assert.AreEqual(this.toDoActivity.Status, result.Status); } } @@ -143,11 +142,11 @@ public void ValidateCustomSerializerSettings() ToDoActivity toDoActivityNoDescription = new ToDoActivity() { - id = "c1d433c1-369d-430e-91e5-14e3ce588f71", - taskNum = 42, - cost = double.MaxValue, - description = null, - status = "TBD" + Id = "c1d433c1-369d-430e-91e5-14e3ce588f71", + TaskNum = 42, + Cost = double.MaxValue, + Description = null, + Status = "TBD" }; string toDoActivityJson = @"{""id"":""c1d433c1-369d-430e-91e5-14e3ce588f71"",""taskNum"":42,""cost"":1.7976931348623157E+308,""status"":""TBD""}"; @@ -175,19 +174,15 @@ public void ValidateResponseFactoryJsonSerializer() ResponseMessage udfResponse = this.CreateResponse(); ResponseMessage itemResponse = this.CreateResponse(); - Mock mockUserJsonSerializer = new Mock(); CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object); - CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore( - serializerCore); - - // Test the user specified response - mockUserJsonSerializer.Setup(x => x.FromStream(itemResponse.Content)).Callback(input => input.Dispose()).Returns(new ToDoActivity()); - mockUserJsonSerializer.Setup(x => x.FromStream(storedProcedureExecuteResponse.Content)).Callback(input => input.Dispose()).Returns(new ToDoActivity()); + CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore(serializerCore); // Verify all the user types use the user specified version ItemResponse itemResponseFromFactory = cosmosResponseFactory.CreateItemResponse(itemResponse); Assert.IsNotNull(itemResponseFromFactory.Diagnostics); + // Verify that FromStream is not called as the stream is empty + mockUserJsonSerializer.Verify(x => x.FromStream(itemResponse.Content), Times.Never); cosmosResponseFactory.CreateStoredProcedureExecuteResponse(storedProcedureExecuteResponse); // Throw if the setups were not called @@ -253,6 +248,27 @@ public void ValidateResponseFactoryJsonSerializer() cosmosResponseFactory.CreateUserDefinedFunctionResponse(udfResponse); } + [TestMethod] + public void ValidateResponseFactoryJsonSerializerWithContent() + { + ResponseMessage itemResponse = this.CreateResponseWithContent(); + + Mock mockUserJsonSerializer = new Mock(); + CosmosSerializerCore serializerCore = new CosmosSerializerCore(mockUserJsonSerializer.Object); + CosmosResponseFactoryInternal cosmosResponseFactory = new CosmosResponseFactoryCore(serializerCore); + + mockUserJsonSerializer.Setup(x => x.FromStream(itemResponse.Content)).Callback(input => input.Dispose()).Returns(new ToDoActivity()); + + // Verify all the user types use the user specified version + ItemResponse itemResponseFromFactory = cosmosResponseFactory.CreateItemResponse(itemResponse); + Assert.IsNotNull(itemResponseFromFactory.Diagnostics); + Assert.IsNotNull(itemResponseFromFactory.Resource); + Assert.AreEqual(HttpStatusCode.OK, itemResponseFromFactory.StatusCode); + + // Throw if the setups were not called + mockUserJsonSerializer.VerifyAll(); + } + [TestMethod] public void ValidateSqlQuerySpecSerializer() { @@ -339,6 +355,15 @@ private ResponseMessage CreateResponse() return cosmosResponse; } + private ResponseMessage CreateResponseWithContent() + { + ResponseMessage cosmosResponse = new ResponseMessage(statusCode: HttpStatusCode.OK) + { + Content = new MemoryStream(Encoding.UTF8.GetBytes(this.toDoActivityJson)) + }; + return cosmosResponse; + } + private ResponseMessage CreateQueryResponse() { List cosmosElements = new List(); @@ -387,13 +412,18 @@ private string GetSerializedToDoActivity() return @"{""id"":""c1d433c1-369d-430e-91e5-14e3ce588f71"",""taskNum"":42,""cost"":1.7976931348623157E+308,""status"":""TBD""}"; } - public class ToDoActivity + private class ToDoActivity { - public string id { get; set; } - public int taskNum { get; set; } - public double cost { get; set; } - public string description { get; set; } - public string status { get; set; } + [JsonProperty("id")] + public string Id { get; set; } + [JsonProperty("taskNum")] + public int TaskNum { get; set; } + [JsonProperty("cost")] + public double Cost { get; set; } + [JsonProperty("description")] + public string Description { get; set; } + [JsonProperty("status")] + public string Status { get; set; } } } }