public void DeferredLinkTest()
        {
            IEdmModel model = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            var cityType = model.FindType("TestModel.CityType");
            Debug.Assert(cityType != null, "cityType != null");

            // TODO: add test cases that use relative URIs

            // Few hand-crafted payloads
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Single deferred link
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType)
                            .NavigationProperty("CityHall", "http://odata.org/CityHall"),
                    PayloadEdmModel = model
                },

                // Multiple deferred links
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).WithTypeAnnotation(cityType)
                            .NavigationProperty("CityHall", "http://odata.org/CityHall")
                            .NavigationProperty("DOL", "http://odata.org/DOL"),
                    PayloadEdmModel = model
                },

                // Multiple deferred links with primitive properties in between
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").WithTypeAnnotation(cityType)
                            .Property("Id", PayloadBuilder.PrimitiveValue(1))
                            .NavigationProperty("CityHall", "http://odata.org/CityHall")
                            .Property("Name", PayloadBuilder.PrimitiveValue("Vienna"))
                            .NavigationProperty("DOL", "http://odata.org/DOL"),
                    PayloadEdmModel = model
                },
            };

            // Add standard deferred link payloads
            testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateDeferredNavigationLinkTestDescriptors(this.Settings, true));

            // Generate interesting payloads around the entry
            testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                // Deferred links are response only.
                // TODO: Reenable Json Light support
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => !tc.IsRequest && tc.Format == ODataFormat.Atom),
                (testDescriptor, testConfiguration) =>
                {
                    testDescriptor.RunTest(testConfiguration);
                });
        }
        public void ReadAssociationLinkTest()
        {
            IEdmModel model = TestModels.BuildTestModel();

            // TODO: add a payload with a relative association Uri

            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Association link with nav. link
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder
                        .NavigationProperty("NavPropWithAssociationUri", "http://odata.org/NavProp", "http://odata.org/NavPropWithAssociationUri")
                        .IsCollection(true),
                    PayloadEdmModel = model
                },

                // No need to add expanded nav links since those will be generated for us by the payload generator below.
            }.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            // Association links with nav. link
            IEnumerable<PayloadReaderTestDescriptor> associationLinkTestDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Association links without a nav. link
                // Association link for a singleton nav. property.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1),
                    PayloadEdmModel = model
                },
                // Association link for a collection nav. property.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1),
                    PayloadEdmModel = model
                },
                // Association link which is not declared
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).Property(
                        PayloadBuilder.NavigationProperty("Nonexistant", null, "http://odata.org/CityHallLink").IsCollection(true)),
                    PayloadEdmModel = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", "Nonexistant", "TestModel.CityType")
                },
                // Association link which is not declared on an open type
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityOpenType").Property(
                        PayloadBuilder.NavigationProperty("Nonexistant", null, "http://odata.org/CityHallLink").IsCollection(true)),
                    PayloadEdmModel = model,
                    ExpectedResultCallback = 
                        (tc) => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                                {
                                    ExpectedException = 
                                        (tc.Format == ODataFormat.Json)
                                        ? ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_OpenPropertyWithoutValue", "Nonexistant")
                                        : ODataExpectedExceptions.ODataException("ValidationUtils_OpenNavigationProperty", "Nonexistant", "TestModel.CityOpenType"),
                                },
                },
                // Association link which is declared but of wrong kind
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).Property(
                        PayloadBuilder.NavigationProperty("Name", null, "http://odata.org/CityHallLink").IsCollection(true)),
                    PayloadEdmModel = model,
                    ExpectedResultCallback = 
                        (tc) => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                                {
                                    ExpectedException = 
                                        (tc.Format == ODataFormat.Json)
                                        ? ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithWrongType", "Name", "Edm.String")
                                        : ODataExpectedExceptions.ODataException("ValidationUtils_NavigationPropertyExpected", "Name", "TestModel.CityType", "Structural"),
                                },
                },
            };

            // Generate interesting payloads around the navigation property - this will skip failure cases like request payloads or wrong versions.
            testDescriptors = testDescriptors.Concat(associationLinkTestDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td)));

            // Add the same cases again, but without skipping interesting configurations.
            testDescriptors = testDescriptors.Concat(associationLinkTestDescriptors.Select(td =>
                {
                    PayloadReaderTestDescriptor result = new PayloadReaderTestDescriptor(td);
                    var originalResultCallback = result.ExpectedResultCallback;
                    result.ExpectedResultCallback = tc =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ExpectedException = tc.IsRequest
                                ? null
                                : originalResultCallback == null ? result.ExpectedException : originalResultCallback(tc).ExpectedException,
                            ExpectedPayloadElement = tc.IsRequest
                                ? RemoveAssociationLinkPayloadElementNormalizer.Normalize(result.PayloadElement.DeepCopy())
                                : result.PayloadElement
                        };

                    // Setting the ExpectedResultCallback prevents normalizers from being run.
                    result.SkipTestConfiguration = tc => tc.Format == ODataFormat.Json;

                    return result;
                }));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                ODataVersionUtils.AllSupportedVersions,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, maxProtocolVersion, testConfiguration) =>
                {
                    if (maxProtocolVersion < testConfiguration.Version)
                    {
                        return;
                    }

                    testDescriptor.RunTest(testConfiguration.CloneAndApplyMaxProtocolVersion(maxProtocolVersion));
                });
        }
        public void EntityReferenceLinkTest()
        {
            IEdmModel model = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            var cityType = model.FindType("TestModel.CityType");
            Debug.Assert(cityType != null, "cityType != null");

            // TODO: add test cases that use relative URIs

            // Few hand-crafted payloads
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Single entity reference link for a singleton
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").WithTypeAnnotation(cityType)
                            .Property(PayloadBuilder.NavigationProperty("PoliceStation", "http://odata.org/PoliceStation").IsCollection(false)),
                    PayloadEdmModel = model
                },
                // Single entity reference link for a collection
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").WithTypeAnnotation(cityType)
                            .Property(PayloadBuilder.NavigationProperty("CityHall", "http://odata.org/CityHall").IsCollection(true)),
                    PayloadEdmModel = model
                },

                // Multiple entity reference links
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").WithTypeAnnotation(cityType)
                            .Property(PayloadBuilder.NavigationProperty("CityHall", "http://odata.org/CityHall").IsCollection(true))
                            .Property(PayloadBuilder.NavigationProperty("PoliceStation", "http://odata.org/PoliceStation").IsCollection(false)),
                    PayloadEdmModel = model
                },

                // Multiple entity reference links with primitive properties in between
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadElement = PayloadBuilder.Entity("TestModel.CityType").WithTypeAnnotation(cityType)
                            .Property("Id", PayloadBuilder.PrimitiveValue(1))
                            .Property(PayloadBuilder.NavigationProperty("CityHall", "http://odata.org/CityHall").IsCollection(true))
                            .Property("Name", PayloadBuilder.PrimitiveValue("Vienna"))
                            .Property(PayloadBuilder.NavigationProperty("DOL", "http://odata.org/DOL").IsCollection(true)),
                    PayloadEdmModel = model
                },
            };

            // Generate interesting payloads around the entry
            testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                // Entity reference links are request only.
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.IsRequest),
                (testDescriptor, testConfiguration) =>
                {
                    testDescriptor.RunTest(testConfiguration);
                });
        }