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>();
            LoggingDataErrorInfoModel model         = new LoggingDataErrorInfoModel(log);
            ModelMetadata             modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey");

            ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "ValidStringProperty");

            node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.ValidStringProperty"));

            node.Validating += delegate { log.Add("In OnValidating()"); };
            node.Validated  += delegate { log.Add("In OnValidated()"); };

            // Act
            node.Validate(controllerContext);

            // Assert
            Assert.Equal(new[] { "In OnValidating()", "In IDataErrorInfo.get_Item('ValidStringProperty')", "In IDataErrorInfo.get_Error()", "In OnValidated()" }, log.ToArray());
        }
        public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorNotPresent_RegistersValidationCallback()
        {
            // Arrange
            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = GetMetadataForObject(new Person()),
            };

            ModelMetadata         propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth");
            ModelValidationNode   validationNode   = new ModelValidationNode(propertyMetadata, "foo");
            ComplexModelDtoResult dtoResult        = new ComplexModelDtoResult(null /* model */, validationNode);

            TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder();

            // Act
            testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult);

            // Assert
            Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid);
            validationNode.Validate(controllerContext, bindingContext.ValidationNode);
            Assert.False(controllerContext.Controller.ViewData.ModelState.IsValid);
        }
        public void Validate_SkipsRemainingValidationIfModelStateIsInvalid()
        {
            // Because a property validator fails, the model validator shouldn't run

            // Arrange
            List <string>             log           = new List <string>();
            LoggingDataErrorInfoModel model         = new LoggingDataErrorInfoModel(log);
            ModelMetadata             modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey");

            ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "InvalidStringProperty");

            node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.InvalidStringProperty"));

            node.Validating += delegate { log.Add("In OnValidating()"); };
            node.Validated  += delegate { log.Add("In OnValidated()"); };

            // Act
            node.Validate(controllerContext);

            // Assert
            Assert.Equal(new[] { "In OnValidating()", "In IDataErrorInfo.get_Item('InvalidStringProperty')", "In OnValidated()" }, log.ToArray());
            Assert.Equal("Sample error message", controllerContext.Controller.ViewData.ModelState["theKey.InvalidStringProperty"].Errors[0].ErrorMessage);
        }
        internal static bool ValidateObject(object o, List <ValidationResultInfo> validationErrors, HttpActionContext actionContext)
        {
            // create a model validation node for the object
            ModelMetadataProvider metadataProvider = actionContext.GetMetadataProvider();
            string modelStateKey = String.Empty;
            ModelValidationNode validationNode = CreateModelValidationNode(o, metadataProvider, actionContext.ModelState, modelStateKey);

            validationNode.ValidateAllProperties = true;

            // add the node to model state
            ModelState modelState = new ModelState();

            modelState.Value = new ValueProviderResult(o, String.Empty, CultureInfo.CurrentCulture);
            actionContext.ModelState.Add(modelStateKey, modelState);

            // invoke validation
            validationNode.Validate(actionContext);

            if (!actionContext.ModelState.IsValid)
            {
                foreach (var modelStateItem in actionContext.ModelState)
                {
                    foreach (ModelError modelError in modelStateItem.Value.Errors)
                    {
                        validationErrors.Add(new ValidationResultInfo(modelError.ErrorMessage, new string[] { modelStateItem.Key }));
                    }
                }
            }

            return(actionContext.ModelState.IsValid);
        }
        public void Validate_SkipsValidationIfSuppressed()
        {
            // Arrange
            List <string>             log           = new List <string>();
            LoggingDataErrorInfoModel model         = new LoggingDataErrorInfoModel(log);
            ModelMetadata             modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey")
            {
                SuppressValidation = true
            };

            node.Validating += (sender, e) => { log.Add("In OnValidating()"); };
            node.Validated  += delegate { log.Add("In OnValidated()"); };

            // Act
            node.Validate(controllerContext);

            // Assert
            Assert.Empty(log);
        }
        public void Validate_SkipsValidationIfHandlerCancels()
        {
            // Arrange
            List <string>             log           = new List <string>();
            LoggingDataErrorInfoModel model         = new LoggingDataErrorInfoModel(log);
            ModelMetadata             modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey");

            node.Validating += (sender, e) =>
            {
                log.Add("In OnValidating()");
                e.Cancel = true;
            };
            node.Validated += delegate { log.Add("In OnValidated()"); };

            // Act
            node.Validate(controllerContext);

            // Assert
            Assert.Equal(new[] { "In OnValidating()" }, log.ToArray());
        }
        public void Validate_ValidateAllProperties_AddsValidationErrors()
        {
            // Arrange
            ValidateAllPropertiesModel model = new ValidateAllPropertiesModel
            {
                RequiredString = null /* error */,
                RangedInt      = 0 /* error */,
                ValidString    = "dog"
            };

            ModelMetadata     modelMetadata     = GetModelMetadata(model);
            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey")
            {
                ValidateAllProperties = true
            };

            controllerContext.Controller.ViewData.ModelState.AddModelError("theKey.RequiredString.Dummy", "existing Error Text");

            // Act
            node.Validate(controllerContext);

            // Assert
            Assert.Null(controllerContext.Controller.ViewData.ModelState["theKey.RequiredString"]);
            Assert.Equal("existing Error Text", controllerContext.Controller.ViewData.ModelState["theKey.RequiredString.Dummy"].Errors[0].ErrorMessage);
            Assert.Equal("The field RangedInt must be between 10 and 30.", controllerContext.Controller.ViewData.ModelState["theKey.RangedInt"].Errors[0].ErrorMessage);
            Assert.Null(controllerContext.Controller.ViewData.ModelState["theKey.ValidString"]);
            Assert.Null(controllerContext.Controller.ViewData.ModelState["theKey"]);
        }
        public void CombineWith()
        {
            // Arrange
            List <string> log = new List <string>();

            ModelValidationNode[] allChildNodes = new[]
            {
                new ModelValidationNode(GetModelMetadata(), "key1"),
                new ModelValidationNode(GetModelMetadata(), "key2"),
                new ModelValidationNode(GetModelMetadata(), "key3"),
            };

            ModelValidationNode parentNode1 = new ModelValidationNode(GetModelMetadata(), "parent1");

            parentNode1.ChildNodes.Add(allChildNodes[0]);
            parentNode1.Validating += delegate { log.Add("Validating parent1."); };
            parentNode1.Validated  += delegate { log.Add("Validated parent1."); };

            ModelValidationNode parentNode2 = new ModelValidationNode(GetModelMetadata(), "parent2");

            parentNode2.ChildNodes.Add(allChildNodes[1]);
            parentNode2.ChildNodes.Add(allChildNodes[2]);
            parentNode2.Validating += delegate { log.Add("Validating parent2."); };
            parentNode2.Validated  += delegate { log.Add("Validated parent2."); };

            // Act
            parentNode1.CombineWith(parentNode2);
            parentNode1.Validate(new ControllerContext {
                Controller = new EmptyController()
            });

            // Assert
            Assert.Equal(new[] { "Validating parent1.", "Validating parent2.", "Validated parent1.", "Validated parent2." }, log.ToArray());
            Assert.Equal(allChildNodes, parentNode1.ChildNodes.ToArray());
        }
