// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using Microsoft.AspNetCore.JsonPatch.Exceptions; using Newtonsoft.Json; using Xunit; namespace Microsoft.AspNetCore.JsonPatch { public class JsonPatchDocumentTest { [Fact] public void InvalidPathAtBeginningShouldThrowException() { // Arrange var patchDocument = new JsonPatchDocument(); // Act var exception = Assert.Throws(() => { patchDocument.Add("//NewInt", 1); }); // Assert Assert.Equal( "The provided string '//NewInt' is an invalid path.", exception.Message); } [Fact] public void InvalidPathAtEndShouldThrowException() { // Arrange var patchDocument = new JsonPatchDocument(); // Act var exception = Assert.Throws(() => { patchDocument.Add("NewInt//", 1); }); // Assert Assert.Equal( "The provided string 'NewInt//' is an invalid path.", exception.Message); } [Fact] public void NonGenericPatchDocToGenericMustSerialize() { // Arrange var targetObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; var patchDocument = new JsonPatchDocument(); patchDocument.Copy("StringProperty", "AnotherStringProperty"); var serialized = JsonConvert.SerializeObject(patchDocument); var deserialized = JsonConvert.DeserializeObject>(serialized); // Act deserialized.ApplyTo(targetObject); // Assert Assert.Equal("A", targetObject.AnotherStringProperty); } [Fact] public void GenericPatchDocToNonGenericMustSerialize() { // Arrange var targetObject = new SimpleObject() { StringProperty = "A", AnotherStringProperty = "B" }; var patchDocTyped = new JsonPatchDocument(); patchDocTyped.Copy(o => o.StringProperty, o => o.AnotherStringProperty); var patchDocUntyped = new JsonPatchDocument(); patchDocUntyped.Copy("StringProperty", "AnotherStringProperty"); var serializedTyped = JsonConvert.SerializeObject(patchDocTyped); var serializedUntyped = JsonConvert.SerializeObject(patchDocUntyped); var deserialized = JsonConvert.DeserializeObject(serializedTyped); // Act deserialized.ApplyTo(targetObject); // Assert Assert.Equal("A", targetObject.AnotherStringProperty); } [Fact] public void Deserialization_Successful_ForValidJsonPatchDocument() { // Arrange var doc = new SimpleObject() { StringProperty = "A", DecimalValue = 10, DoubleValue = 10, FloatValue = 10, IntegerValue = 10 }; var patchDocument = new JsonPatchDocument(); patchDocument.Replace(o => o.StringProperty, "B"); patchDocument.Replace(o => o.DecimalValue, 12); patchDocument.Replace(o => o.DoubleValue, 12); patchDocument.Replace(o => o.FloatValue, 12); patchDocument.Replace(o => o.IntegerValue, 12); // default: no envelope var serialized = JsonConvert.SerializeObject(patchDocument); // Act var deserialized = JsonConvert.DeserializeObject>(serialized); // Assert Assert.IsType>(deserialized); } [Fact] public void Deserialization_Fails_ForInvalidJsonPatchDocument() { // Arrange var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; // Act var exception = Assert.Throws(() => { var deserialized = JsonConvert.DeserializeObject(serialized); }); // Assert Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); } [Fact] public void Deserialization_Fails_ForInvalidTypedJsonPatchDocument() { // Arrange var serialized = "{\"Operations\": [{ \"op\": \"replace\", \"path\": \"/title\", \"value\": \"New Title\"}]}"; // Act var exception = Assert.Throws(() => { var deserialized = JsonConvert.DeserializeObject>(serialized); }); // Assert Assert.Equal("The JSON patch document was malformed and could not be parsed.", exception.Message); } } }