aspnetcore/test/Microsoft.AspNetCore.JsonPa.../JsonPatchDocumentJsonProper...

306 lines
11 KiB
C#

// 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 System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using Xunit;
namespace Microsoft.AspNetCore.JsonPatch
{
public class JsonPatchDocumentJsonPropertyAttributeTest
{
[Fact]
public void Add_ToRoot_OfListOfObjects_AtEndOfList()
{
var patchDoc = new JsonPatchDocument<List<JsonPropertyObject>>();
patchDoc.Add(p => p, new JsonPropertyObject());
var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>(serialized);
// get path
var pathToCheck = deserialized.Operations.First().path;
Assert.Equal("/-", pathToCheck);
}
[Fact]
public void Add_ToRoot_OfListOfObjects_AtGivenPosition()
{
var patchDoc = new JsonPatchDocument<List<JsonPropertyObject>>();
patchDoc.Add(p => p[3], new JsonPropertyObject());
var serialized = JsonConvert.SerializeObject(patchDoc);
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>(serialized);
// get path
var pathToCheck = deserialized.Operations.First().path;
Assert.Equal("/3", pathToCheck);
}
[Fact]
public void Add_WithExpression_RespectsJsonPropertyName_ForModelProperty()
{
var patchDoc = new JsonPatchDocument<JsonPropertyObject>();
patchDoc.Add(p => p.Name, "John");
var serialized = JsonConvert.SerializeObject(patchDoc);
// serialized value should have "AnotherName" as path
// deserialize to a JsonPatchDocument<JsonPropertyWithAnotherNameDTO> to check
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>(serialized);
// get path
var pathToCheck = deserialized.Operations.First().path;
Assert.Equal("/AnotherName", pathToCheck);
}
[Fact]
public void Add_WithExpressionOnStringProperty_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty()
{
// Arrange
var patchDoc = new JsonPatchDocument<JsonPropertyWithNoPropertyName>();
patchDoc.Add(m => m.StringProperty, "Test");
var serialized = JsonConvert.SerializeObject(patchDoc);
// Act
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithNoPropertyName>>(serialized);
// Assert
var pathToCheck = deserialized.Operations.First().path;
Assert.Equal("/StringProperty", pathToCheck);
}
[Fact]
public void Add_WithExpressionOnArrayProperty_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty()
{
// Arrange
var patchDoc = new JsonPatchDocument<JsonPropertyWithNoPropertyName>();
patchDoc.Add(m => m.ArrayProperty, "James");
var serialized = JsonConvert.SerializeObject(patchDoc);
// Act
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithNoPropertyName>>(serialized);
// Assert
var pathToCheck = deserialized.Operations.First().path;
Assert.Equal("/ArrayProperty/-", pathToCheck);
}
[Fact]
public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToDifferentlyTypedClassWithPropertyMatchingJsonPropertyName()
{
var patchDocToSerialize = new JsonPatchDocument<JsonPropertyObject>();
patchDocToSerialize.Add(p => p.Name, "John");
// the patchdoc will deserialize to "anothername". We should thus be able to apply
// it to a class that HAS that other property name.
var doc = new JsonPropertyWithAnotherNameObject()
{
AnotherName = "InitialValue"
};
var serialized = JsonConvert.SerializeObject(patchDocToSerialize);
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>
(serialized);
deserialized.ApplyTo(doc);
Assert.Equal("John", doc.AnotherName);
}
[Fact]
public void Add_WithExpression_RespectsJsonPropertyName_WhenApplyingToSameTypedClassWithMatchingJsonPropertyName()
{
var patchDocToSerialize = new JsonPatchDocument<JsonPropertyObject>();
patchDocToSerialize.Add(p => p.Name, "John");
// the patchdoc will deserialize to "anothername". As JsonPropertyDTO has
// a JsonProperty signifying that "Name" should be deseriallized from "AnotherName",
// we should be able to apply the patchDoc.
var doc = new JsonPropertyObject()
{
Name = "InitialValue"
};
var serialized = JsonConvert.SerializeObject(patchDocToSerialize);
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyObject>>
(serialized);
deserialized.ApplyTo(doc);
Assert.Equal("John", doc.Name);
}
[Fact]
public void Add_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument()
{
var doc = new JsonPropertyObject()
{
Name = "InitialValue"
};
// serialization should serialize to "AnotherName"
var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]";
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyObject>>(serialized);
deserialized.ApplyTo(doc);
Assert.Equal("Kevin", doc.Name);
}
[Fact]
public void Remove_OnApplyFromJson_RespectsJsonPropertyNameOnJsonDocument()
{
var doc = new JsonPropertyObject()
{
Name = "InitialValue"
};
// serialization should serialize to "AnotherName"
var serialized = "[{\"path\":\"/AnotherName\",\"op\":\"remove\"}]";
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyObject>>(serialized);
deserialized.ApplyTo(doc);
Assert.Null(doc.Name);
}
[Fact]
public void Add_OnApplyFromJson_RespectsInheritedJsonPropertyNameOnJsonDocument()
{
var doc = new JsonPropertyWithInheritanceObject()
{
Name = "InitialName"
};
// serialization should serialize to "AnotherName"
var serialized = "[{\"value\":\"Kevin\",\"path\":\"/AnotherName\",\"op\":\"add\"}]";
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithInheritanceObject>>(serialized);
deserialized.ApplyTo(doc);
Assert.Equal("Kevin", doc.Name);
}
[Fact]
public void Add_WithExpression_RespectsJsonPropertyName_ForInheritedModelProperty()
{
var patchDoc = new JsonPatchDocument<JsonPropertyWithInheritanceObject>();
patchDoc.Add(p => p.Name, "John");
var serialized = JsonConvert.SerializeObject(patchDoc);
// serialized value should have "AnotherName" as path
// deserialize to a JsonPatchDocument<JsonPropertyWithAnotherNameDTO> to check
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithAnotherNameObject>>(serialized);
// get path
var pathToCheck = deserialized.Operations.First().path;
Assert.Equal("/AnotherName", pathToCheck);
}
[Fact]
public void Add_OnApplyFromJson_EscapingHandledOnComplexJsonPropertyNameOnJsonDocument()
{
var doc = new JsonPropertyComplexNameObject()
{
FooSlashBars = "InitialName",
FooSlashTilde = new SimpleObject
{
StringProperty = "Initial Value"
}
};
// serialization should serialize to "AnotherName"
var serialized = "[{\"value\":\"Kevin\",\"path\":\"/foo~1bar~0\",\"op\":\"add\"},{\"value\":\"Final Value\",\"path\":\"/foo~1~0/StringProperty\",\"op\":\"replace\"}]";
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyComplexNameObject>>(serialized);
deserialized.ApplyTo(doc);
Assert.Equal("Kevin", doc.FooSlashBars);
Assert.Equal("Final Value", doc.FooSlashTilde.StringProperty);
}
[Fact]
public void Move_WithExpression_FallsbackToPropertyName_WhenJsonPropertyName_IsEmpty()
{
// Arrange
var patchDoc = new JsonPatchDocument<JsonPropertyWithNoPropertyName>();
patchDoc.Move(m => m.StringProperty, m => m.StringProperty2);
var serialized = JsonConvert.SerializeObject(patchDoc);
// Act
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithNoPropertyName>>(serialized);
// Assert
var fromPath = deserialized.Operations.First().from;
Assert.Equal("/StringProperty", fromPath);
var toPath = deserialized.Operations.First().path;
Assert.Equal("/StringProperty2", toPath);
}
[Fact]
public void Add_WithExpression_AndCustomContractResolver_UsesPropertyName_SetByContractResolver()
{
// Arrange
var patchDoc = new JsonPatchDocument<JsonPropertyWithNoPropertyName>();
patchDoc.ContractResolver = new CustomContractResolver();
patchDoc.Add(m => m.SSN, "123-45-6789");
var serialized = JsonConvert.SerializeObject(patchDoc);
// Act
var deserialized =
JsonConvert.DeserializeObject<JsonPatchDocument<JsonPropertyWithNoPropertyName>>(serialized);
// Assert
var path = deserialized.Operations.First().path;
Assert.Equal("/SocialSecurityNumber", path);
}
private class JsonPropertyWithNoPropertyName
{
[JsonProperty]
public string StringProperty { get; set; }
[JsonProperty]
public string[] ArrayProperty { get; set; }
[JsonProperty]
public string StringProperty2 { get; set; }
[JsonProperty]
public string SSN { get; set; }
}
private class CustomContractResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
var jsonProperty = base.CreateProperty(member, memberSerialization);
if (jsonProperty.PropertyName == "SSN")
{
jsonProperty.PropertyName = "SocialSecurityNumber";
}
return jsonProperty;
}
}
}
}