Esempio n. 9
0
        public void SetProperty_PropertyIsSettable_CallsSetter()
        {
            // Arrange
            Person              model          = new Person();
            HttpActionContext   context        = ContextUtil.CreateActionContext();
            ModelBindingContext bindingContext = new ModelBindingContext
            {
                ModelMetadata = GetMetadataForObject(model)
            };

            ModelMetadata         propertyMetadata  = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth");
            ModelValidationNode   validationNode    = new ModelValidationNode(propertyMetadata, "foo");
            ComplexModelDtoResult dtoResult         = new ComplexModelDtoResult(new DateTime(2001, 1, 1), validationNode);
            ModelValidator        requiredValidator = context.GetValidators(propertyMetadata).Where(v => v.IsRequired).FirstOrDefault();

            TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder();

            // Act
            testableBinder.SetPropertyPublic(context, bindingContext, propertyMetadata, dtoResult, requiredValidator);

            // Assert
            validationNode.Validate(context);
            Assert.True(context.ModelState.IsValid);
            Assert.Equal(new DateTime(2001, 1, 1), model.DateOfBirth);
        }
        public void SetProperty_PropertyIsSettable_CallsSetter()
        {
            // Arrange
            Person            model             = new Person();
            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = GetMetadataForObject(model)
            };

            ModelMetadata         propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth");
            ModelValidationNode   validationNode   = new ModelValidationNode(propertyMetadata, "foo");
            ComplexModelDtoResult dtoResult        = new ComplexModelDtoResult(new DateTime(2001, 1, 1), validationNode);

            TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder();

            // Act
            testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult);

            // Assert
            validationNode.Validate(controllerContext);
            Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid);
            Assert.Equal(new DateTime(2001, 1, 1), model.DateOfBirth);
        }
