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

            var propertyValidator = new PropertyValidator(
                "Name",
                new[] { mockValidator.Object });

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

            var results = propertyValidator.Validate(
                MockHelper.CreateEntityValidationContext(mockInternalEntityEntry.Object),
                mockInternalEntityEntry.Object.Member("Name"));

            ValidationErrorHelper.VerifyResults(
                new[] { new Tuple<string, string>("Name", "error") },
                results);
        }
        /// <summary>
        ///     Build validators for the <paramref name="clrProperties" /> and the corresponding <paramref name="edmProperties" />
        ///     or <paramref name="navigationProperties" />.
        /// </summary>
        /// <param name="clrProperties"> Properties to build validators for. </param>
        /// <param name="edmProperties"> Non-navigation EDM properties. </param>
        /// <param name="navigationProperties"> Navigation EDM properties. </param>
        /// <returns> A list of validators. Possibly empty, never null. </returns>
        protected virtual IList <PropertyValidator> BuildValidatorsForProperties(
            IEnumerable <PropertyInfo> clrProperties,
            IEnumerable <EdmProperty> edmProperties,
            IEnumerable <NavigationProperty> navigationProperties)
        {
            DebugCheck.NotNull(edmProperties);
            DebugCheck.NotNull(navigationProperties);
            DebugCheck.NotNull(clrProperties);

            var validators = new List <PropertyValidator>();

            foreach (var property in clrProperties)
            {
                PropertyValidator propertyValidator = null;

                var edmProperty = edmProperties
                                  .Where(p => p.Name == property.Name)
                                  .SingleOrDefault();

                if (edmProperty != null)
                {
                    var referencingAssociations = from navigationProperty in navigationProperties
                                                  let associationType =
                        navigationProperty.RelationshipType as AssociationType
                        where associationType != null
                        from constraint in associationType.ReferentialConstraints
                        where constraint.ToProperties.Contains(edmProperty)
                        select constraint;

                    propertyValidator = BuildPropertyValidator(
                        property, edmProperty, buildFacetValidators: !referencingAssociations.Any());
                }
                else
                {
                    // Currently we don't use facets to build validators for navigation properties,
                    // if this changes in the future we would need to implement and call a different overload
                    // of BuildPropertyValidator here

                    propertyValidator = BuildPropertyValidator(property);
                }

                if (propertyValidator != null)
                {
                    validators.Add(propertyValidator);
                }
            }

            return(validators);
        }
        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 PropertyValidator_does_not_return_errors_if_primitive_property_value_is_valid()
        {
            var mockValidator = new Mock<IValidator>();
            mockValidator
                .Setup(v => v.Validate(It.IsAny<EntityValidationContext>(), It.IsAny<InternalMemberEntry>()))
                .Returns(() => Enumerable.Empty<DbValidationError>());
            var propertyValidator = new PropertyValidator(
                "Name",
                new[] { mockValidator.Object });

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

            var results = propertyValidator.Validate(
                MockHelper.CreateEntityValidationContext(mockInternalEntityEntry.Object),
                mockInternalEntityEntry.Object.Member("Name"));

            Assert.False(results.Any());
        }
        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);
        }