public void EntityValidator_does_not_run_other_validation_if_property_validation_failed()
        {
            var mockValidator = new Mock<IValidator>();
            mockValidator
                .Setup(v => v.Validate(It.IsAny<EntityValidationContext>(), It.IsAny<InternalMemberEntry>()))
                .Returns(() => new[] { new DbValidationError("ID", "error") });

            var mockUncalledValidator = new Mock<IValidator>(MockBehavior.Strict);

            var entityValidator = new EntityValidator(
                new[]
                    {
                        new PropertyValidator(
                            "ID",
                            new[] { mockValidator.Object })
                    },
                new[] { mockUncalledValidator.Object });

            var mockInternalEntityEntry = Internal.MockHelper.CreateMockInternalEntityEntry(
                new Dictionary<string, object>
                    {
                        { "ID", -1 }
                    });

            var entityValidationResult = entityValidator.Validate(MockHelper.CreateEntityValidationContext(mockInternalEntityEntry.Object));

            Assert.NotNull(entityValidationResult);

            ValidationErrorHelper.VerifyResults(
                new[] { new Tuple<string, string>("ID", "error") }, entityValidationResult.ValidationErrors);
        }
        public void EntityValidator_does_not_return_error_if_entity_is_valid()
        {
            var mockValidator = new Mock<IValidator>();
            mockValidator
                .Setup(v => v.Validate(It.IsAny<EntityValidationContext>(), It.IsAny<InternalMemberEntry>()))
                .Returns(() => Enumerable.Empty<DbValidationError>());

            var entityValidator = new EntityValidator(
                new[]
                    {
                        new PropertyValidator(
                            "Name",
                            new[] { mockValidator.Object })
                    }, new ValidationAttributeValidator[0]);

            var mockInternalEntityEntry = Internal.MockHelper.CreateMockInternalEntityEntry(
                new Dictionary<string, object>
                    {
                        { "Name", "abc" }
                    });

            var validationResult = entityValidator.Validate(MockHelper.CreateEntityValidationContext(mockInternalEntityEntry.Object));
            Assert.NotNull(validationResult);
            Assert.True(validationResult.IsValid);
        }
        public void GetEntityValidator_returns_cached_validator()
        {
            var mockInternalEntity = Internal.MockHelper.CreateMockInternalEntityEntry(new object());
            var mockBuilder = MockHelper.CreateMockEntityValidatorBuilder();
            var provider = MockHelper.CreateMockValidationProvider(mockBuilder.Object);

            var expectedValidator = new EntityValidator(new PropertyValidator[0], new IValidator[0]);
            mockBuilder.Setup(b => b.BuildEntityValidator(It.IsAny<InternalEntityEntry>()))
                .Returns<InternalEntityEntry>(e => expectedValidator);

            var entityValidator = provider.Object.GetEntityValidatorBase(mockInternalEntity.Object);
            Assert.Same(expectedValidator, entityValidator);
            mockBuilder.Verify(b => b.BuildEntityValidator(It.IsAny<InternalEntityEntry>()), Times.Once());

            // Now it should get the cached one
            entityValidator = provider.Object.GetEntityValidatorBase(mockInternalEntity.Object);
            Assert.Same(expectedValidator, entityValidator);
            mockBuilder.Verify(b => b.BuildEntityValidator(It.IsAny<InternalEntityEntry>()), Times.Once());
        }
        public void EntityValidator_returns_an_error_if_IValidatableObject_validation_failed()
        {
            var entity = new FlightSegmentWithNestedComplexTypes
            {
            };

            var mockInternalEntityEntry = Internal.MockHelper.CreateMockInternalEntityEntry(entity);

            var entityValidator = new EntityValidator(
                new PropertyValidator[0],
                new[] { MockHelper.CreateValidatableObjectValidator("object", "IValidatableObject is invalid") });

            var entityValidationResult = entityValidator.Validate(MockHelper.CreateEntityValidationContext(mockInternalEntityEntry.Object));

            Assert.NotNull(entityValidationResult);

            ValidationErrorHelper.VerifyResults(
                new[] { new Tuple<string, string>("object", "IValidatableObject is invalid") }, entityValidationResult.ValidationErrors);
        }
 /// <summary>
 ///     Gets a validator for the <paramref name="memberEntry" />.
 /// </summary>
 /// <param name="entityValidator"> Entity validator. </param>
 /// <param name="memberEntry"> Property to get a validator for. </param>
 /// <returns> Validator to validate <paramref name="memberEntry" /> . Possibly null if there is no validation for the <paramref
 ///      name="memberEntry" /> . </returns>
 /// <remarks>
 ///     For complex properties this method walks up the type hierarchy to get to the entity level and then goes down
 ///     and gets a validator for the child property that is an ancestor of the property to validate. If a validator
 ///     returned for an ancestor is null it means that there is no validation defined beneath and the method just 
 ///     propagates (and eventually returns) null.
 /// </remarks>
 protected virtual PropertyValidator GetValidatorForProperty(
     EntityValidator entityValidator, InternalMemberEntry memberEntry)
 {
     var complexPropertyEntry = memberEntry as InternalNestedPropertyEntry;
     if (complexPropertyEntry != null)
     {
         var propertyValidator =
             GetValidatorForProperty(entityValidator, complexPropertyEntry.ParentPropertyEntry) as
             ComplexPropertyValidator;
         // if a validator for parent property is null there is no validation for child properties.  
         // just propagate the null.
         return propertyValidator != null && propertyValidator.ComplexTypeValidator != null
                    ? propertyValidator.ComplexTypeValidator.GetPropertyValidator(memberEntry.Name)
                    : null;
     }
     else
     {
         return entityValidator.GetPropertyValidator(memberEntry.Name);
     }
 }
        public void GetPropertyValidator_returns_correct_validator()
        {
            var entity = new FlightSegmentWithNestedComplexTypes();
            var mockInternalEntityEntry = Internal.MockHelper.CreateMockInternalEntityEntry(entity);
            var propertyEntry = mockInternalEntityEntry.Object.Property("Departure");

            var propertyValidator = new PropertyValidator("Departure", new IValidator[0]);
            var entityValidator = new EntityValidator(new[] { propertyValidator }, new IValidator[0]);

            var mockValidationProvider = MockHelper.CreateMockValidationProvider();
            mockValidationProvider.Setup(p => p.GetEntityValidator(It.IsAny<InternalEntityEntry>()))
                .Returns<InternalEntityEntry>(e => entityValidator);
            mockValidationProvider.Protected()
                .Setup<PropertyValidator>("GetValidatorForProperty", ItExpr.IsAny<EntityValidator>(), ItExpr.IsAny<InternalMemberEntry>())
                .Returns<EntityValidator, InternalMemberEntry>((ev, e) => propertyValidator);

            var actualPropertyValidator = mockValidationProvider.Object.GetPropertyValidatorBase(
                mockInternalEntityEntry.Object, propertyEntry);

            Assert.Same(propertyValidator, actualPropertyValidator);
        }
        public void GetValidatorForProperty_returns_correct_validator_for_child_complex_property()
        {
            var entity = new DepartureArrivalInfoWithNestedComplexType
            {
                Airport = new AirportDetails(),
            };

            var mockInternalEntityEntry = Internal.MockHelper.CreateMockInternalEntityEntry(entity);
            var childPropertyEntry = mockInternalEntityEntry.Object.Property("Airport").Property("AirportCode");

            var childPropertyValidator = new PropertyValidator("AirportCode", new IValidator[0]);
            var complexPropertyValidator = new ComplexPropertyValidator(
                "Airport", new IValidator[0],
                new ComplexTypeValidator(new[] { childPropertyValidator }, new IValidator[0]));
            var entityValidator = new EntityValidator(new[] { complexPropertyValidator }, new IValidator[0]);

            var mockValidationProvider = MockHelper.CreateMockValidationProvider();

            mockValidationProvider.Protected()
                .Setup<PropertyValidator>("GetValidatorForProperty", ItExpr.IsAny<EntityValidator>(), ItExpr.IsAny<InternalMemberEntry>())
                .Returns<EntityValidator, InternalMemberEntry>((ev, e) => complexPropertyValidator);

            var actualPropertyValidator = mockValidationProvider.Object.GetValidatorForPropertyBase(entityValidator, childPropertyEntry);

            Assert.Same(childPropertyValidator, actualPropertyValidator);
        }
        public void GetValidatorForProperty_returns_correct_validator_for_scalar_property()
        {
            var entity = new FlightSegmentWithNestedComplexTypes();
            var mockInternalEntityEntry = Internal.MockHelper.CreateMockInternalEntityEntry(entity);
            var propertyEntry = mockInternalEntityEntry.Object.Property("FlightNumber");

            var propertyValidator = new PropertyValidator("FlightNumber", new IValidator[0]);
            var entityValidator = new EntityValidator(new[] { propertyValidator }, new IValidator[0]);

            var actualPropertyValidator = MockHelper.CreateMockValidationProvider().Object.GetValidatorForPropertyBase(entityValidator, propertyEntry);

            Assert.Same(propertyValidator, actualPropertyValidator);
        }
        public void GetValidatorForProperty_returns_null_for_child_complex_property_if_no_property_validation()
        {
            var entity = new DepartureArrivalInfoWithNestedComplexType
            {
                Airport = new AirportDetails(),
            };

            var mockInternalEntityEntry = Internal.MockHelper.CreateMockInternalEntityEntry(entity);
            var childPropertyEntry = mockInternalEntityEntry.Object.Property("Airport").Property("AirportCode");

            var entityValidator = new EntityValidator(new PropertyValidator[0], new IValidator[0]);

            var actualPropertyValidator = MockHelper.CreateMockValidationProvider().Object.GetValidatorForPropertyBase(
                entityValidator, childPropertyEntry);

            Assert.Null(actualPropertyValidator);
        }
 public PropertyValidator GetValidatorForPropertyBase(EntityValidator entityValidator, InternalMemberEntry memberEntry)
 {
     return base.GetValidatorForProperty(entityValidator, memberEntry);
 }