/// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="settings">Settings class to use.</param>
        public PayloadReaderTestDescriptor(Settings settings)
        {
            this.settings          = settings;
            this.PayloadDescriptor = new PayloadTestDescriptor();

            var nullFunction = (Func <ODataPayloadElement, ODataPayloadElement>)null;

            this.PayloadNormalizers = new List <Func <ReaderTestConfiguration, Func <ODataPayloadElement, ODataPayloadElement> > >
            {
                (tc) => tc.Format == ODataFormat.Json ? (payloadElement) => JsonLightPayloadElementNormalizer.Normalize(payloadElement, tc) : nullFunction,
            };

            var nullAction = (Action <PayloadReaderTestDescriptor>)null;

            this.TestDescriptorNormalizers = new List <Func <ReaderTestConfiguration, Action <PayloadReaderTestDescriptor> > >
            {
                (tc) => tc.Format == ODataFormat.Json ? (descriptor) => JsonLightPayloadElementFixup.Fixup(descriptor) : nullAction,
            };

            this.ExpectedResultNormalizers = new List <Func <ReaderTestConfiguration, Func <ODataPayloadElement, ODataPayloadElement> > >
            {
                (tc) => tc.Format == ODataFormat.Atom ? AtomPayloadElementPropertyOrderNormalizer.Normalize : nullFunction,
                (tc) => nullFunction,
                (tc) => tc.Format == ODataFormat.Json ? RemoveCollectionNameAnnotationForCollectionPayloadElementVisitor.Visit : nullFunction,
                (tc) => tc.Format == ODataFormat.Json ? (payloadElement) => JsonLightExpectedPayloadElementNormalizer.Normalize(payloadElement, tc) : nullFunction,
            };
        }
Exemplo n.º 2
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);
                });
            });
        }