public void ExecuteActionAsync_Faults_And_Traces_When_Inner_Faults() { // Arrange InvalidOperationException exception = new InvalidOperationException("test"); Mock <IActionFilter> mockFilter = new Mock <IActionFilter>() { CallBase = true }; TaskCompletionSource <HttpResponseMessage> tcs = new TaskCompletionSource <HttpResponseMessage>(null); tcs.TrySetException(exception); mockFilter.Setup(f => f.ExecuteActionFilterAsync(It.IsAny <HttpActionContext>(), It.IsAny <CancellationToken>(), It.IsAny <Func <Task <HttpResponseMessage> > >())).Returns(tcs.Task); Mock <HttpActionDescriptor> mockActionDescriptor = new Mock <HttpActionDescriptor>() { CallBase = true }; mockActionDescriptor.Setup(a => a.ActionName).Returns("test"); mockActionDescriptor.Setup(a => a.GetParameters()).Returns(new Collection <HttpParameterDescriptor>(new HttpParameterDescriptor[0])); HttpActionContext actionContext = ContextUtil.CreateActionContext(actionDescriptor: mockActionDescriptor.Object); TestTraceWriter traceWriter = new TestTraceWriter(); ActionFilterTracer tracer = new ActionFilterTracer(mockFilter.Object, traceWriter); Func <Task <HttpResponseMessage> > continuation = () => TaskHelpers.FromResult <HttpResponseMessage>(new HttpResponseMessage()); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ExecuteActionFilterAsync" }, new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Error) { Kind = TraceKind.End, Operation = "ExecuteActionFilterAsync" }, }; // Act Task <HttpResponseMessage> task = ((IActionFilter)tracer).ExecuteActionFilterAsync(actionContext, CancellationToken.None, continuation); // Assert Exception thrown = Assert.Throws <InvalidOperationException>(() => task.Wait()); Assert.Equal <TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); Assert.Same(exception, traceWriter.Traces[1].Exception); }
public void SetProperty_SettingNullableTypeToNull_RequiredValidatorPresent_PropertySetterThrows_AddsRequiredMessageString() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForObject(new ModelWhosePropertySetterThrows()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single( o => o.PropertyName == "Name" ); ModelValidationNode validationNode = new ModelValidationNode( propertyMetadata, "foo.Name" ); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult( null /* model */ , validationNode ); ModelValidator requiredValidator = context .GetValidators(propertyMetadata) .Where(v => v.IsRequired) .FirstOrDefault(); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic( context, bindingContext, propertyMetadata, dtoResult, requiredValidator ); // Assert Assert.False(bindingContext.ModelState.IsValid); ModelError modelError = Assert.Single(bindingContext.ModelState["foo.Name"].Errors); Assert.Equal( "This message comes from the [Required] attribute.", modelError.ErrorMessage ); }
public void ExecuteActionFilterAsync_Traces_Executing_And_Executed() { // Arrange Mock <ActionFilterAttribute> mockAttr = new Mock <ActionFilterAttribute>() { CallBase = true }; Mock <HttpActionDescriptor> mockActionDescriptor = new Mock <HttpActionDescriptor>() { CallBase = true }; mockActionDescriptor.Setup(a => a.ActionName).Returns("test"); mockActionDescriptor.Setup(a => a.GetParameters()).Returns(new Collection <HttpParameterDescriptor>(new HttpParameterDescriptor[0])); HttpActionContext actionContext = ContextUtil.CreateActionContext(actionDescriptor: mockActionDescriptor.Object); TestTraceWriter traceWriter = new TestTraceWriter(); ActionFilterAttributeTracer tracer = new ActionFilterAttributeTracer(mockAttr.Object, traceWriter); Func <Task <HttpResponseMessage> > continuation = () => TaskHelpers.FromResult <HttpResponseMessage>(new HttpResponseMessage()); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ActionExecuting" }, new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.End, Operation = "ActionExecuting" }, new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ActionExecuted" }, new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.End, Operation = "ActionExecuted" } }; // Act Task <HttpResponseMessage> task = ((IActionFilter)tracer).ExecuteActionFilterAsync(actionContext, CancellationToken.None, continuation); task.Wait(); // Assert Assert.Equal <TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); }
public void Validate_DoesNotUseOverridden_GetHashCodeOrEquals() { // Arrange ModelMetadataProvider metadataProvider = new DataAnnotationsModelMetadataProvider(); HttpActionContext actionContext = ContextUtil.CreateActionContext(); DefaultBodyModelValidator validator = new DefaultBodyModelValidator(); object instance = new[] { new TypeThatOverridesEquals { Funny = "hehe" }, new TypeThatOverridesEquals { Funny = "hehe" } }; // Act & Assert Assert.DoesNotThrow( () => validator.Validate(instance, typeof(TypeThatOverridesEquals[]), metadataProvider, actionContext, String.Empty)); }
public void ExcludedTypes_AreNotValidated() { // Arrange ModelMetadataProvider metadataProvider = new DataAnnotationsModelMetadataProvider(); HttpActionContext actionContext = ContextUtil.CreateActionContext(); Mock <DefaultBodyModelValidator> mockValidator = new Mock <DefaultBodyModelValidator>(); mockValidator.CallBase = true; mockValidator.Setup(validator => validator.ShouldValidateType(typeof(Person))).Returns(false); // Act mockValidator.Object.Validate(new Person(), typeof(Person), metadataProvider, actionContext, string.Empty); // Assert Assert.True(actionContext.ModelState.IsValid); }
public void ExecuteActionFilterAsync_IfContinuationParameterIsNull_ThrowsException() { var filter = new TestableActionFilter() as IActionFilter; Assert.ThrowsArgumentNull( () => { filter.ExecuteActionFilterAsync( actionContext: ContextUtil.CreateActionContext(), cancellationToken: CancellationToken.None, continuation: null ); }, "continuation" ); }
public HttpActionSelectorTracerTest() { _mockActionDescriptor = new Mock <HttpActionDescriptor>() { CallBase = true }; _mockActionDescriptor.Setup(a => a.ActionName).Returns("test"); _mockActionDescriptor.Setup(a => a.GetParameters()).Returns(new Collection <HttpParameterDescriptor>(new HttpParameterDescriptor[0])); _controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "controller", typeof(ApiController)); _controllerContext = ContextUtil.CreateControllerContext(request: new HttpRequestMessage()); _controllerContext.ControllerDescriptor = _controllerDescriptor; _actionContext = ContextUtil.CreateActionContext(_controllerContext, actionDescriptor: _mockActionDescriptor.Object); }
public void BindModel_SubBindingSucceeds() { // Arrange Mock <IModelBinder> mockIntBinder = new Mock <IModelBinder>(); Mock <IModelBinder> mockStringBinder = new Mock <IModelBinder>(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(KeyValuePair <int, string>)), ModelName = "someName", ValueProvider = new SimpleHttpValueProvider() }; HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.ServiceResolver.SetServices(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) { SuppressPrefixCheck = true }, new SimpleModelBinderProvider(typeof(string), mockStringBinder.Object) { SuppressPrefixCheck = true }); mockIntBinder .Setup(o => o.BindModel(context, It.IsAny <ModelBindingContext>())) .Returns((HttpActionContext cc, ModelBindingContext mbc) => { mbc.Model = 42; return(true); }); mockStringBinder .Setup(o => o.BindModel(context, It.IsAny <ModelBindingContext>())) .Returns((HttpActionContext cc, ModelBindingContext mbc) => { mbc.Model = "forty-two"; return(true); }); KeyValuePairModelBinder <int, string> binder = new KeyValuePairModelBinder <int, string>(); // Act bool retVal = binder.BindModel(context, bindingContext); // Assert Assert.True(retVal); Assert.Equal(new KeyValuePair <int, string>(42, "forty-two"), bindingContext.Model); Assert.Equal(new[] { "someName.key", "someName.value" }, bindingContext.ValidationNode.ChildNodes.Select(n => n.ModelStateKey).ToArray()); }
public void BindModel_SuccessfulBind_RunsValidationAndReturnsModel() { // Arrange HttpActionContext actionContext = ContextUtil.CreateActionContext(GetHttpControllerContext()); bool validationCalled = false; ModelBindingContext bindingContext = new ModelBindingContext { FallbackToEmptyPrefix = true, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType(null, typeof(int)), ModelName = "someName", //ModelState = executionContext.Controller.ViewData.ModelState, //PropertyFilter = _ => true, ValueProvider = new SimpleValueProvider { { "someName", "dummyValue" } } }; Mock <IModelBinder> mockIntBinder = new Mock <IModelBinder>(); mockIntBinder .Setup(o => o.BindModel(actionContext, It.IsAny <ModelBindingContext>())) .Returns( delegate(HttpActionContext cc, ModelBindingContext mbc) { Assert.Same(bindingContext.ModelMetadata, mbc.ModelMetadata); Assert.Equal("someName", mbc.ModelName); Assert.Same(bindingContext.ValueProvider, mbc.ValueProvider); mbc.Model = 42; mbc.ValidationNode.Validating += delegate { validationCalled = true; }; return(true); }); //binderProviders.RegisterBinderForType(typeof(int), mockIntBinder.Object, false /* suppressPrefixCheck */); IModelBinder shimBinder = new CompositeModelBinder(mockIntBinder.Object); // Act bool isBound = shimBinder.BindModel(actionContext, bindingContext); // Assert Assert.True(isBound); Assert.Equal(42, bindingContext.Model); Assert.True(validationCalled); Assert.True(bindingContext.ModelState.IsValid); }
public void BindModel() { // Arrange Mock <IValueProvider> mockValueProvider = new Mock <IValueProvider>(); mockValueProvider.Setup(o => o.ContainsPrefix(It.IsAny <string>())).Returns(true); Mock <IModelBinder> mockDtoBinder = new Mock <IModelBinder>(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForObject(new Person()), ModelName = "someName", ValueProvider = mockValueProvider.Object }; HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.Services.Replace(typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(ComplexModelDto), mockDtoBinder.Object) { SuppressPrefixCheck = true }); mockDtoBinder .Setup(o => o.BindModel(context, It.IsAny <ModelBindingContext>())) .Returns((HttpActionContext cc, ModelBindingContext mbc2) => { return(true); // just return the DTO unchanged }); Mock <TestableMutableObjectModelBinder> mockTestableBinder = new Mock <TestableMutableObjectModelBinder> { CallBase = true }; mockTestableBinder.Setup(o => o.EnsureModelPublic(context, bindingContext)).Verifiable(); mockTestableBinder.Setup(o => o.GetMetadataForPropertiesPublic(context, bindingContext)).Returns(new ModelMetadata[0]).Verifiable(); TestableMutableObjectModelBinder testableBinder = mockTestableBinder.Object; testableBinder.MetadataProvider = new DataAnnotationsModelMetadataProvider(); // Act bool retValue = testableBinder.BindModel(context, bindingContext); // Assert Assert.True(retValue); Assert.IsType <Person>(bindingContext.Model); Assert.True(bindingContext.ValidationNode.ValidateAllProperties); mockTestableBinder.Verify(); }
public void ProcessDto_RequiredFieldMissing_RaisesModelError() { // Arrange ModelWithRequired model = new ModelWithRequired(); ModelMetadata containerMetadata = GetMetadataForObject(model); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; // Set no properties though Age (a non-Nullable struct) and City (a class) properties are required. ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessDto(context, bindingContext, dto); // Assert ModelStateDictionary modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(2, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); ModelError modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The Age field is required.", modelError.ErrorMessage); // Check City error. Assert.True(modelStateDictionary.TryGetValue("theModel.City", out modelState)); Assert.Equal(1, modelState.Errors.Count); modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The City field is required.", modelError.ErrorMessage); }
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 async Task ExecuteActionFilterAsync_IfContinuationFaulted_InvokesOnActionExecutedAsError() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); Mock <ActionFilterAttribute> filterMock = new Mock <ActionFilterAttribute>() { CallBase = true, }; var filter = (IActionFilter)filterMock.Object; Exception exception = new Exception("{ABCC912C-B6D1-4C27-9059-732ABC644A0C}"); Func <Task <HttpResponseMessage> > continuation = () => TaskHelpers.FromError <HttpResponseMessage>(exception); // Act & Assert await Assert.ThrowsAsync <Exception>( () => filter.ExecuteActionFilterAsync(context, CancellationToken.None, continuation) ); // Assert filterMock.Verify( f => f.OnActionExecuted( It.Is <HttpActionExecutedContext>( ec => Object.ReferenceEquals(ec.Exception, exception) && ec.Response == null && Object.ReferenceEquals(ec.ActionContext, context) ) ) ); filterMock.Verify( f => f.OnActionExecutedAsync( It.Is <HttpActionExecutedContext>( ec => Object.ReferenceEquals(ec.Exception, exception) && ec.Response == null && Object.ReferenceEquals(ec.ActionContext, context) ), It.IsAny <CancellationToken>() ) ); }
public HttpActionInvokerTracerTest() { UsersController controller = new UsersController(); _apiController = controller; Func <HttpResponseMessage> actionMethod = controller.Get; _actionContext = ContextUtil.CreateActionContext( ContextUtil.CreateControllerContext(instance: _apiController), new ReflectedHttpActionDescriptor { MethodInfo = actionMethod.Method }); HttpRequestMessage request = new HttpRequestMessage(); _actionContext.ControllerContext.Request = request; }
public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorPresent_AddsModelError() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = GetMetadataForObject(new Person()), ModelName = "foo" }; ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single( o => o.PropertyName == "ValueTypeRequired" ); ModelValidationNode validationNode = new ModelValidationNode( propertyMetadata, "foo.ValueTypeRequired" ); ComplexModelDtoResult dtoResult = new ComplexModelDtoResult( null /* model */ , validationNode ); ModelValidator requiredValidator = context .GetValidators(propertyMetadata) .Where(v => v.IsRequired) .FirstOrDefault(); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.SetPropertyPublic( context, bindingContext, propertyMetadata, dtoResult, requiredValidator ); // Assert Assert.False(bindingContext.ModelState.IsValid); Assert.Equal( "Sample message", bindingContext.ModelState["foo.ValueTypeRequired"].Errors[0].ErrorMessage ); }
public void BindModel() { // Arrange Mock <IModelBinder> mockIntBinder = new Mock <IModelBinder>(); HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.Services.Replace( typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) ); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType( null, typeof(int[]) ), ModelName = "someName", ValueProvider = new SimpleHttpValueProvider { { "someName[0]", "42" }, { "someName[1]", "84" } } }; mockIntBinder .Setup(o => o.BindModel(context, It.IsAny <ModelBindingContext>())) .Returns( (HttpActionContext ec, ModelBindingContext mbc) => { mbc.Model = mbc.ValueProvider .GetValue(mbc.ModelName) .ConvertTo(mbc.ModelType); return(true); } ); // Act bool retVal = new ArrayModelBinder <int>().BindModel(context, bindingContext); // Assert Assert.True(retVal); int[] array = bindingContext.Model as int[]; Assert.Equal(new[] { 42, 84 }, array); }
public async Task InvokeActionWithActionFilters_ChainsFiltersInOrderFollowedByInnerActionContinuation() { // Arrange HttpActionContext actionContextInstance = ContextUtil.CreateActionContext(); List <string> log = new List <string>(); Mock <IActionFilter> globalFilterMock = CreateActionFilterMock( (ctx, ct, continuation) => { log.Add("globalFilter"); return(continuation()); } ); Mock <IActionFilter> actionFilterMock = CreateActionFilterMock( (ctx, ct, continuation) => { log.Add("actionFilter"); return(continuation()); } ); Func <Task <HttpResponseMessage> > innerAction = () => Task <HttpResponseMessage> .Factory.StartNew( () => { log.Add("innerAction"); return(null); } ); var filters = new IActionFilter[] { globalFilterMock.Object, actionFilterMock.Object, }; // Act var result = ActionFilterResult.InvokeActionWithActionFilters( actionContextInstance, CancellationToken.None, filters, innerAction ); // Assert Assert.NotNull(result); await result(); Assert.Equal(new[] { "globalFilter", "actionFilter", "innerAction" }, log.ToArray()); globalFilterMock.Verify(); actionFilterMock.Verify(); }
public void ProcessDto_RequiredFieldNull_RaisesModelError() { // Arrange ModelWithRequired model = new ModelWithRequired(); ModelMetadata containerMetadata = GetMetadataForObject(model); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Make Age valid and City invalid. ModelMetadata propertyMetadata = dto.PropertyMetadata.Single(p => p.PropertyName == "Age"); dto.Results[propertyMetadata] = new ComplexModelDtoResult(23, new ModelValidationNode(propertyMetadata, "theModel.Age")); propertyMetadata = dto.PropertyMetadata.Single(p => p.PropertyName == "City"); dto.Results[propertyMetadata] = new ComplexModelDtoResult(null, new ModelValidationNode(propertyMetadata, "theModel.City")); // Act testableBinder.ProcessDto(context, bindingContext, dto); // Assert ModelStateDictionary modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check City error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.City", out modelState)); Assert.Equal(1, modelState.Errors.Count); ModelError modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The City field is required.", modelError.ErrorMessage); }
public void ProcessDto_BindRequiredFieldMissing_RaisesModelError() { // Arrange ModelWithBindRequired model = new ModelWithBindRequired { Name = "original value", Age = -20 }; ModelMetadata containerMetadata = GetMetadataForObject(model); HttpActionContext context = ContextUtil.CreateActionContext(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = containerMetadata, ModelName = "theModel" }; ComplexModelDto dto = new ComplexModelDto(containerMetadata, containerMetadata.Properties); ModelMetadata nameProperty = dto.PropertyMetadata.Single(o => o.PropertyName == "Name"); dto.Results[nameProperty] = new ComplexModelDtoResult("John Doe", new ModelValidationNode(nameProperty, "")); TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder(); // Act testableBinder.ProcessDto(context, bindingContext, dto); // Assert ModelStateDictionary modelStateDictionary = bindingContext.ModelState; Assert.False(modelStateDictionary.IsValid); Assert.Equal(1, modelStateDictionary.Count); // Check Age error. ModelState modelState; Assert.True(modelStateDictionary.TryGetValue("theModel.Age", out modelState)); Assert.Equal(1, modelState.Errors.Count); ModelError modelError = modelState.Errors[0]; Assert.Null(modelError.Exception); Assert.NotNull(modelError.ErrorMessage); Assert.Equal("The Age property is required.", modelError.ErrorMessage); }
public BindModel() { actionContext = ContextUtil.CreateActionContext(); binder = new PaginationBinder <StubPagination>(); var data = new DataAnnotationsModelMetadataProvider(); var modelMetadata = data.GetMetadataForType(null, typeof(IPagination)); mockValueProvider = new Mock <IValueProvider>(); bindingContext = new ModelBindingContext { ModelName = modelName, ValueProvider = mockValueProvider.Object, ModelMetadata = modelMetadata, }; }
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 <HttpParameterBinding> mockBinding = new Mock <HttpParameterBinding>(mockParamDescriptor.Object) { 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(); 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.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 async Task ExecuteActionAsync_Traces_ExecuteActionFilterAsync() { // Arrange HttpResponseMessage response = new HttpResponseMessage(); Mock <IActionFilter> mockFilter = new Mock <IActionFilter>() { CallBase = true }; mockFilter.Setup( f => f.ExecuteActionFilterAsync(It.IsAny <HttpActionContext>(), It.IsAny <CancellationToken>(), It.IsAny <Func <Task <HttpResponseMessage> > >())).Returns( Task.FromResult <HttpResponseMessage>(response)); Mock <HttpActionDescriptor> mockActionDescriptor = new Mock <HttpActionDescriptor>() { CallBase = true }; mockActionDescriptor.Setup(a => a.ActionName).Returns("test"); mockActionDescriptor.Setup(a => a.GetParameters()).Returns(new Collection <HttpParameterDescriptor>(new HttpParameterDescriptor[0])); HttpActionContext actionContext = ContextUtil.CreateActionContext(actionDescriptor: mockActionDescriptor.Object); TestTraceWriter traceWriter = new TestTraceWriter(); ActionFilterTracer tracer = new ActionFilterTracer(mockFilter.Object, traceWriter); Func <Task <HttpResponseMessage> > continuation = () => Task.FromResult <HttpResponseMessage>(new HttpResponseMessage()); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "ExecuteActionFilterAsync" }, new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.End, Operation = "ExecuteActionFilterAsync" }, }; // Act var filter = (IActionFilter)tracer; await filter.ExecuteActionFilterAsync(actionContext, CancellationToken.None, continuation); // Assert Assert.Equal <TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); }
public void BindModel_UnsuccessfulBind_SimpleTypeNoFallback_ReturnsNull() { // Arrange HttpActionContext actionContext = ContextUtil.CreateActionContext( GetHttpControllerContext() ); Mock <ModelBinderProvider> mockBinderProvider = new Mock <ModelBinderProvider>(); mockBinderProvider .Setup(o => o.GetBinder(It.IsAny <HttpConfiguration>(), It.IsAny <Type>())) .Returns((IModelBinder)null) .Verifiable(); List <ModelBinderProvider> binderProviders = new List <ModelBinderProvider>() { mockBinderProvider.Object }; CompositeModelBinderProvider shimBinderProvider = new CompositeModelBinderProvider( binderProviders ); CompositeModelBinder shimBinder = new CompositeModelBinder( shimBinderProvider.GetBinder(null, null) ); ModelBindingContext bindingContext = new ModelBindingContext { FallbackToEmptyPrefix = true, ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType( null, typeof(int) ), //ModelState = executionContext.Controller.ViewData.ModelState }; // Act bool isBound = shimBinder.BindModel(actionContext, bindingContext); // Assert Assert.False(isBound); Assert.Null(bindingContext.Model); Assert.True(bindingContext.ModelState.IsValid); mockBinderProvider.Verify(); mockBinderProvider.Verify( o => o.GetBinder(It.IsAny <HttpConfiguration>(), It.IsAny <Type>()), Times.AtMostOnce() ); }
public void NullCheckFailedHandler_ModelStateValid_AddsErrorString() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); ModelMetadata modelMetadata = GetMetadataForType(typeof(Person)); ModelValidationNode validationNode = new ModelValidationNode(modelMetadata, "foo"); ModelValidatedEventArgs e = new ModelValidatedEventArgs(context, null /* parentNode */); // Act EventHandler <ModelValidatedEventArgs> handler = MutableObjectModelBinder.CreateNullCheckFailedHandler(modelMetadata, null /* incomingValue */); handler(validationNode, e); // Assert Assert.True(context.ModelState.ContainsKey("foo")); Assert.Equal("A value is required.", context.ModelState["foo"].Errors[0].ErrorMessage); }
public void BindModel_SimpleCollection() { // Arrange CultureInfo culture = CultureInfo.GetCultureInfo("fr-FR"); Mock <IModelBinder> mockIntBinder = new Mock <IModelBinder>(); ModelBindingContext bindingContext = new ModelBindingContext { ModelMetadata = new EmptyModelMetadataProvider().GetMetadataForType( null, typeof(int) ), ModelName = "someName", ValueProvider = new SimpleHttpValueProvider { { "someName", new[] { "42", "100", "200" } } } }; HttpActionContext context = ContextUtil.CreateActionContext(); context.ControllerContext.Configuration.Services.Replace( typeof(ModelBinderProvider), new SimpleModelBinderProvider(typeof(int), mockIntBinder.Object) ); mockIntBinder .Setup(o => o.BindModel(context, It.IsAny <ModelBindingContext>())) .Returns( (HttpActionContext ec, ModelBindingContext mbc) => { mbc.Model = mbc.ValueProvider .GetValue(mbc.ModelName) .ConvertTo(mbc.ModelType); return(true); } ); CollectionModelBinder <int> modelBinder = new CollectionModelBinder <int>(); // Act bool retVal = modelBinder.BindModel(context, bindingContext); // Assert Assert.True(retVal); Assert.Equal(new[] { 42, 100, 200 }, ((List <int>)bindingContext.Model).ToArray()); }
public async Task ExecuteActionFilterAsync_Faults_And_Traces_When_OnExecuting_Faults() { // Arrange Mock <ActionFilterAttribute> mockAttr = new Mock <ActionFilterAttribute>() { CallBase = true }; InvalidOperationException exception = new InvalidOperationException("test"); mockAttr.Setup(a => a.OnActionExecuting(It.IsAny <HttpActionContext>())).Throws(exception); Mock <HttpActionDescriptor> mockActionDescriptor = new Mock <HttpActionDescriptor>() { CallBase = true }; mockActionDescriptor.Setup(a => a.ActionName).Returns("test"); mockActionDescriptor.Setup(a => a.GetParameters()).Returns(new Collection <HttpParameterDescriptor>(new HttpParameterDescriptor[0])); HttpActionContext actionContext = ContextUtil.CreateActionContext(actionDescriptor: mockActionDescriptor.Object); TestTraceWriter traceWriter = new TestTraceWriter(); IActionFilter tracer = new ActionFilterAttributeTracer(mockAttr.Object, traceWriter) as IActionFilter; Func <Task <HttpResponseMessage> > continuation = () => Task.FromResult <HttpResponseMessage>(new HttpResponseMessage()); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Info) { Kind = TraceKind.Begin, Operation = "OnActionExecutingAsync" }, new TraceRecord(actionContext.Request, TraceCategories.FiltersCategory, TraceLevel.Error) { Kind = TraceKind.End, Operation = "OnActionExecutingAsync" } }; // Act Task <HttpResponseMessage> task = tracer.ExecuteActionFilterAsync(actionContext, CancellationToken.None, continuation); // Assert Exception thrown = await Assert.ThrowsAsync <InvalidOperationException>(() => task); Assert.Same(exception, thrown); Assert.Same(exception, traceWriter.Traces[1].Exception); Assert.Equal <TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); }
public void ExecuteAsync_Faults_And_Traces_When_Inner_Faults() { // Arrange InvalidOperationException exception = new InvalidOperationException(); TaskCompletionSource <HttpResponseMessage> tcs = new TaskCompletionSource <HttpResponseMessage>(); tcs.TrySetException(exception); Mock <ApiController> mockController = new Mock <ApiController>() { CallBase = true }; mockController.Setup(b => b.ExecuteAsync(It.IsAny <HttpControllerContext>(), It.IsAny <CancellationToken>())).Returns(tcs.Task); HttpRequestMessage request = new HttpRequestMessage(); HttpControllerContext controllerContext = ContextUtil.CreateControllerContext(request: request); controllerContext.ControllerDescriptor = _controllerDescriptor; controllerContext.Controller = mockController.Object; HttpActionContext actionContext = ContextUtil.CreateActionContext(controllerContext, actionDescriptor: _mockActionDescriptor.Object); TestTraceWriter traceWriter = new TestTraceWriter(); HttpControllerTracer tracer = new HttpControllerTracer(request, mockController.Object, traceWriter); TraceRecord[] expectedTraces = new TraceRecord[] { new TraceRecord(actionContext.Request, TraceCategories.ControllersCategory, TraceLevel.Info) { Kind = TraceKind.Begin }, new TraceRecord(actionContext.Request, TraceCategories.ControllersCategory, TraceLevel.Error) { Kind = TraceKind.End } }; // Act Exception thrown = Assert.Throws <InvalidOperationException>(() => ((IHttpController)tracer).ExecuteAsync(controllerContext, CancellationToken.None).Wait()); // Assert Assert.Equal <TraceRecord>(expectedTraces, traceWriter.Traces, new TraceRecordComparer()); Assert.Same(exception, thrown); Assert.Same(exception, traceWriter.Traces[1].Exception); }
public async Task ExecuteAsync_IfInnerResultTaskIsFaulted_ExecutesFiltersAndReturnsFaultedTaskIfNotHandled() { // Arrange List <string> log = new List <string>(); HttpActionContext actionContext = ContextUtil.CreateActionContext(); Exception exceptionSeenByFilter = null; var exceptionFilter = CreateExceptionFilter( (ec, ct) => { exceptionSeenByFilter = ec.Exception; log.Add("exceptionFilter"); return(Task.Factory.StartNew(() => { })); } ); var filters = new IExceptionFilter[] { exceptionFilter }; IExceptionLogger exceptionLogger = CreateExceptionLogger( (c, i) => { log.Add("exceptionLogger"); return(Task.FromResult(0)); } ); IExceptionHandler exceptionHandler = CreateStubExceptionHandler(); var expectedException = new Exception(); var actionResult = CreateStubActionResult( TaskHelpers.FromError <HttpResponseMessage>(expectedException) ); IHttpActionResult product = CreateProductUnderTest( actionContext, filters, exceptionLogger, exceptionHandler, actionResult ); // Act & Assert var exception = await Assert.ThrowsAsync <Exception>( () => product.ExecuteAsync(CancellationToken.None) ); Assert.Same(expectedException, exception); Assert.Same(expectedException, exceptionSeenByFilter); Assert.Equal(new string[] { "exceptionLogger", "exceptionFilter" }, log.ToArray()); }
public async Task ExecuteAuthorizationFilterAsync_IfContinuationSucceeded_ReturnsSuccessTask() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); Mock <AuthorizationFilterAttribute> filterMock = new Mock <AuthorizationFilterAttribute>() { CallBase = true, }; var filter = (IAuthorizationFilter)filterMock.Object; HttpResponseMessage expectedResponse = new HttpResponseMessage(); // Act var response = await filter.ExecuteAuthorizationFilterAsync(context, CancellationToken.None, () => Task.FromResult(expectedResponse)); // Assert Assert.Same(expectedResponse, response); }
public void ExecuteActionFilterAsync_IfContinuationTaskWasCanceled_ReturnsCanceledTask() { // Arrange HttpActionContext context = ContextUtil.CreateActionContext(); Mock <ActionFilterAttribute> filterMock = new Mock <ActionFilterAttribute>() { CallBase = true, }; var filter = (IActionFilter)filterMock.Object; // Act var result = filter.ExecuteActionFilterAsync(context, CancellationToken.None, () => TaskHelpers.Canceled <HttpResponseMessage>()); // Assert result.WaitUntilCompleted(); Assert.True(result.IsCanceled); }