public void ExecuteBindingAsync_Traces_And_Throws_When_Inner_Throws() { // Arrange Mock<HttpParameterDescriptor> mockParamDescriptor = new Mock<HttpParameterDescriptor>() { CallBase = true }; mockParamDescriptor.Setup(d => d.ParameterName).Returns("paramName"); mockParamDescriptor.Setup(d => d.ParameterType).Returns(typeof(string)); Mock<FormatterParameterBinding> mockBinding = new Mock<FormatterParameterBinding>(mockParamDescriptor.Object, new MediaTypeFormatterCollection(), null) { CallBase = true }; InvalidOperationException exception = new InvalidOperationException("test"); mockBinding.Setup( b => b.ExecuteBindingAsync(It.IsAny<ModelMetadataProvider>(), It.IsAny<HttpActionContext>(), It.IsAny<CancellationToken>())).Throws(exception); TestTraceWriter traceWriter = new TestTraceWriter(); FormatterParameterBindingTracer tracer = new FormatterParameterBindingTracer(mockBinding.Object, traceWriter); HttpActionContext actionContext = ContextUtil.CreateActionContext(); ModelMetadataProvider metadataProvider = new EmptyModelMetadataProvider(); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ExecuteBindingAsync" }, new TraceRecord(actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Error) { Kind = TraceKind.End, Operation = "ExecuteBindingAsync" } }; // Act & Assert Exception thrown = Assert.Throws<InvalidOperationException>(() => tracer.ExecuteBindingAsync(metadataProvider, actionContext, CancellationToken.None)); // Assert Assert.Same(exception, thrown); Assert.Same(exception, traceWriter.Traces[1].Exception); Assert.Equal<TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); }
public void ExecuteBindingAsync_Traces_And_Invokes_Inner() { // Arrange Mock<HttpParameterDescriptor> mockParamDescriptor = new Mock<HttpParameterDescriptor>() { CallBase = true }; mockParamDescriptor.Setup(d => d.ParameterName).Returns("paramName"); mockParamDescriptor.Setup(d => d.ParameterType).Returns(typeof(string)); Mock<HttpParameterBinding> mockBinding = new Mock<HttpParameterBinding>(mockParamDescriptor.Object) { CallBase = true }; bool innerInvoked = false; mockBinding.Setup( b => b.ExecuteBindingAsync(It.IsAny<ModelMetadataProvider>(), It.IsAny<HttpActionContext>(), It.IsAny<CancellationToken>())).Returns(TaskHelpers.Completed()).Callback(() => innerInvoked = true); TestTraceWriter traceWriter = new TestTraceWriter(); HttpParameterBindingTracer tracer = new HttpParameterBindingTracer(mockBinding.Object, traceWriter); HttpActionContext actionContext = ContextUtil.CreateActionContext(); ModelMetadataProvider metadataProvider = new EmptyModelMetadataProvider(); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ExecuteBindingAsync" }, new TraceRecord(actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Info) { Kind = TraceKind.End, Operation = "ExecuteBindingAsync" } }; // Act Task task = tracer.ExecuteBindingAsync(metadataProvider, actionContext, CancellationToken.None); task.Wait(); // Assert Assert.Equal<TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); Assert.True(innerInvoked); }
public void ExecuteBindingAsync_Traces_And_Invokes_Inner_ReadAsync() { // Arrange Mock<HttpParameterDescriptor> mockParamDescriptor = new Mock<HttpParameterDescriptor>() { CallBase = true }; mockParamDescriptor.Setup(d => d.ParameterName).Returns("paramName"); mockParamDescriptor.Setup(d => d.ParameterType).Returns(typeof (string)); FormatterParameterBinding binding = new FormatterParameterBinding(mockParamDescriptor.Object, new MediaTypeFormatterCollection(), null); TestTraceWriter traceWriter = new TestTraceWriter(); FormatterParameterBindingTracer tracer = new FormatterParameterBindingTracer(binding, traceWriter); HttpActionContext actionContext = ContextUtil.CreateActionContext(); actionContext.Request.Content = new StringContent("true"); actionContext.Request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); ModelMetadataProvider metadataProvider = new EmptyModelMetadataProvider(); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ExecuteBindingAsync" }, new TraceRecord(actionContext.Request, TraceCategories.ModelBindingCategory, TraceLevel.Info) { Kind = TraceKind.End, Operation = "ExecuteBindingAsync" } }; // Act Task task = tracer.ExecuteBindingAsync(metadataProvider, actionContext, CancellationToken.None); task.Wait(); // Assert Assert.Equal<TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); Assert.Equal("True", actionContext.ActionArguments["paramName"]); }
public void GetModelValidator_DoesNotReadPropertyValues() { // Arrange IEnumerable<ModelValidatorProvider> validatorProviders = new[] { new ObservableModelValidatorProvider() }; ObservableModel model = new ObservableModel(); ModelMetadata metadata = new EmptyModelMetadataProvider().GetMetadataForType(() => model, typeof(ObservableModel)); // Act ModelValidator validator = ModelValidator.GetModelValidator(validatorProviders); ModelValidationResult[] results = validator.Validate(metadata, model).ToArray(); // Assert Assert.False(model.PropertyWasRead()); }
public void Validate_SkipsRemainingValidationIfModelStateIsInvalid() { // Because a property validator fails, the model validator shouldn't run // Arrange List<string> log = new List<string>(); LoggingValidatableObject model = new LoggingValidatableObject(log); ModelMetadata modelMetadata = GetModelMetadata(model); ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "InvalidStringProperty"); ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.InvalidStringProperty")); node.Validating += (sender, e) => log.Add("In OnValidating()"); node.Validated += (sender, e) => log.Add("In OnValidated()"); HttpActionContext context = ContextUtil.CreateActionContext(); // Act node.Validate(context); // Assert Assert.Equal(new[] { "In OnValidating()", "In IValidatableObject.Validate()", "In OnValidated()" }, log.ToArray()); Assert.Equal("Sample error message", context.ModelState["theKey.InvalidStringProperty"].Errors[0].ErrorMessage); }
public void Validate_Ordering() { // Proper order of invocation: // 1. OnValidating() // 2. Child validators // 3. This validator // 4. OnValidated() // Arrange List<string> log = new List<string>(); LoggingValidatableObject model = new LoggingValidatableObject(log); ModelMetadata modelMetadata = GetModelMetadata(model); ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "ValidStringProperty"); ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey"); node.Validating += (sender, e) => log.Add("In OnValidating()"); node.Validated += (sender, e) => log.Add("In OnValidated()"); node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.ValidStringProperty")); // Act node.Validate(ContextUtil.CreateActionContext()); // Assert Assert.Equal(new[] { "In OnValidating()", "In LoggingValidatonAttribute.IsValid()", "In IValidatableObject.Validate()", "In OnValidated()" }, log.ToArray()); }
public void BindModel() { // Arrange MyModel model = new MyModel(); ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => model, typeof(MyModel)); ComplexModelDto dto = new ComplexModelDto(modelMetadata, modelMetadata.Properties); Mock<IModelBinder> mockStringBinder = new Mock<IModelBinder>(); Mock<IModelBinder> mockIntBinder = new Mock<IModelBinder>(); Mock<IModelBinder> mockDateTimeBinder = new Mock<IModelBinder>(); HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.ServiceResolver.SetServices(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(string), mockStringBinder.Object) { SuppressPrefixCheck = true }, new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) { SuppressPrefixCheck = true }, new SimpleModelBinderProvider(typeof(DateTime), mockDateTimeBinder.Object) { SuppressPrefixCheck = true }); mockStringBinder .Setup(b => b.BindModel(context, It.IsAny<ModelBindingContext>())) .Returns((HttpActionContext ec, ModelBindingContext mbc) => { Assert.Equal(typeof(string), mbc.ModelType); Assert.Equal("theModel.StringProperty", mbc.ModelName); mbc.ValidationNode = new ModelValidationNode(mbc.ModelMetadata, "theModel.StringProperty"); mbc.Model = "someStringValue"; return true; }); mockIntBinder .Setup(b => b.BindModel(context, It.IsAny<ModelBindingContext>())) .Returns((HttpActionContext ec, ModelBindingContext mbc) => { Assert.Equal(typeof(int), mbc.ModelType); Assert.Equal("theModel.IntProperty", mbc.ModelName); mbc.ValidationNode = new ModelValidationNode(mbc.ModelMetadata, "theModel.IntProperty"); mbc.Model = 42; return true; }); mockDateTimeBinder .Setup(b => b.BindModel(context, It.IsAny<ModelBindingContext>())) .Returns((HttpActionContext ec, ModelBindingContext mbc) => { Assert.Equal(typeof(DateTime), mbc.ModelType); Assert.Equal("theModel.DateTimeProperty", mbc.ModelName); return false; }); ModelBindingContext parentBindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(() => dto, typeof(ComplexModelDto)), ModelName = "theModel", }; ComplexModelDtoModelBinder binder = new ComplexModelDtoModelBinder(); // Act bool retVal = binder.BindModel(context, parentBindingContext); // Assert Assert.True(retVal); Assert.Equal(dto, parentBindingContext.Model); ComplexModelDtoResult stringDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(string)).First()]; Assert.Equal("someStringValue", stringDtoResult.Model); Assert.Equal("theModel.StringProperty", stringDtoResult.ValidationNode.ModelStateKey); ComplexModelDtoResult intDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(int)).First()]; Assert.Equal(42, intDtoResult.Model); Assert.Equal("theModel.IntProperty", intDtoResult.ValidationNode.ModelStateKey); ComplexModelDtoResult dateTimeDtoResult = dto.Results[dto.PropertyMetadata.Where(m => m.ModelType == typeof(DateTime)).First()]; Assert.Null(dateTimeDtoResult); }
private static ModelValidationNode GetValidationNode() { EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider(); ModelMetadata metadata = provider.GetMetadataForType(null, typeof(object)); return new ModelValidationNode(metadata, "someKey"); }
public ControllerData(Type type) { var metadataProvider = new EmptyModelMetadataProvider(); this.Properties = (from p in type.GetProperties() let attr = p.GetCustomAttributes(typeof(FromRouteAttribute), inherit: true) .Cast<FromRouteAttribute>() .SingleOrDefault() where attr != null select new PropertyData( property: p, attribute: attr, metadata: metadataProvider.GetMetadataForType(null, p.PropertyType) )).ToArray(); }
public void SimpleDisplayTextReturnsEmptyStringForNonNullModelWithNoVisibleProperties() { // Arrange SimpleDisplayTextModelWithNoProperties model = new SimpleDisplayTextModelWithNoProperties(); EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider(); ModelMetadata metadata = new ModelMetadata(provider, null, () => model, typeof(SimpleDisplayTextModelWithNoProperties), null); // Act string result = metadata.SimpleDisplayText; // Assert Assert.Equal(String.Empty, result); }
public void SimpleDisplayTextReturnsFirstPropertyNullDisplayTextForNonNullModelWithNullDisplayColumnPropertyValue() { // Arrange SimpleDisplayTextModelWithoutToString model = new SimpleDisplayTextModelWithoutToString(); EmptyModelMetadataProvider propertyProvider = new EmptyModelMetadataProvider(); ModelMetadata propertyMetadata = propertyProvider.GetMetadataForProperty(() => model.FirstProperty, typeof(SimpleDisplayTextModelWithoutToString), "FirstProperty"); propertyMetadata.NullDisplayText = "Null Display Text"; Mock<ModelMetadataProvider> provider = new Mock<ModelMetadataProvider>(); provider.Setup(p => p.GetMetadataForProperties(model, typeof(SimpleDisplayTextModelWithoutToString))) .Returns(new[] { propertyMetadata }); ModelMetadata metadata = new ModelMetadata(provider.Object, null, () => model, typeof(SimpleDisplayTextModelWithoutToString), null); // Act string result = metadata.SimpleDisplayText; // Assert Assert.Equal(propertyMetadata.NullDisplayText, result); }
public void SimpleDisplayTextReturnsFirstPropertyValueForNonNullModel() { // Arrange SimpleDisplayTextModelWithoutToString model = new SimpleDisplayTextModelWithoutToString { FirstProperty = "First Property Value" }; EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider(); ModelMetadata metadata = new ModelMetadata(provider, null, () => model, typeof(SimpleDisplayTextModelWithoutToString), null); // Act string result = metadata.SimpleDisplayText; // Assert Assert.Equal(model.FirstProperty, result); }
public void SimpleDisplayTextReturnsToStringValueWhenOverridden() { // Arrange SimpleDisplayTextModelWithToString model = new SimpleDisplayTextModelWithToString(); EmptyModelMetadataProvider provider = new EmptyModelMetadataProvider(); ModelMetadata metadata = new ModelMetadata(provider, null, () => model, typeof(SimpleDisplayTextModelWithToString), null); // Act string result = metadata.SimpleDisplayText; // Assert Assert.Equal(model.ToString(), result); }
public void BindingUnboundedCollection_WithRecursiveRelation_ProducesSingleLengthCollection() { // Arrange string propertyName = "People"; ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty( modelAccessor: null, containerType: typeof(PeopleModel), propertyName: propertyName); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = modelMetadata, ModelName = propertyName, ValueProvider = new SimpleHttpValueProvider { { propertyName, "test value" } } }; HttpActionContext context = ContextUtil.CreateActionContext(); CollectionModelBinder<Person> binder = new CollectionModelBinder<Person>(); // Act bool result = binder.BindModel(context, bindingContext); // Assert Assert.True(result); List<Person> boundModel = Assert.IsType<List<Person>>(bindingContext.Model); Person type = Assert.Single(boundModel); Assert.Null(type.Name); }
public void BindingListsWithIndex_ProducesSingleLengthCollection_WithNullValues() { // Arrange string propertyName = "Addresses"; ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty( modelAccessor: null, containerType: typeof(UserWithAddress), propertyName: propertyName); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = modelMetadata, ModelName = propertyName, ValueProvider = new SimpleHttpValueProvider { { "Addresses.index", "10000" } } }; HttpActionContext context = ContextUtil.CreateActionContext(); CollectionModelBinder<UserWithAddress> binder = new CollectionModelBinder<UserWithAddress>(); // Act bool result = binder.BindModel(context, bindingContext); // Assert Assert.True(result); List<UserWithAddress> boundModel = Assert.IsType<List<UserWithAddress>>(bindingContext.Model); UserWithAddress listModel = Assert.Single(boundModel); Assert.Null(listModel); }
public void BindingNestedUnboundedCollection_WhenNoValuesArePresent_ProducesEmptyCollection() { // Arrange string propertyName = "Addresses"; ModelMetadata modelMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty( modelAccessor: null, containerType: typeof(UserWithAddress), propertyName: propertyName); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = modelMetadata, ModelName = propertyName, ValueProvider = new SimpleHttpValueProvider { { "Addresses.AddressLines", "some value" } } }; HttpActionContext context = ContextUtil.CreateActionContext(); CollectionModelBinder<UserWithAddress> binder = new CollectionModelBinder<UserWithAddress>(); // Act bool result = binder.BindModel(context, bindingContext); // Assert Assert.True(result); List<UserWithAddress> boundModel = Assert.IsType<List<UserWithAddress>>(bindingContext.Model); Assert.Empty(boundModel); }