Esempio n. 11
0
        public virtual bool TryValidateModel([NotNull] object model, string prefix)
        {
            if (BindingContext == null)
            {
                var message = Resources.FormatPropertyOfTypeCannotBeNull(
                    nameof(BindingContext),
                    typeof(Controller).FullName);
                throw new InvalidOperationException(message);
            }

            var modelMetadata = MetadataProvider.GetMetadataForType(
                modelAccessor: () => model,
                modelType: model.GetType());

            var validationContext = new ModelValidationContext(
                MetadataProvider,
                BindingContext.ValidatorProvider,
                ModelState,
                modelMetadata,
                containerMetadata: null);

            var modelName = prefix ?? string.Empty;

            var validationNode = new ModelValidationNode(modelMetadata, modelName)
            {
                ValidateAllProperties = true
            };

            validationNode.Validate(validationContext);

            return(ModelState.IsValid);
        }
        public void Validate_PassesNullContainerInstanceIfCannotBeConvertedToProperType()
        {
            // Arrange
            List <string>             log1           = new List <string>();
            LoggingDataErrorInfoModel model1         = new LoggingDataErrorInfoModel(log1);
            ModelMetadata             modelMetadata1 = GetModelMetadata(model1);

            List <string>             log2           = new List <string>();
            LoggingDataErrorInfoModel model2         = new LoggingDataErrorInfoModel(log2);
            ModelMetadata             modelMetadata2 = GetModelMetadata(model2);

            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata1, "theKey");

            node.ChildNodes.Add(new ModelValidationNode(modelMetadata2, "theKey.SomeProperty"));

            // Act
            node.Validate(controllerContext);

            // Assert
            Assert.Equal(new[] { "In IDataErrorInfo.get_Error()" }, log1.ToArray());
            Assert.Equal(new[] { "In IDataErrorInfo.get_Error()" }, log2.ToArray());
        }
        public void Validate_ThrowsIfControllerContextIsNull()
        {
            // Arrange
            ModelValidationNode node = new ModelValidationNode(GetModelMetadata(), "someKey");

            // Act & assert
            Assert.ThrowsArgumentNull(
                delegate { node.Validate(null); }, "controllerContext");
        }
        public void CombineWith_OtherNodeIsSuppressed_DoesNothing()
        {
            // Arrange
            List <string> log = new List <string>();

            ModelValidationNode[] allChildNodes = new ModelValidationNode[] {
                new ModelValidationNode(GetModelMetadata(), "key1"),
                new ModelValidationNode(GetModelMetadata(), "key2"),
                new ModelValidationNode(GetModelMetadata(), "key3"),
            };

            ModelValidationNode[] expectedChildNodes = new ModelValidationNode[] {
                allChildNodes[0]
            };

            ModelValidationNode parentNode1 = new ModelValidationNode(GetModelMetadata(), "parent1");

            parentNode1.ChildNodes.Add(allChildNodes[0]);
            parentNode1.Validating += delegate { log.Add("Validating parent1."); };
            parentNode1.Validated  += delegate { log.Add("Validated parent1."); };

            ModelValidationNode parentNode2 = new ModelValidationNode(GetModelMetadata(), "parent2");

            parentNode2.ChildNodes.Add(allChildNodes[1]);
            parentNode2.ChildNodes.Add(allChildNodes[2]);
            parentNode2.Validating        += delegate { log.Add("Validating parent2."); };
            parentNode2.Validated         += delegate { log.Add("Validated parent2."); };
            parentNode2.SuppressValidation = true;

            // Act
            parentNode1.CombineWith(parentNode2);
            parentNode1.Validate(new ControllerContext()
            {
                Controller = new EmptyController()
            });

            // Assert
            CollectionAssert.AreEqual(
                new string[] { "Validating parent1.", "Validated parent1." },
                log);
            CollectionAssert.AreEqual(expectedChildNodes, parentNode1.ChildNodes.ToArray());
        }
        public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorNotPresent_RegistersValidationCallback()
        {
            // Arrange
            HttpActionContext   context        = ContextUtil.CreateActionContext();
            ModelBindingContext bindingContext = new ModelBindingContext
            {
                ModelMetadata = GetMetadataForObject(new Person()),
            };

            ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(
                o => o.PropertyName == "DateOfBirth"
                );
            ModelValidationNode   validationNode = new ModelValidationNode(propertyMetadata, "foo");
            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.True(context.ModelState.IsValid);
            validationNode.Validate(context, bindingContext.ValidationNode);
            Assert.False(context.ModelState.IsValid);
        }
        public void Validate_PassesNullContainerInstanceIfCannotBeConvertedToProperType() {
            // Arrange
            List<string> log1 = new List<string>();
            LoggingDataErrorInfoModel model1 = new LoggingDataErrorInfoModel(log1);
            ModelMetadata modelMetadata1 = GetModelMetadata(model1);

            List<string> log2 = new List<string>();
            LoggingDataErrorInfoModel model2 = new LoggingDataErrorInfoModel(log2);
            ModelMetadata modelMetadata2 = GetModelMetadata(model2);

            ControllerContext controllerContext = new ControllerContext() {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata1, "theKey");
            node.ChildNodes.Add(new ModelValidationNode(modelMetadata2, "theKey.SomeProperty"));

            // Act
            node.Validate(controllerContext);

            // Assert
            CollectionAssert.AreEqual(
                new string[] { "In IDataErrorInfo.get_Error()" },
                log1);

            CollectionAssert.AreEqual(
                new string[] { "In IDataErrorInfo.get_Error()" },
                log2);
        }
        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>();
            LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log);
            ModelMetadata modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext() {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey");

            ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "ValidStringProperty");
            node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.ValidStringProperty"));

            node.Validating += delegate {
                log.Add("In OnValidating()");
            };
            node.Validated += delegate {
                log.Add("In OnValidated()");
            };

            // Act
            node.Validate(controllerContext);

            // Assert
            CollectionAssert.AreEqual(
                new string[] { "In OnValidating()", "In IDataErrorInfo.get_Item('ValidStringProperty')", "In IDataErrorInfo.get_Error()", "In OnValidated()" },
                log);
        }
        public void SetProperty_PropertyIsSettable_CallsSetter()
        {
            // Arrange
            Person model = new Person();
            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = GetMetadataForObject(model)
            };

            ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth");
            ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo");
            ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(new DateTime(2001, 1, 1), validationNode);

            TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder();

            // Act
            testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult);

            // Assert
            validationNode.Validate(controllerContext);
            Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid);
            Assert.Equal(new DateTime(2001, 1, 1), model.DateOfBirth);
        }
        public void SetProperty_SettingNonNullableValueTypeToNull_RequiredValidatorNotPresent_RegistersValidationCallback()
        {
            // Arrange
            ControllerContext controllerContext = new ControllerContext
            {
                Controller = new EmptyController()
            };
            ExtensibleModelBindingContext bindingContext = new ExtensibleModelBindingContext
            {
                ModelMetadata = GetMetadataForObject(new Person()),
            };

            ModelMetadata propertyMetadata = bindingContext.ModelMetadata.Properties.Single(o => o.PropertyName == "DateOfBirth");
            ModelValidationNode validationNode = new ModelValidationNode(propertyMetadata, "foo");
            ComplexModelDtoResult dtoResult = new ComplexModelDtoResult(null /* model */, validationNode);

            TestableMutableObjectModelBinder testableBinder = new TestableMutableObjectModelBinder();

            // Act
            testableBinder.SetPropertyPublic(controllerContext, bindingContext, propertyMetadata, dtoResult);

            // Assert
            Assert.True(controllerContext.Controller.ViewData.ModelState.IsValid);
            validationNode.Validate(controllerContext, bindingContext.ValidationNode);
            Assert.False(controllerContext.Controller.ViewData.ModelState.IsValid);
        }
        public void Validate_SkipsValidationIfHandlerCancels() {
            // Arrange
            List<string> log = new List<string>();
            LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log);
            ModelMetadata modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext() {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey");

            node.Validating += (sender, e) => {
                log.Add("In OnValidating()");
                e.Cancel = true;
            };
            node.Validated += delegate {
                log.Add("In OnValidated()");
            };

            // Act
            node.Validate(controllerContext);

            // Assert
            CollectionAssert.AreEqual(
                new string[] { "In OnValidating()" },
                log);
        }
        public void Validate_SkipsRemainingValidationIfModelStateIsInvalid() {
            // Because a property validator fails, the model validator shouldn't run

            // Arrange
            List<string> log = new List<string>();
            LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log);
            ModelMetadata modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext() {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey");

            ModelMetadata childMetadata = new EmptyModelMetadataProvider().GetMetadataForProperty(() => model, model.GetType(), "InvalidStringProperty");
            node.ChildNodes.Add(new ModelValidationNode(childMetadata, "theKey.InvalidStringProperty"));

            node.Validating += delegate {
                log.Add("In OnValidating()");
            };
            node.Validated += delegate {
                log.Add("In OnValidated()");
            };

            // Act
            node.Validate(controllerContext);

            // Assert
            CollectionAssert.AreEqual(
                new string[] { "In OnValidating()", "In IDataErrorInfo.get_Item('InvalidStringProperty')", "In OnValidated()" },
                log);

            Assert.AreEqual("Sample error message", controllerContext.Controller.ViewData.ModelState["theKey.InvalidStringProperty"].Errors[0].ErrorMessage);
        }
        public void Validate_SkipsValidationIfSuppressed() {
            // Arrange
            List<string> log = new List<string>();
            LoggingDataErrorInfoModel model = new LoggingDataErrorInfoModel(log);
            ModelMetadata modelMetadata = GetModelMetadata(model);

            ControllerContext controllerContext = new ControllerContext() {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey") {
                SuppressValidation = true
            };

            node.Validating += (sender, e) => {
                log.Add("In OnValidating()");
            };
            node.Validated += delegate {
                log.Add("In OnValidated()");
            };

            // Act
            node.Validate(controllerContext);

            // Assert
            CollectionAssert.AreEqual(new string[0], log, "Validate() should have been a no-op.");
        }
        public void Validate_ThrowsIfControllerContextIsNull() {
            // Arrange
            ModelValidationNode node = new ModelValidationNode(GetModelMetadata(), "someKey");

            // Act & assert
            ExceptionHelper.ExpectArgumentNullException(
                delegate {
                    node.Validate(null);
                }, "controllerContext");
        }
        public void Validate_ValidateAllProperties_AddsValidationErrors() {
            // Arrange
            ValidateAllPropertiesModel model = new ValidateAllPropertiesModel() {
                RequiredString = null /* error */,
                RangedInt = 0 /* error */,
                ValidString = "dog"
            };

            ModelMetadata modelMetadata = GetModelMetadata(model);
            ControllerContext controllerContext = new ControllerContext() {
                Controller = new EmptyController()
            };
            ModelValidationNode node = new ModelValidationNode(modelMetadata, "theKey") {
                ValidateAllProperties = true
            };

            controllerContext.Controller.ViewData.ModelState.AddModelError("theKey.RequiredString.Dummy", "existing Error Text");

            // Act
            node.Validate(controllerContext);

            // Assert
            Assert.IsNull(controllerContext.Controller.ViewData.ModelState["theKey.RequiredString"]);
            Assert.AreEqual("existing Error Text", controllerContext.Controller.ViewData.ModelState["theKey.RequiredString.Dummy"].Errors[0].ErrorMessage);
            Assert.AreEqual("The field RangedInt must be between 10 and 30.", controllerContext.Controller.ViewData.ModelState["theKey.RangedInt"].Errors[0].ErrorMessage);
            Assert.IsNull(controllerContext.Controller.ViewData.ModelState["theKey.ValidString"]);
            Assert.IsNull(controllerContext.Controller.ViewData.ModelState["theKey"]);
        }
        public void CombineWith() {
            // Arrange
            List<string> log = new List<string>();

            ModelValidationNode[] allChildNodes = new ModelValidationNode[] {
                new ModelValidationNode(GetModelMetadata(), "key1"),
                new ModelValidationNode(GetModelMetadata(), "key2"),
                new ModelValidationNode(GetModelMetadata(), "key3"),
            };

            ModelValidationNode parentNode1 = new ModelValidationNode(GetModelMetadata(), "parent1");
            parentNode1.ChildNodes.Add(allChildNodes[0]);
            parentNode1.Validating += delegate { log.Add("Validating parent1."); };
            parentNode1.Validated += delegate { log.Add("Validated parent1."); };

            ModelValidationNode parentNode2 = new ModelValidationNode(GetModelMetadata(), "parent2");
            parentNode2.ChildNodes.Add(allChildNodes[1]);
            parentNode2.ChildNodes.Add(allChildNodes[2]);
            parentNode2.Validating += delegate { log.Add("Validating parent2."); };
            parentNode2.Validated += delegate { log.Add("Validated parent2."); };

            // Act
            parentNode1.CombineWith(parentNode2);
            parentNode1.Validate(new ControllerContext() { Controller = new EmptyController() });

            // Assert
            CollectionAssert.AreEqual(
                new string[] { "Validating parent1.", "Validating parent2.", "Validated parent1.", "Validated parent2." },
                log);
            CollectionAssert.AreEqual(allChildNodes, parentNode1.ChildNodes.ToArray());
        }
        public void CombineWith_OtherNodeIsSuppressed_DoesNothing()
        {
            // Arrange
            List<string> log = new List<string>();

            ModelValidationNode[] allChildNodes = new[]
            {
                new ModelValidationNode(GetModelMetadata(), "key1"),
                new ModelValidationNode(GetModelMetadata(), "key2"),
                new ModelValidationNode(GetModelMetadata(), "key3"),
            };

            ModelValidationNode[] expectedChildNodes = new[]
            {
                allChildNodes[0]
            };

            ModelValidationNode parentNode1 = new ModelValidationNode(GetModelMetadata(), "parent1");
            parentNode1.ChildNodes.Add(allChildNodes[0]);
            parentNode1.Validating += delegate { log.Add("Validating parent1."); };
            parentNode1.Validated += delegate { log.Add("Validated parent1."); };

            ModelValidationNode parentNode2 = new ModelValidationNode(GetModelMetadata(), "parent2");
            parentNode2.ChildNodes.Add(allChildNodes[1]);
            parentNode2.ChildNodes.Add(allChildNodes[2]);
            parentNode2.Validating += delegate { log.Add("Validating parent2."); };
            parentNode2.Validated += delegate { log.Add("Validated parent2."); };
            parentNode2.SuppressValidation = true;

            // Act
            parentNode1.CombineWith(parentNode2);
            parentNode1.Validate(new ControllerContext { Controller = new EmptyController() });

            // Assert
            Assert.Equal(new[] { "Validating parent1.", "Validated parent1." }, log.ToArray());
            Assert.Equal(expectedChildNodes, parentNode1.ChildNodes.ToArray());
        }