/// <summary>
            /// Because the test deserializer used to parse the actual payload will not have metadata, we fix it up here.
            /// Note: this should probably move to happen just before comparison, rather than when generating expectations.
            /// </summary>
            /// <param name="payloadElement">The payload element</param>
            private void SortAndNormalizeProperties(ComplexInstance payloadElement)
            {
                var sortedProperties = payloadElement.Properties.OrderBy(p => p.Name).ToList();

                foreach (var p in sortedProperties)
                {
                    var property = p;
                    payloadElement.Remove(property);

                    // If we have a primitive property with null value, we write a type name for the null value
                    // in V1 and V2. If not type name is available or we are in V3, we don't do that and thus expect a null property instance.
                    var primitiveProperty = property as PrimitiveProperty;
                    if (primitiveProperty != null && primitiveProperty.Value.IsNull &&
                        (this.dsv >= DataServiceProtocolVersion.V4 || string.IsNullOrEmpty(primitiveProperty.Value.FullTypeName)))
                    {
                        property = new NullPropertyInstance(property.Name, null).WithAnnotations(property.Annotations);
                    }

                    var complexProperty = property as ComplexProperty;
                    if (complexProperty != null && complexProperty.Value.IsNull)
                    {
                        property = new NullPropertyInstance(property.Name, complexProperty.Value.FullTypeName).WithAnnotations(property.Annotations);
                    }

                    var complexCollectionProperty = property as ComplexMultiValueProperty;
                    if (complexCollectionProperty != null && complexCollectionProperty.Value.Count == 0 && complexCollectionProperty.Value.FullTypeName == null)
                    {
                        property = new PrimitiveProperty(complexCollectionProperty.Name, complexCollectionProperty.Value.FullTypeName, string.Empty);
                    }

                    payloadElement.Add(property);
                }
            }
 /// <summary>
 /// Removes duplicate properties from the specified complex or entity value.
 /// </summary>
 /// <param name="payloadElement"></param>
 private void DeduplicateProperties(ComplexInstance payloadElement)
 {
     Dictionary<string, PropertyInstance> properties = new Dictionary<string, PropertyInstance>();
     foreach (PropertyInstance propertyInstance in payloadElement.Properties.ToList())
     {
         PropertyInstance firstPropertyInstance;
         if (properties.TryGetValue(propertyInstance.Name, out firstPropertyInstance))
         {
             payloadElement.Remove(propertyInstance);
             payloadElement.Replace(firstPropertyInstance, propertyInstance);
             properties[propertyInstance.Name] = propertyInstance;
         }
         else
         {
             properties.Add(propertyInstance.Name, propertyInstance);
         }
     }
 }
Esempio n. 3
0
        /// <summary>
        /// Removes duplicate properties from the specified complex or entity value.
        /// </summary>
        /// <param name="payloadElement"></param>
        private void DeduplicateProperties(ComplexInstance payloadElement)
        {
            Dictionary <string, PropertyInstance> properties = new Dictionary <string, PropertyInstance>();

            foreach (PropertyInstance propertyInstance in payloadElement.Properties.ToList())
            {
                PropertyInstance firstPropertyInstance;
                if (properties.TryGetValue(propertyInstance.Name, out firstPropertyInstance))
                {
                    payloadElement.Remove(propertyInstance);
                    payloadElement.Replace(firstPropertyInstance, propertyInstance);
                    properties[propertyInstance.Name] = propertyInstance;
                }
                else
                {
                    properties.Add(propertyInstance.Name, propertyInstance);
                }
            }
        }
            /// <summary>
            /// Because the test deserializer used to parse the actual payload will not have metadata, we fix it up here.
            /// Note: this should probably move to happen just before comparison, rather than when generating expectations.
            /// </summary>
            /// <param name="payloadElement">The payload element</param>
            private void SortAndNormalizeProperties(ComplexInstance payloadElement)
            {
                var sortedProperties = payloadElement.Properties.OrderBy(p => p.Name).ToList();
                foreach (var p in sortedProperties)
                {
                    var property = p;
                    payloadElement.Remove(property);

                    // If we have a primitive property with null value, we write a type name for the null value
                    // in V1 and V2. If not type name is available or we are in V3, we don't do that and thus expect a null property instance.
                    var primitiveProperty = property as PrimitiveProperty;
                    if (primitiveProperty != null && primitiveProperty.Value.IsNull && 
                        (this.dsv >= DataServiceProtocolVersion.V4 || string.IsNullOrEmpty(primitiveProperty.Value.FullTypeName)))
                    {
                        property = new NullPropertyInstance(property.Name, null).WithAnnotations(property.Annotations);
                    }

                    var complexProperty = property as ComplexProperty;
                    if (complexProperty != null && complexProperty.Value.IsNull)
                    {
                        property = new NullPropertyInstance(property.Name, complexProperty.Value.FullTypeName).WithAnnotations(property.Annotations);
                    }

                    var complexCollectionProperty = property as ComplexMultiValueProperty;
                    if (complexCollectionProperty != null && complexCollectionProperty.Value.Count == 0 && complexCollectionProperty.Value.FullTypeName == null)
                    {
                        property = new PrimitiveProperty(complexCollectionProperty.Name, complexCollectionProperty.Value.FullTypeName, string.Empty);
                    }

                    payloadElement.Add(property);
                }
            }
