using System.Collections.Generic; using Newtonsoft.Json.Serialization; using Xunit; namespace Microsoft.AspNetCore.JsonPatch.Internal { public class ObjectVisitorTest { private class Class1 { public IList States { get; set; } = new List(); public IDictionary Countries = new Dictionary(); } [Fact] public void Visit_ValidPathToArray_ReturnsListAdapter() { // Arrange var visitor = new ObjectVisitor(new ParsedPath("/States/-"), new DefaultContractResolver()); var model = new Class1(); object targetObject = model; IAdapter adapter = null; string message = null; // Act var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); // Assert Assert.True(visitStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Same(model.States, targetObject); Assert.IsType(adapter); } [Fact] public void Visit_ValidPathToDictionary_ReturnsDictionaryAdapter() { // Arrange var visitor = new ObjectVisitor(new ParsedPath("/Countries/USA"), new DefaultContractResolver()); var model = new Class1(); object targetObject = model; IAdapter adapter = null; string message = null; // Act var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); // Assert Assert.True(visitStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Same(model.Countries, targetObject); Assert.IsType(adapter); } private class AutomobileDepartment { public List Customers { get; set; } = new List(); } [Fact] public void Visit_ValidPathToArray_ReturnsListAdapter_ForDeepNestedPath() { // Arrange var visitor = new ObjectVisitor(new ParsedPath("/Customers/0/States/-"), new DefaultContractResolver()); var customer = new Class1(); var automobileDepartment = new AutomobileDepartment(); automobileDepartment.Customers.Add(customer); object targetObject = automobileDepartment; IAdapter adapter = null; string message = null; // Act var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); // Assert Assert.True(visitStatus); Assert.True(string.IsNullOrEmpty(message), "Expected no error message"); Assert.Same(customer.States, targetObject); Assert.IsType(adapter); } [Fact] public void Visit_InvalidPathToArray_Fails() { // Arrange var invalidIndex = 2; var visitor = new ObjectVisitor(new ParsedPath($"/Customers/{invalidIndex}/States/-"), new DefaultContractResolver()); var automobileDepartment = new AutomobileDepartment(); object targetObject = automobileDepartment; IAdapter adapter = null; string message = null; // Act var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); // Assert Assert.False(visitStatus); Assert.Equal(string.Format(ErrorMessageFormats.IndexOutOfBounds, invalidIndex), message); } [Fact] public void Visit_DoesNotValidate_FinalPathSegment() { // Arrange var visitor = new ObjectVisitor(new ParsedPath($"/NonExisting"), new DefaultContractResolver()); var model = new Class1(); object targetObject = model; IAdapter adapter = null; string message = null; // Act var visitStatus = visitor.TryVisit(ref targetObject, out adapter, out message); // Assert Assert.False(visitStatus); Assert.Equal(string.Format(ErrorMessageFormats.TargetLocationAtPathSegmentNotFound, "NonExisting"), message); } } }