// 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; using System.Collections; using System.Collections.Generic; using System.Linq; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; using Xunit; namespace Microsoft.AspNetCore.Mvc.Internal { public class DefaultCollectionValidationStrategyTest { [Fact] public void EnumerateElements() { // Arrange var model = new List() { 2, 3, 5 }; var metadata = TestModelMetadataProvider.CreateDefaultProvider().GetMetadataForType(typeof(List)); var strategy = DefaultCollectionValidationStrategy.Instance; // Act var enumerator = strategy.GetChildren(metadata, "prefix", model); // Assert Assert.Collection( BufferEntries(enumerator).OrderBy(e => e.Key), e => { Assert.Equal("prefix[0]", e.Key); Assert.Equal(2, e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }, e => { Assert.Equal("prefix[1]", e.Key); Assert.Equal(3, e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }, e => { Assert.Equal("prefix[2]", e.Key); Assert.Equal(5, e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }); } [Fact] public void EnumerateElements_Dictionary() { // Arrange var model = new Dictionary() { { 2, "two" }, { 3, "three" }, { 5, "five" }, }; var metadata = TestModelMetadataProvider.CreateDefaultProvider().GetMetadataForType(typeof(List)); var strategy = DefaultCollectionValidationStrategy.Instance; // Act var enumerator = strategy.GetChildren(metadata, "prefix", model); // Assert Assert.Collection( BufferEntries(enumerator).OrderBy(e => e.Key), e => { Assert.Equal("prefix[0]", e.Key); Assert.Equal(new KeyValuePair(2, "two"), e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }, e => { Assert.Equal("prefix[1]", e.Key); Assert.Equal(new KeyValuePair(3, "three"), e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }, e => { Assert.Equal("prefix[2]", e.Key); Assert.Equal(new KeyValuePair(5, "five"), e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }); } [Fact] public void EnumerateElements_TwoEnumerableImplemenations() { // Arrange var model = new TwiceEnumerable(new int[] { 2, 3, 5 }); var metadata = TestModelMetadataProvider.CreateDefaultProvider().GetMetadataForType(typeof(TwiceEnumerable)); var strategy = DefaultCollectionValidationStrategy.Instance; // Act var enumerator = strategy.GetChildren(metadata, "prefix", model); // Assert Assert.Collection( BufferEntries(enumerator).OrderBy(e => e.Key), e => { Assert.Equal("prefix[0]", e.Key); Assert.Equal(2, e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }, e => { Assert.Equal("prefix[1]", e.Key); Assert.Equal(3, e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }, e => { Assert.Equal("prefix[2]", e.Key); Assert.Equal(5, e.Model); Assert.Same(metadata.ElementMetadata, e.Metadata); }); } // 'int' is chosen by validation because it's declared on the more derived type. private class TwiceEnumerable : List, IEnumerable { private readonly IEnumerable _enumerable; public TwiceEnumerable(IEnumerable enumerable) { _enumerable = enumerable; } IEnumerator IEnumerable.GetEnumerator() { return _enumerable.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { throw new InvalidOperationException(); } } private List BufferEntries(IEnumerator enumerator) { var entries = new List(); while (enumerator.MoveNext()) { entries.Add(enumerator.Current); } return entries; } } }