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
                );
        }
        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 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_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);
        }