Esempio n. 5
0
        public void ComplexValueIgnorePropertyNullValuesTest()
        {
            var versions = new Version[] {
                null,
                new Version(4, 0),
            };

            EdmModel        edmModel          = new EdmModel();
            IEdmComplexType countryRegionType = edmModel.ComplexType("CountryRegion")
                                                .Property("Name", EdmPrimitiveTypeKind.String)
                                                .Property("CountryRegionCode", EdmPrimitiveTypeKind.String);
            IEdmComplexType countryRegionNullType = edmModel.ComplexType("CountryRegionNull")
                                                    .Property("Name", EdmPrimitiveTypeKind.String)
                                                    .Property("CountryRegionCode", EdmPrimitiveTypeKind.String);
            IEdmComplexType addressType = edmModel.ComplexType("Address")
                                          .Property("Street", EdmPrimitiveTypeKind.String)
                                          .Property("StreetNull", EdmCoreModel.Instance.GetString(true) as EdmTypeReference)
                                          .Property("Numbers", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)) as EdmTypeReference)
                                          .Property("CountryRegion", new EdmComplexTypeReference(countryRegionType, false))
                                          .Property("CountryRegionNull", new EdmComplexTypeReference(countryRegionNullType, true));

            edmModel.EntityType("Customer")
            .KeyProperty("ID", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference)
            .Property("Address", new EdmComplexTypeReference(addressType, false));
            edmModel.Fixup();

            this.CombinatorialEngineProvider.RunCombinations(
                new ODataNullValueBehaviorKind[] { ODataNullValueBehaviorKind.Default, ODataNullValueBehaviorKind.DisableValidation, ODataNullValueBehaviorKind.IgnoreValue },
                versions,
                versions,
                TestReaderUtils.ODataBehaviorKinds,
                (nullPropertyValueReaderBehavior, dataServiceVersion, edmVersion, behaviorKind) =>
            {
                edmModel.SetEdmVersion(edmVersion);

                // Now we set the 'IgnoreNullValues' annotation on all properties
                IEdmComplexType edmAddressType = (IEdmComplexType)edmModel.FindType("TestModel.Address");
                foreach (IEdmStructuralProperty edmProperty in edmAddressType.StructuralProperties())
                {
                    edmModel.SetNullValueReaderBehavior(edmProperty, nullPropertyValueReaderBehavior);
                }

                EntityInstance customerPayload = PayloadBuilder.Entity("TestModel.Customer")
                                                 .PrimitiveProperty("ID", 1)
                                                 .Property("Address", PayloadBuilder.ComplexValue("TestModel.Address")
                                                           .PrimitiveProperty("Street", "One Microsoft Way")
                                                           .PrimitiveProperty("StreetNull", "One Microsoft Way")
                                                           .Property("Numbers", PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)").Item(1).Item(2))
                                                           .Property("CountryRegion", PayloadBuilder.ComplexValue("TestModel.CountryRegion")
                                                                     .PrimitiveProperty("Name", "Austria")
                                                                     .PrimitiveProperty("CountryRegionCode", "AUT"))
                                                           .Property("CountryRegionNull", PayloadBuilder.ComplexValue("TestModel.CountryRegionNull")
                                                                     .PrimitiveProperty("Name", "Austria")
                                                                     .PrimitiveProperty("CountryRegionCode", "AUT")));

                var testCases = new[]
                {
                    // Complex types that are not nullable should not allow null values.
                    // Null primitive property in the payload and non-nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "Street",
                        ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "Street", "Edm.String"),
                    },
                    // Null complex property in the payload and non-nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "CountryRegion",
                        ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "CountryRegion", "TestModel.CountryRegion"),
                    },
                    // Null collection property in the payload and non-nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "Numbers",
                        ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "Numbers", "Collection(Edm.Int32)"),
                    },
                    // Complex types that are nullable should allow null values.
                    // Null primitive property in the payload and nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "StreetNull",
                    },
                    // Null complex property in the payload and nullable property in the model
                    new IgnoreNullValueTestCase
                    {
                        PropertyName = "CountryRegionNull",
                    },
                };

                Func <IgnoreNullValueTestCase, ReaderTestConfiguration, PayloadReaderTestDescriptor> createTestDescriptor =
                    (testCase, testConfig) =>
                {
                    EntityInstance payloadValue         = customerPayload.DeepCopy();
                    ComplexInstance payloadAddressValue = ((ComplexProperty)payloadValue.GetProperty("Address")).Value;
                    SetToNull(payloadAddressValue, testCase.PropertyName);

                    ComplexInstance resultValue = payloadValue;
                    if (testConfig.IsRequest && nullPropertyValueReaderBehavior == ODataNullValueBehaviorKind.IgnoreValue)
                    {
                        resultValue = customerPayload.DeepCopy();
                        ComplexInstance resultAddressValue = ((ComplexProperty)resultValue.GetProperty("Address")).Value;
                        resultAddressValue.Remove(resultAddressValue.GetProperty(testCase.PropertyName));
                    }

                    return(new PayloadReaderTestDescriptor(this.Settings)
                    {
                        PayloadElement = payloadValue,
                        PayloadEdmModel = edmModel,
                        ExpectedResultPayloadElement =
                            tc =>
                        {
                            if (tc.Format == ODataFormat.Json)
                            {
                                // under the client knob ODL will compute edit links, ids, etc
                                // so we need to update the expected payload
                                if (tc.RunBehaviorKind == TestODataBehaviorKind.WcfDataServicesClient)
                                {
                                    var entity = resultValue as EntityInstance;
                                    if (entity != null)
                                    {
                                        if (!tc.IsRequest)
                                        {
                                            entity.Id = "http://odata.org/test/Customer(1)";
                                            entity.EditLink = "http://odata.org/test/Customer(1)";
                                            entity.WithSelfLink("http://odata.org/test/Customer(1)");
                                        }
                                    }
                                }

                                var tempDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                                {
                                    PayloadElement = resultValue,
                                    PayloadEdmModel = edmModel,
                                };

                                JsonLightPayloadElementFixup.Fixup(tempDescriptor);
                                return tempDescriptor.PayloadElement;
                            }

                            return resultValue;
                        },
                        ExpectedException = (testConfig.IsRequest && nullPropertyValueReaderBehavior != ODataNullValueBehaviorKind.Default) ? null : testCase.ExpectedResponseException
                    });
                };

                this.CombinatorialEngineProvider.RunCombinations(
                    testCases,
                    this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                    (testCase, testConfiguration) =>
                {
                    testConfiguration = testConfiguration.CloneAndApplyBehavior(behaviorKind);
                    testConfiguration.MessageReaderSettings.BaseUri = null;

                    PayloadReaderTestDescriptor testDescriptor = createTestDescriptor(testCase, testConfiguration);
                    testDescriptor.RunTest(testConfiguration);
                });
            });
        }