1 // Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information. 2 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Web.Http.Controllers; 6 using System.Web.Http.Metadata.Providers; 7 using System.Web.Http.Util; 8 using Moq; 9 using Xunit; 10 11 namespace System.Web.Http.ModelBinding.Binders 12 { 13 public class KeyValuePairModelBinderTest 14 { 15 [Fact] BindModel_MissingKey_ReturnsFalse()16 public void BindModel_MissingKey_ReturnsFalse() 17 { 18 // Arrange 19 KeyValuePairModelBinder<int, string> binder = new KeyValuePairModelBinder<int, string>(); 20 ModelBindingContext bindingContext = new ModelBindingContext 21 { 22 ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)), 23 ModelName = "someName", 24 ValueProvider = new SimpleHttpValueProvider() 25 }; 26 HttpActionContext context = ContextUtil.CreateActionContext(); 27 context.ControllerContext.Configuration.Services.Replace(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(KeyValuePair<int, string>), binder)); 28 29 // Act 30 bool retVal = binder.BindModel(context, bindingContext); 31 32 // Assert 33 Assert.False(retVal); 34 Assert.Null(bindingContext.Model); 35 Assert.Empty(bindingContext.ValidationNode.ChildNodes); 36 } 37 38 [Fact] BindModel_MissingValue_ReturnsTrue()39 public void BindModel_MissingValue_ReturnsTrue() 40 { 41 // Arrange 42 Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); 43 ModelBindingContext bindingContext = new ModelBindingContext 44 { 45 ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)), 46 ModelName = "someName", 47 ValueProvider = new SimpleHttpValueProvider() 48 }; 49 HttpActionContext context = ContextUtil.CreateActionContext(); 50 context.ControllerContext.Configuration.Services.Replace(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) { SuppressPrefixCheck = true }); 51 52 mockIntBinder 53 .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>())) 54 .Returns((HttpActionContext cc, ModelBindingContext mbc) => 55 { 56 mbc.Model = 42; 57 return true; 58 }); 59 KeyValuePairModelBinder<int, string> binder = new KeyValuePairModelBinder<int, string>(); 60 61 // Act 62 bool retVal = binder.BindModel(context, bindingContext); 63 64 // Assert 65 Assert.True(retVal); 66 Assert.Null(bindingContext.Model); 67 Assert.Equal(new[] { "someName.key" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray()); 68 } 69 70 [Fact] BindModel_SubBindingSucceeds()71 public void BindModel_SubBindingSucceeds() 72 { 73 // Arrange 74 Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); 75 Mock<IModelBinder> mockStringBinder = new Mock<IModelBinder>(); 76 ModelBindingContext bindingContext = new ModelBindingContext 77 { 78 ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair<int, string>)), 79 ModelName = "someName", 80 ValueProvider = new SimpleHttpValueProvider() 81 }; 82 HttpActionContext context = ContextUtil.CreateActionContext(); 83 context.ControllerContext.Configuration.Services.ReplaceRange(typeof(ModelBinderProvider), 84 new ModelBinderProvider[] { 85 new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) { SuppressPrefixCheck = true }, 86 new SimpleModelBinderProvider(typeof(string), mockStringBinder.Object) { SuppressPrefixCheck = true } 87 }); 88 89 mockIntBinder 90 .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>())) 91 .Returns((HttpActionContext cc, ModelBindingContext mbc) => 92 { 93 mbc.Model = 42; 94 return true; 95 }); 96 mockStringBinder 97 .Setup(o => o.BindModel(context, It.IsAny<ModelBindingContext>())) 98 .Returns((HttpActionContext cc, ModelBindingContext mbc) => 99 { 100 mbc.Model = "forty-two"; 101 return true; 102 }); 103 KeyValuePairModelBinder<int, string> binder = new KeyValuePairModelBinder<int, string>(); 104 105 // Act 106 bool retVal = binder.BindModel(context, bindingContext); 107 108 // Assert 109 Assert.True(retVal); 110 Assert.Equal(new KeyValuePair<int, string>(42, "forty-two"), bindingContext.Model); 111 Assert.Equal(new[] { "someName.key", "someName.value" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray()); 112 } 113 } 114 } 115