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 InvalidEntityReferenceLinkReaderAtomTest()
        {
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                #region Wrong name and namespace
                // Wrong name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.DeferredLink("http://odata.org/link").XmlRepresentation("<m:Ref id=\"http://odata.org/link\" />"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_InvalidEntityReferenceLinkStartElement", "Ref", "http://docs.oasis-open.org/odata/ns/metadata"),
                },
                // Wrong namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.DeferredLink("http://odata.org/link").XmlRepresentation("<ref id=\"http://odata.org/link\" />"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_InvalidEntityReferenceLinkStartElement", "ref", "http://www.w3.org/2005/Atom"),
                },
                #endregion Wrong name and namespace
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Example #3
0
        private IEnumerable <PayloadReaderTestDescriptor> CreateCrossReferenceTestDescriptors(CrossReferenceTestCase testCase, ReaderTestConfiguration testConfiguration)
        {
            ExceptionUtilities.CheckArgumentNotNull(testCase, "testCase");

            var emptyPayload = new OData.Common.PayloadTestDescriptor()
            {
                PayloadEdmModel = new EdmModel().Fixup()
            };

            IEnumerable <OData.Common.PayloadTestDescriptor> operationPayloads = new[] { emptyPayload };

            // One of the operations in the test case may specify a reference link value to use to generate payloads
            string payloadReferenceLink = testCase.ChangeSets.SelectMany(cset => cset.Operations).Select(o => o.PayloadCrossReferenceLink).SingleOrDefault(s => !string.IsNullOrEmpty(s));

            if (payloadReferenceLink != null)
            {
                EdmModel testModel = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
                operationPayloads =
                    GeneratePayloadElementsWithCrossReferenceLinks(payloadReferenceLink, testConfiguration).Select(
                        p => new OData.Common.PayloadTestDescriptor
                {
                    PayloadElement  = p,
                    PayloadEdmModel = testModel,
                });
            }

            var testDescriptors = new List <PayloadReaderTestDescriptor>();

            foreach (var payload in operationPayloads)
            {
                IEnumerable <IMimePart> requestChangesets = testCase.ChangeSets.Select(
                    c => (IMimePart)BatchUtils.GetRequestChangeset(
                        c.Operations.Select(o =>
                {
                    // check whether we need to inject a payload into this operation
                    var operationPayload = string.IsNullOrEmpty(o.PayloadCrossReferenceLink) ? emptyPayload : payload;

                    ODataUri operationUri = new ODataUri(new[] { ODataUriBuilder.Unrecognized(o.Uri.OriginalString) });
                    var requestOperation  = operationPayload.InRequestOperation(HttpVerb.Post, operationUri, this.RequestManager);
                    requestOperation.Headers.Add(HttpHeaders.ContentId, o.ContentId);

                    return((IMimePart)requestOperation);
                }).ToArray(),
                        this.RequestManager));

                var testDescriptor = new PayloadReaderTestDescriptor(this.PayloadReaderSettings)
                {
                    DebugDescription      = testCase.DebugDescription,
                    PayloadElement        = PayloadBuilder.BatchRequestPayload(requestChangesets.ToArray()).AddAnnotation(new BatchBoundaryAnnotation("batch_foo")),
                    ExpectedException     = testCase.ExpectedException,
                    SkipTestConfiguration = (testConfig) => !testConfig.IsRequest,
                };

                testDescriptors.Add(testDescriptor);
            }

            return(testDescriptors);
        }
        public void TopLevelPropertyTest()
        {
            var testDescriptors = new PayloadReaderTestDescriptor[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty(null, "foo")
                                     .XmlRepresentation("<value xmlns=''>42</value>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_TopLevelPropertyElementWrongNamespace", string.Empty, TestAtomConstants.ODataMetadataNamespace),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty("propertyName", "foo")
                                     .XmlRepresentation("<d:value>42</d:value>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_TopLevelPropertyElementWrongNamespace", TestAtomConstants.ODataNamespace, TestAtomConstants.ODataMetadataNamespace),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty(null, "")
                                     .XmlRepresentation("<m:value m:type='Edm.String'/>"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty(null, "")
                                     .XmlRepresentation("<!--s-->  <?value?><m:value m:type='Edm.String'/><?value?><!-- -->"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty(null, GeographyFactory.Point(50, 70).Build())
                                     .XmlRepresentation(
                        "<m:value>" +
                        "<gml:Point gml:srsName=\"http://www.opengis.net/def/crs/EPSG/0/4326\" xmlns:gml=\"http://www.opengis.net/gml\">" +
                        "<gml:pos>50 70</gml:pos>" +
                        "</gml:Point>" +
                        "</m:value>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty(null, GeographyFactory.Point(50, 70).Build())
                                     .XmlRepresentation(
                        "<m:value m:type='Edm.GeographyPoint'>" +
                        "<gml:Point gml:srsName=\"http://www.opengis.net/def/crs/EPSG/0/4326\" xmlns:gml=\"http://www.opengis.net/gml\">" +
                        "<gml:pos>50 70</gml:pos>" +
                        "</gml:Point>" +
                        "</m:value>"),
                    SkipTestConfiguration = tc => tc.Version < ODataVersion.V4
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Example #5
0
        public void HomogeneousCollectionReaderAtomTest()
        {
            EdmModel edmModel = new EdmModel();

            EdmComplexType edmComplexTypeEmpty = new EdmComplexType(ModelNamespace, "EmptyComplexType");

            edmModel.AddElement(edmComplexTypeEmpty);

            EdmComplexType edmComplexTypeCity = new EdmComplexType(ModelNamespace, "CityType");

            edmComplexTypeCity.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
            edmModel.AddElement(edmComplexTypeCity);

            EdmComplexType edmComplexTypeAddress = new EdmComplexType(ModelNamespace, "AddressType");

            edmComplexTypeAddress.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(true));
            edmModel.AddElement(edmComplexTypeAddress);

            edmModel.Fixup();

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // complex collection with primitive expected type
                new PayloadReaderTestDescriptor(this.PayloadTestDescriptorSettings)
                {
                    PayloadElement = new ComplexInstanceCollection(
                        PayloadBuilder.ComplexValue("TestModel.CityType").Property("Name", PayloadBuilder.PrimitiveValue("Vienna")),
                        PayloadBuilder.ComplexValue("TestModel.CityType").Property("Name", PayloadBuilder.PrimitiveValue("Prague"))
                        ).ExpectedCollectionItemType(EdmDataTypes.Int32).CollectionName(null),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.CityType", "Primitive", "Complex"),
                },

                // primitive collection in XMLRepresentation with complex expected type.
                new PayloadReaderTestDescriptor(this.PayloadTestDescriptorSettings)
                {
                    PayloadElement = new ComplexInstanceCollection(
                        PayloadBuilder.ComplexValue("TestModel.CityType"),
                        PayloadBuilder.ComplexValue("TestModel.CityType")
                        ).ExpectedCollectionItemType(edmComplexTypeCity).CollectionName(null)
                                     .XmlRepresentation(@"
                                            <m:value>
                                                <m:element m:type='Edm.Int32'>1</m:element>
                                                <m:element m:type='Edm.Int32'>2</m:element>
                                            </m:value>"),
                    PayloadEdmModel   = edmModel,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "Edm.Int32", "Complex", "Primitive"),
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
        private void RunMessageSizeLimitTests(
            IEnumerable <ReaderTestConfiguration> testConfigurations,
            EdmModel model,
            ODataPayloadElement payload,
            MessageSizeLimitTestCase[] testCases,
            Func <ReaderTestConfiguration, bool> skipTestConfigurationFunc = null)
        {
            var transformScope = this.Settings.PayloadTransformFactory.EmptyScope();

            using (transformScope.Apply())
            {
                this.CombinatorialEngineProvider.RunCombinations(
                    testCases,
                    testConfigurations,
                    (testCase, testConfiguration) =>
                {
                    int size = -1;
                    if (testConfiguration.Format == ODataFormat.Atom && testCase.AtomSizes != null)
                    {
                        size = testConfiguration.IsRequest ? testCase.AtomSizes.RequestSize : testCase.AtomSizes.ResponseSize;
                    }
                    else if (testConfiguration.Format == ODataFormat.Json && testCase.JsonLightSizes != null)
                    {
                        size = testConfiguration.IsRequest ? testCase.JsonLightSizes.RequestSize : testCase.JsonLightSizes.ResponseSize;
                    }
                    else if (testCase.RawSizes != null)
                    {
                        size = testConfiguration.IsRequest ? testCase.RawSizes.RequestSize : testCase.RawSizes.ResponseSize;
                    }

                    int maxSize = testCase.MaxMessageSize >= 0 ? testCase.MaxMessageSize : 1024 * 1024;
                    ExpectedException expectedException = size < 0
                            ? null
                            : ODataExpectedExceptions.ODataException("MessageStreamWrappingStream_ByteLimitExceeded", size.ToString(), maxSize.ToString());

                    var testDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                    {
                        PayloadEdmModel             = model,
                        PayloadElement              = payload.DeepCopy(),
                        ExpectedException           = expectedException,
                        SkipTestConfiguration       = skipTestConfigurationFunc,
                        ApplyPayloadTransformations = false,
                    };

                    testDescriptor.ExpectedResultNormalizers.Add(
                        tc => (Func <ODataPayloadElement, ODataPayloadElement>)null);

                    if (testCase.MaxMessageSize > 0)
                    {
                        testConfiguration = new ReaderTestConfiguration(testConfiguration);
                        testConfiguration.MessageReaderSettings.MessageQuotas.MaxReceivedMessageSize = testCase.MaxMessageSize;
                    }

                    testDescriptor.RunTest(testConfiguration);
                });
            }
        }
        public void FeedWithSubContextUriTest()
        {
            IEdmModel           model           = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            IEdmEntityContainer container       = model.FindEntityContainer("DefaultContainer");
            IEdmEntitySet       citiesEntitySet = container.FindEntitySet("Cities");
            IEdmType            cityType        = model.FindType("TestModel.CityType") as IEdmType;

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Feed containing entries with and without sub context uri",
                    PayloadElement   = PayloadBuilder
                                       .EntitySet(new EntityInstance[]
                    {
                        PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).AddAnnotation(new SerializationTypeNameTestAnnotation()
                        {
                            TypeName = null
                        }),
                        PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).AddAnnotation(new SerializationTypeNameTestAnnotation()
                        {
                            TypeName = null
                        }),
                    })
                                       .XmlRepresentation(
                        "<feed m:context=\"http://odata.org/test/$metadata#Cities(Id)\">" +
                        "<entry m:context=\"http://odata.org/test/$metadata#Cities(Id)/$entity\">" +
                        "<content type=\"application/xml\">" +
                        "<m:properties>" +
                        "<d:Id>1</d:Id>" +
                        "</m:properties>" +
                        "</content>" +
                        "</entry>" +
                        "<entry>" +
                        "<content type=\"application/xml\">" +
                        "<m:properties>" +
                        "<d:Id>2</d:Id>" +
                        "</m:properties>" +
                        "</content>" +
                        "</entry>" +
                        "</feed>")
                                       .ExpectedEntityType(cityType, citiesEntitySet),
                    PayloadEdmModel = model
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
Example #8
0
        /// <summary>
        /// Runs each test descriptor with each ATOM reader test configuration and with ATOM metadata both enabled and disabled.
        /// </summary>
        /// <param name="testDescriptors">The test descriptors to run</param>
        /// <param name="runOnlyWithMetadataReadingOn">If true, then the test descriptors are only run with ATOM metadata reading enabled; false means run each descriptor with ATOM metadata reading both enabled and disabled.</param>
        protected void RunAtomMetadataReaderTests(IEnumerable <PayloadReaderTestDescriptor> testDescriptors, bool runOnlyWithMetadataReadingOn = false)
        {
            bool[] enableMetadataReadingOptions = runOnlyWithMetadataReadingOn
                ? new bool[] { true }
                : new bool[] { true, false };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                enableMetadataReadingOptions,
                (testDescriptor, testConfiguration, enableMetadataReading) =>
            {
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                testConfiguration.MessageReaderSettings.EnableAtomMetadataReading = enableMetadataReading;

                testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);

                // Normalize the payload elements so that if an ATOM metadata property is set, the corresponding ATOM metadata
                // annotation is created, and vice versa.
                testDescriptor.ExpectedResultNormalizers.Add(tc => ODataPayloadElementAtomMetadataNormalizer.GenerateNormalizer(tc));

                if (!enableMetadataReading)
                {
                    // If we are running with ATOM metadata reading turned off, strip off all ATOM metadata annotations and
                    // properties from the expected result.
                    testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveAtomMetadataFromPayloadElementVisitor.Visit);

                    // Association links are only recognized in response and MPV >= V3
                    if (testConfiguration.IsRequest)
                    {
                        testDescriptor.ExpectedResultNormalizers.Add(tc =>
                                                                     (payloadElement => RemoveAssociationLinkPayloadElementNormalizer.Normalize(payloadElement)));
                    }

                    // Stream properties are only recognized in response and >=V3
                    if (testConfiguration.IsRequest)
                    {
                        testDescriptor.ExpectedResultNormalizers.Add(tc =>
                                                                     (payloadElement => RemoveStreamPropertyPayloadElementNormalizer.Normalize(payloadElement)));
                    }

                    // In this test class, expected exceptions apply only when ATOM metadata reading is on.
                    testDescriptor.ExpectedException = null;
                }
                else
                {
                    // In requests when metadata reading is enabled we have to turn stream properties and association links
                    // into Atom metadata (and XmlTree annotation instances)
                    testDescriptor.ExpectedResultNormalizers.Add(tc => (payloadElement) => ConvertAtomMetadataForConfigurationPayloadElementNormalizer.Normalize(payloadElement, tc));
                }

                testDescriptor.RunTest(testConfiguration);
            });
        }
        private void RunStreamPropertyTest(IEdmModel model, IEnumerable <StreamPropertyTestCase> testCases)
        {
            var cityType = model.FindDeclaredType("TestModel.CityType").ToTypeReference();
            var cities   = model.EntityContainer.FindEntitySet("Cities");
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = testCases.Select(testCase =>
            {
                IEdmTypeReference entityType = testCase.OwningEntityType ?? cityType;
                EntityInstance entity        = PayloadBuilder.Entity(entityType.FullName()).PrimitiveProperty("Id", 1)
                                               .JsonRepresentation(
                    "{" +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities/" + entityType.FullName() + "()/$entity\"," +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"" + entityType.FullName() + "\"," +
                    "\"Id\": 1," +
                    testCase.Json +
                    "}")
                                               .ExpectedEntityType(entityType, cities);
                foreach (NamedStreamInstance streamProperty in testCase.ExpectedEntity.Properties.OfType <NamedStreamInstance>())
                {
                    entity.Add(streamProperty.DeepCopy());
                }

                return(new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = testCase.DebugDescription,
                    PayloadEdmModel = model,
                    PayloadElement = entity,
                    ExpectedException = testCase.ExpectedException,
                    SkipTestConfiguration = tc => testCase.OnlyResponse ? tc.IsRequest : false,
                    InvalidOnRequest = testCase.InvalidOnRequest
                });
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                if (testConfiguration.IsRequest && testDescriptor.InvalidOnRequest)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor)
                    {
                        ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_StreamPropertyInRequest")
                    };
                }

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                var testConfigClone = new ReaderTestConfiguration(testConfiguration);
                testConfigClone.MessageReaderSettings.BaseUri = null;

                testDescriptor.RunTest(testConfigClone);
            });
        }
Example #10
0
        public void InvalidXmlBaseUriHandlingTest()
        {
            string absoluteUri = "http://odata.org/relative";

            var testCases = new[]
            {
                new
                {
                    BaseUriString     = "relativeUri",
                    SettingsBaseUri   = (string)null,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomDeserializer_RelativeUriUsedWithoutBaseUriSpecified", "relativeUri")
                },
                new
                {
                    BaseUriString     = string.Empty,
                    SettingsBaseUri   = (string)null,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomDeserializer_RelativeUriUsedWithoutBaseUriSpecified", string.Empty)
                },
                new
                {
                    BaseUriString     = "http://invalid:uri:value",
                    SettingsBaseUri   = (string)null,
                    ExpectedException = new ExpectedException(typeof(UriFormatException))
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                new TestODataBehaviorKind[] { TestODataBehaviorKind.Default, TestODataBehaviorKind.WcfDataServicesServer },
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testCase, behaviorKind, testConfiguration) =>
            {
                var td = new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity().AsMediaLinkEntry().StreamSourceLink(absoluteUri)
                                     .XmlRepresentation("<entry xml:base='" + testCase.BaseUriString + "'><content src='" + absoluteUri + "'/></entry>"),
                    ExpectedException = testCase.ExpectedException
                };

                // [Astoria-ODataLib-Integration] Parsing of URLs on OData recognized places may fail, but Astoria server doesn't
                // In server mode we need to normalize payload to not expect information that the server does not read
                if (behaviorKind == TestODataBehaviorKind.WcfDataServicesServer)
                {
                    td.ExpectedResultNormalizers.Add((tc) => (payloadElement => WcfDsServerPayloadElementNormalizer.Normalize(payloadElement, tc.Format, (EdmModel)null)));
                }


                testConfiguration = testConfiguration.CloneAndApplyBehavior(behaviorKind);
                testConfiguration.MessageReaderSettings.BaseUri = testCase.SettingsBaseUri == null ? null : new Uri(testCase.SettingsBaseUri);

                td.RunTest(testConfiguration);
            });
        }
 internal PayloadReaderTestDescriptor ToEdmPayloadReaderTestDescriptor(PayloadReaderTestDescriptor.Settings payloadTestDescriptorSettings, PayloadReaderTestExpectedResult.PayloadReaderTestExpectedResultSettings payloadExpectedResultSettings)
 {
     return new PayloadReaderTestDescriptor(payloadTestDescriptorSettings)
     {
         PayloadElement = this.Json,
         PayloadEdmModel = this.EdmModel,
         SkipTestConfiguration = this.SkipTestConfiguration,
         ExpectedResultCallback = (testConfig) =>
             new PayloadReaderTestExpectedResult(payloadExpectedResultSettings)
             {
                 ExpectedException = this.ExpectedExceptionFunc == null ? null : this.ExpectedExceptionFunc(this, testConfig),
             }
     };
 }
Example #12
0
        public void FeedStartElementTest()
        {
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Empty feed element
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().XmlRepresentation("<feed/>")
                },
                // Element with wrong local name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.EntitySet().XmlRepresentation("<entry/>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_FeedElementWrongName", "entry", "http://www.w3.org/2005/Atom")
                },
                // Element with wrong local name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.EntitySet().XmlRepresentation("<Feed/>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_FeedElementWrongName", "Feed", "http://www.w3.org/2005/Atom")
                },
                // Element with wrong namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.EntitySet().XmlRepresentation("<d:feed/>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_FeedElementWrongName", "feed", "http://docs.oasis-open.org/odata/ns/data")
                },
                // Element with wrong namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement    = PayloadBuilder.EntitySet().XmlRepresentation("<m:type/>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_FeedElementWrongName", "type", "http://docs.oasis-open.org/odata/ns/metadata")
                },
                // Empty feed element with additional attributes - all attributes are ignored
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().XmlRepresentation("<feed some='bar' m:type='Edm.String' m:null='true' m:etag='foo' d:prop='1' />")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void TopLevelNullPropertyWithInvalidTypeNameTest()
        {
            EdmModel model = new EdmModel().Fixup();

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty(null, null)
                                     .XmlRepresentation("<m:value m:null='true' m:type='UnknownType' />"),
                    PayloadEdmModel = model,
                },
            };

            var expectedTypes = new DataType[]
            {
                null,
                EdmDataTypes.Int32.NotNullable(),
                EdmDataTypes.Int32.Nullable(),
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                new bool[] { true, false },
                expectedTypes,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, disablePrimitiveTypeConversion, expectedType, testConfiguration) =>
            {
                if (disablePrimitiveTypeConversion)
                {
                    testConfiguration = new ReaderTestConfiguration(testConfiguration);
                    testConfiguration.MessageReaderSettings.DisablePrimitiveTypeConversion = true;
                }

                if (expectedType != null)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);
                    ((PropertyInstance)testDescriptor.PayloadElement).ExpectedPropertyType(expectedType);

                    if (!disablePrimitiveTypeConversion && !expectedType.IsNullable)
                    {
                        testDescriptor.ExpectedException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullValueForNonNullableType", "Edm.Int32");
                    }
                }

                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void FeedAtomMetadataGeneratorTest()
        {
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Basic generator with name, uri, and version
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().AtomGenerator("Test Generator", "http://odata.org/generator", "1.0")
                },
                // Empty generator (empty element)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().AtomGenerator(null, null, null)
                                     .XmlRepresentation("<feed><generator /></feed>")
                },
                // Empty generator (no children)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().AtomGenerator(String.Empty, null, null)
                                     .XmlRepresentation("<feed><generator></generator></feed>")
                },
                // Generator with extra (ignored) attributes
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().AtomGenerator("Test Generator", null, null)
                                     .XmlRepresentation("<feed><generator extra='attribute'>Test Generator</generator></feed>")
                },
                // Generator with attributes in the wrong namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().AtomGenerator("Test Generator", null, null)
                                     .XmlRepresentation("<feed><generator cn:uri='http://odata.org' cn:version='4.0' xmlns:cn='http://customnamespace.com'>Test Generator</generator></feed>")
                },
                // Feed with multiple generator elements should fail
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet()
                                     .XmlRepresentation(@"<feed>
                                                <generator uri='http://odata.org' version='1'>Some Name</generator>
                                                <generator uri='http://second.uri' version='2'>Another Name</generator>
                                             </feed>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomMetadataDeserializer_MultipleSingletonMetadataElements", "generator", "feed")
                },
            };

            this.RunAtomMetadataReaderTests(testDescriptors);
        }
        public void HeterogeneousCollectionReaderTest()
        {
            EdmModel model    = new EdmModel();
            var      cityType = new EdmComplexType("TestModel", "CityType");

            cityType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(true));
            model.AddElement(cityType);

            var addressType = new EdmComplexType("TestModel", "AddressType");

            addressType.AddStructuralProperty("Street", EdmCoreModel.Instance.GetString(true));
            model.AddElement(addressType);

            var testContainer = new EdmEntityContainer("TestModel", "TestContainer");

            model.AddElement(testContainer);
            EdmFunction citiesFunction = new EdmFunction("TestModel", "Cities", EdmCoreModel.GetCollection(cityType.ToTypeReference()));

            model.AddElement(citiesFunction);
            EdmOperationImport citiesFunctionImport = testContainer.AddFunctionImport("Cities", citiesFunction);

            model.Fixup();

            // Add some hand-crafted payloads
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // expected type without type names in the payload and heterogeneous items
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = new ComplexInstanceCollection(
                        PayloadBuilder.ComplexValue().Property("Name", PayloadBuilder.PrimitiveValue("Vienna")),
                        PayloadBuilder.ComplexValue().Property("Street", PayloadBuilder.PrimitiveValue("Am Euro Platz")))
                                     .ExpectedFunctionImport(citiesFunctionImport)
                                     .CollectionName(null),
                    PayloadEdmModel   = model,
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", "Street", "TestModel.CityType"),
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Example #16
0
        public void FeedWithEntriesTest()
        {
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Single empty entry (empty element)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().Append(PayloadBuilder.Entity())
                                     .XmlRepresentation("<feed><entry/></feed>")
                },
                // Single empty entry (full end element)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().Append(PayloadBuilder.Entity())
                                     .XmlRepresentation("<feed><entry></entry></feed>")
                },
                // Two entries (first empty element)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().Append(PayloadBuilder.Entity().ETag("etag1"), PayloadBuilder.Entity().ETag("etag2"))
                                     .XmlRepresentation("<feed><entry m:etag='etag1'/><entry m:etag='etag2'></entry></feed>")
                },
                // Two entries (first full end element)
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().Append(PayloadBuilder.Entity().ETag("etag1"), PayloadBuilder.Entity().ETag("etag2"))
                                     .XmlRepresentation("<feed><entry m:etag='etag1'></entry><entry m:etag='etag2'/></feed>")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.EntitySet().InlineCount(42).NextLink("http://odata.org/next").AtomId("urn:id")
                                     .Append(PayloadBuilder.Entity(), PayloadBuilder.Entity().ETag("second")),
                    SkipTestConfiguration = tc => tc.IsRequest
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testDescriptor.RunTest(testConfiguration);
            });
        }
Example #17
0
        /// <summary>
        /// Generates interesting properties element payloads with ordering of properties for ATOM reader.
        /// </summary>
        /// <typeparam name="T">The type of the payload element to use.</typeparam>
        /// <param name="sourceTestDescriptor">The source descriptor to use.
        /// This should have the PayloadElement be the instance to which to add properties, the PayloadModel should be filled if necessary
        /// with model which defines two properties stringProperty (Edm.String) and numberProperty (Edm.Int32) and nullProperty (Edm.String nullable).</param>
        /// <param name="applyXmlValue">Func which will apply the generated XML value to the payload element.</param>
        /// <returns>Enumeration of interesting test descriptors.</returns>
        public static IEnumerable <PayloadReaderTestDescriptor> CreatePropertiesElementOrderingPayloads <T>(
            PayloadReaderTestDescriptor sourceTestDescriptor,
            Func <T, IEnumerable <XNode>, T> applyXmlValue,
            string odataNamespace = TestAtomConstants.ODataNamespace) where T : ComplexInstance
        {
            XNamespace odataXNamespace = XNamespace.Get(odataNamespace);
            var        properties      = new[]
            {
                new
                {
                    PropertyXml     = new XElement(odataXNamespace + "stringProperty", "some"),
                    PropertyElement = PayloadBuilder.PrimitiveProperty("stringProperty", "some")
                },
                new
                {
                    PropertyXml = new XElement(odataXNamespace + "numberProperty",
                                               new XAttribute(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomTypeAttributeName, "Edm.Int32"),
                                               "42"),
                    PropertyElement = PayloadBuilder.PrimitiveProperty("numberProperty", 42)
                },
                new
                {
                    PropertyXml = new XElement(odataXNamespace + "nullProperty",
                                               new XAttribute(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.ODataNullAttributeName, TestAtomConstants.AtomTrueLiteral)),
                    PropertyElement = PayloadBuilder.PrimitiveProperty("nullProperty", null)
                },
            };

            return(properties.Permutations().Select(props =>
            {
                var payloadElement = (T)sourceTestDescriptor.PayloadElement.DeepCopy();
                List <XNode> xmlNodes = new List <XNode>();
                for (int i = 0; i < properties.Length; i++)
                {
                    xmlNodes.Add(props[i].PropertyXml);
                    payloadElement.Add(props[i].PropertyElement);
                }

                return new PayloadReaderTestDescriptor(sourceTestDescriptor)
                {
                    PayloadElement = applyXmlValue(payloadElement, xmlNodes)
                };
            }));
        }
Example #18
0
        private List <PayloadReaderTestDescriptor> PayloadDescriptorsToReaderDescriptors(IEnumerable <PayloadTestDescriptor> payloadDescriptors)
        {
            var testDescriptors = new List <PayloadReaderTestDescriptor>();

            foreach (var payloadDescriptor in payloadDescriptors)
            {
                var payload       = payloadDescriptor.PayloadElement.DeepCopy();
                var newDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor     = payloadDescriptor,
                    PayloadElement        = payload,
                    PayloadEdmModel       = payloadDescriptor.PayloadEdmModel,
                    SkipTestConfiguration = payloadDescriptor.SkipTestConfiguration,
                };
                testDescriptors.Add(newDescriptor);
            }

            return(testDescriptors);
        }
        private List<PayloadReaderTestDescriptor> PayloadDescriptorsToReaderDescriptors(IEnumerable<PayloadTestDescriptor> payloadDescriptors)
        {
            var testDescriptors = new List<PayloadReaderTestDescriptor>();

            foreach (var payloadDescriptor in payloadDescriptors)
            {
                var payload = payloadDescriptor.PayloadElement.DeepCopy();
                var newDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                                    {
                                        PayloadDescriptor = payloadDescriptor,
                                        PayloadElement = payload,
                                        PayloadEdmModel = payloadDescriptor.PayloadEdmModel,
                                        SkipTestConfiguration = payloadDescriptor.SkipTestConfiguration,
                                    };
                testDescriptors.Add(newDescriptor);
            }

            return testDescriptors;
        }
Example #20
0
        public void OpenTypeFeedWithHeterogenousItems()
        {
            var model = new EdmModel();

            var openTestDescriptor = new PayloadReaderTestDescriptor(this.Settings)
            {
                PayloadElement  = TestFeeds.CreateOpenEntitySetInstance(model, true, (p) => true),
                PayloadEdmModel = model,
            };

            this.CombinatorialEngineProvider.RunCombinations(
                this.PayloadGenerator.GenerateReaderPayloads(openTestDescriptor),
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                // These payloads get quite large and exceed default size limits
                var actualConfiguration = new ReaderTestConfiguration(testConfiguration);
                actualConfiguration.MessageReaderSettings.MessageQuotas.MaxReceivedMessageSize = long.MaxValue;
                testDescriptor.RunTest(actualConfiguration);
            });
        }
        public void StreamPropertyWithMetadataTests()
        {
            IEnumerable <PayloadReaderTestDescriptor> testDescriptors =
                StreamReferenceValueReaderTests.CreateStreamPropertyMetadataTestDescriptors(this.Settings).SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                if (testConfiguration.IsRequest)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor)
                    {
                        ExpectedException            = null,
                        ExpectedResultPayloadElement = tc => RemoveStreamPropertyPayloadElementNormalizer.Normalize(testDescriptor.PayloadElement.DeepCopy())
                    };
                }

                testDescriptor.RunTest(testConfiguration);
            });
        }
Example #22
0
        public void ReadODataOperationTest()
        {
            IEdmModel           model     = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            IEdmEntityContainer container = model.FindEntityContainer("DefaultContainer");
            IEdmEntitySet       cities    = container.FindEntitySet("Cities");
            IEdmType            cityType  = model.FindType("TestModel.CityType");

            var testCases = new[]
            {
                new
                {
                    DebugDescription = "Single operation without title and target",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{}",
                    ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor {
                                                                     IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                                                                 } }
                },
                new
                {
                    DebugDescription = "Single operation with title",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{\"title\":\"PrimitiveResultOperation\"}",
                    ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor {
                                                                     IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                                                                 } }
                },
                new
                {
                    DebugDescription = "Single operation with target",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{\"target\":\"http://odata.org/test/PrimitiveResultOperation\"}",
                    ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor {
                                                                     IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation"
                                                                 } }
                },
                new
                {
                    DebugDescription = "Single operation with title and target",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{\"title\":\"PrimitiveResultOperation\", \"target\":\"http://odata.org/test/PrimitiveResultOperation\"}",
                    ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor {
                                                                     IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation"
                                                                 } }
                },
                new
                {
                    DebugDescription = "Single operation with 2 targets",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":[{\"target\":\"http://odata.org/test/PrimitiveResultOperation1\"},{\"target\":\"http://odata.org/test/PrimitiveResultOperation2\"}]",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation1"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation2"
                        }
                    }
                },
                new
                {
                    DebugDescription = "Single operation with 2 targets and 2 titles",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":[{\"title\":\"title1\",\"target\":\"http://odata.org/test/PrimitiveResultOperation1\"},{\"title\":\"title2\",\"target\":\"http://odata.org/test/PrimitiveResultOperation2\"}]",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "title1", Target = "http://odata.org/test/PrimitiveResultOperation1"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "title2", Target = "http://odata.org/test/PrimitiveResultOperation2"
                        }
                    }
                },
                new
                {
                    DebugDescription = "Two operations, one without target or title, the other with with 2 targets",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":[{\"target\":\"http://odata.org/test/PrimitiveResultOperation1\"},{\"target\":\"http://odata.org/test/PrimitiveResultOperation2\"}]," +
                                       "\"#TestModel.ComplexResultOperation\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation1"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation2"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.ComplexResultOperation", Title = "TestModel.ComplexResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.ComplexResultOperation"
                        },
                    }
                },
                new
                {
                    DebugDescription = "Two operations, one with target and title, the other with 2 targets and 1 title",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":[{\"title\":\"PrimitiveResultOperation\",\"target\":\"http://odata.org/test/PrimitiveResultOperation1\"},{\"target\":\"http://odata.org/test/PrimitiveResultOperation2\"}]," +
                                       "\"#TestModel.ComplexResultOperation\":{\"title\":\"ComplexResultOperation\",\"target\":\"http://odata.org/test/ComplexResultOperation\"}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation1"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/PrimitiveResultOperation2"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.ComplexResultOperation", Title = "ComplexResultOperation", Target = "http://odata.org/test/ComplexResultOperation"
                        }
                    }
                },
                new
                {
                    DebugDescription = "function group with overloads",
                    Json             = "\"#TestModel.FunctionImportWithOverload\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload", Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload"
                        },
                    }
                },
                new
                {
                    DebugDescription = "function group with overloads and the overload with 0 parameter",
                    Json             = "\"#TestModel.FunctionImportWithOverload\":{}," +
                                       "\"#TestModel.FunctionImportWithOverload()\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload", Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload"
                        },
                    }
                },
                new
                {
                    DebugDescription = "function group with overloads and the overload with 1 parameter",
                    Json             = "\"#TestModel.FunctionImportWithOverload\":{}," +
                                       "\"#TestModel.FunctionImportWithOverload(p1)\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload", Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("(p1)"), Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload(p1=@p1)"
                        },
                    }
                },
                new
                {
                    DebugDescription = "three overloads of an operation, with 0, 1 and 2 parameters",
                    Json             = "\"#TestModel.FunctionImportWithOverload()\":{}," +
                                       "\"#TestModel.FunctionImportWithOverload(p1)\":{}," +
                                       "\"#TestModel.FunctionImportWithOverload(p1,p2)\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("(p1)"), Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload(p1=@p1)"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("(p1,p2)"), Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.FunctionImportWithOverload(p1=@p1,p2=@p2)"
                        },
                    }
                },
                new
                {
                    DebugDescription = "Two overloads of an operation, one with target and title, the other with 2 targets and 1 title",
                    Json             = "\"#TestModel.FunctionImportWithOverload()\":[{\"title\":\"FunctionImportWithOverload\",\"target\":\"http://odata.org/test/FunctionImportWithOverload/Target1\"},{\"target\":\"http://odata.org/test/FunctionImportWithOverload/Target2\"}]," +
                                       "\"#TestModel.FunctionImportWithOverload(p1)\":{\"title\":\"FunctionImportWithOverload(p1)\",\"target\":\"http://odata.org/test/FunctionImportWithOverload(p1=@p1)\"}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("()"), Title = "FunctionImportWithOverload", Target = "http://odata.org/test/FunctionImportWithOverload/Target1"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.FunctionImportWithOverload", Target = "http://odata.org/test/FunctionImportWithOverload/Target2"
                        },
                        new ServiceOperationDescriptor {
                            IsAction = false, Metadata = "http://odata.org/test/$metadata#TestModel.FunctionImportWithOverload" + Uri.EscapeDataString("(p1)"), Title = "FunctionImportWithOverload(p1)", Target = "http://odata.org/test/FunctionImportWithOverload(p1=@p1)"
                        }
                    }
                },
                new
                {
                    DebugDescription = "The operation that is not in model",
                    Json             = "\"#TestModel.UnknownOperation()\":[{\"title\":\"FunctionImportWithOverload\",\"target\":\"http://odata.org/test/FunctionImportWithOverload/Target1\"}]",
                    ExpectedServiceOperationDescriptor = new ServiceOperationDescriptor[] {},
                },
                new
                {
                    DebugDescription = "Single operation with title and a operation that is not in model",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{\"title\":\"PrimitiveResultOperation\"}," +
                                       "\"#TestModel.UnknownOperation\":{\"title\":\"UnknownOperation\"}",
                    ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor {
                                                                     IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                                                                 } }
                },
            };

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = testCases.Select(
                t => new PayloadReaderTestDescriptor(this.Settings)
            {
                DebugDescription = t.DebugDescription,
                PayloadEdmModel  = model,
                PayloadElement   = PayloadBuilder.Entity("TestModel.CityType")
                                   .JsonRepresentation(
                    "{" +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#DefaultContainer.Cities/$entity\"," +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.CityType\"," +
                    "\"Id\":1," +
                    "\"Name\":\"cityTypeName\"," +
                    t.Json +
                    "}")
                                   .ExpectedEntityType(cityType, cities),
                ExpectedResultPayloadElement = (tc) =>
                {
                    var entityInstance = PayloadBuilder.Entity("TestModel.CityType").
                                         PrimitiveProperty("Id", 1).
                                         PrimitiveProperty("Name", "cityTypeName").
                                         StreamProperty("Skyline", "http://odata.org/test/Cities(1)/Skyline", "http://odata.org/test/Cities(1)/Skyline").
                                         NavigationProperty("CityHall", "http://odata.org/test/Cities(1)/CityHall").
                                         NavigationProperty("DOL", "http://odata.org/test/Cities(1)/DOL").
                                         NavigationProperty("PoliceStation", "http://odata.org/test/Cities(1)/PoliceStation");
                    foreach (var op in t.ExpectedServiceOperationDescriptor)
                    {
                        entityInstance.OperationDescriptor(op);
                    }
                    return(entityInstance);
                },
                SkipTestConfiguration = tc => tc.IsRequest
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                if (testConfiguration.IsRequest)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);
                    testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize);
                }

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();

                testDescriptor.RunTest(testConfiguration);
            });
        }
Example #23
0
        /// <summary>
        /// Generates interesting properties element payloads with paddings for ATOM reader.
        /// </summary>
        /// <typeparam name="T">The type of the payload element to use.</typeparam>
        /// <param name="sourceTestDescriptor">The source descriptor to use.
        /// This should have the PayloadElement be the instance to which to add properties, the PayloadModel should be filled if necessary
        /// with model which defines two properties stringProperty (Edm.String) and numberProperty (Edm.Int32).</param>
        /// <param name="applyXmlValue">Func which will apply the generated XML value to the payload element.</param>
        /// <returns>Enumeration of interesting test descriptors.</returns>
        public static IEnumerable <PayloadReaderTestDescriptor> CreatePropertiesElementPaddingPayloads <T>(
            PayloadReaderTestDescriptor sourceTestDescriptor,
            Func <T, string, T> applyXmlValue) where T : ComplexInstance
        {
            var payloadWithPadding = new[]
            {
                // Element with insignificant content is a valid complex value
                new
                {
                    XmlValue   = "{0}",
                    Properties = new PropertyInstance[] { }
                },
                // Simple empty string property - padding before
                new
                {
                    XmlValue   = "{0}<d:stringProperty/>",
                    Properties = new PropertyInstance[] { PayloadBuilder.PrimitiveProperty("stringProperty", string.Empty) }
                },
                // Simple empty string property - padding after
                new
                {
                    XmlValue   = "<d:stringProperty/>{0}",
                    Properties = new PropertyInstance[] { PayloadBuilder.PrimitiveProperty("stringProperty", string.Empty) }
                },
                // Two simple properties - padding between
                new
                {
                    XmlValue   = "<d:stringProperty/>{0}<d:numberProperty m:type='Edm.Int32'>42</d:numberProperty>",
                    Properties = new PropertyInstance[] {
                        PayloadBuilder.PrimitiveProperty("stringProperty", string.Empty),
                        PayloadBuilder.PrimitiveProperty("numberProperty", 42)
                    }
                },
                // Two simple properties - padding after
                new
                {
                    XmlValue   = "<d:stringProperty/><d:numberProperty m:type='Edm.Int32'>42</d:numberProperty>{0}",
                    Properties = new PropertyInstance[] {
                        PayloadBuilder.PrimitiveProperty("stringProperty", string.Empty),
                        PayloadBuilder.PrimitiveProperty("numberProperty", 42)
                    }
                },
            };

            string[] xmlPaddingToIgnore = new string[]
            {
                string.Empty,                                           // Nothing
                "  \r\n\t",                                             // Whitespace only
                "<!--s--> <?value?>",                                   // Insignificant nodes
                "some text <![CDATA[cdata]]>",                          // Significant nodes to be ignored
                "<foo xmlns=''/>",                                      // Element in no namespace
                "<c:foo xmlns:c='uri' attr='1'><c:child/>text</c:foo>", // Element in custom namespace
                "<m:properties/>",                                      // Element in metadata namespace (should be ignored as well)
                "<entry/>",                                             // Element in atom namespace (should also be ignored)
            };

            return(payloadWithPadding.SelectMany(payload =>
                                                 xmlPaddingToIgnore.Select(xmlPadding =>
            {
                var payloadElement = (T)sourceTestDescriptor.PayloadElement.DeepCopy();
                foreach (var prop in payload.Properties)
                {
                    payloadElement.Add(prop);
                }

                payloadElement = applyXmlValue(payloadElement, string.Format(CultureInfo.InvariantCulture, payload.XmlValue, xmlPadding));

                return new PayloadReaderTestDescriptor(sourceTestDescriptor)
                {
                    PayloadElement = payloadElement
                };
            })));
        }
        public void InvalidEntityReferenceLinkReaderAtomTest()
        {
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                #region Wrong name and namespace
                // Wrong name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.DeferredLink("http://odata.org/link").XmlRepresentation("<m:Ref id=\"http://odata.org/link\" />"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_InvalidEntityReferenceLinkStartElement", "Ref", "http://docs.oasis-open.org/odata/ns/metadata"),
                },
                // Wrong namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.DeferredLink("http://odata.org/link").XmlRepresentation("<ref id=\"http://odata.org/link\" />"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_InvalidEntityReferenceLinkStartElement", "ref", "http://www.w3.org/2005/Atom"),
                },
                #endregion Wrong name and namespace
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
                {
                    testDescriptor.RunTest(testConfiguration);
                });
        }
 /// <summary>
 /// Copy constructor for NavigationLinkTestCaseDescriptor.
 /// </summary>
 /// <param name="original">The original test descriptor to copy.</param>
 public NavigationLinkTestCaseDescriptor(PayloadReaderTestDescriptor original)
     : base(original)
 {
 }
        public void TopLevelPropertyNamespaceTest()
        {
            var testCases = new[]
            {
                new
                {
                    // Support custom data namespace for compatibility with WCF DS client.
                    NamespaceUri      = TestAtomConstants.ODataMetadataNamespace + "/custom",
                    ExpectedException = new System.Func <TestODataBehaviorKind, ODataVersion, ExpectedException>((TestODataBehaviorKind behavior, ODataVersion odataVersion) =>
                    {
                        if (behavior == TestODataBehaviorKind.WcfDataServicesServer)
                        {
                            return(null);
                        }
                        else
                        {
                            return(ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_TopLevelPropertyElementWrongNamespace", TestAtomConstants.ODataMetadataNamespace + "/custom", TestAtomConstants.ODataMetadataNamespace));
                        }
                    })
                },
                new
                {
                    NamespaceUri      = TestAtomConstants.ODataMetadataNamespace,
                    ExpectedException = new System.Func <TestODataBehaviorKind, ODataVersion, ExpectedException>((TestODataBehaviorKind behavior, ODataVersion odataVersion) =>
                    {
                        return(null);
                    })
                },
                new
                {
                    NamespaceUri      = TestAtomConstants.ODataNamespace,
                    ExpectedException = new System.Func <TestODataBehaviorKind, ODataVersion, ExpectedException>((TestODataBehaviorKind behavior, ODataVersion odataVersion) =>
                    {
                        if (behavior == TestODataBehaviorKind.WcfDataServicesServer)
                        {
                            return(null);
                        }
                        else
                        {
                            return(ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_TopLevelPropertyElementWrongNamespace", TestAtomConstants.ODataNamespace, TestAtomConstants.ODataMetadataNamespace));
                        }
                    })
                },
                new
                {
                    NamespaceUri      = "http://odata.org/customUri",
                    ExpectedException = new System.Func <TestODataBehaviorKind, ODataVersion, ExpectedException>((TestODataBehaviorKind behavior, ODataVersion odataVersion) =>
                    {
                        if (behavior == TestODataBehaviorKind.WcfDataServicesServer)
                        {
                            return(null);
                        }
                        else
                        {
                            return(ODataExpectedExceptions.ODataException("ODataAtomPropertyAndValueDeserializer_TopLevelPropertyElementWrongNamespace", "http://odata.org/customUri", TestAtomConstants.ODataMetadataNamespace));
                        }
                    })
                }
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                TestReaderUtils.ODataBehaviorKinds,
                new[] { ODataVersion.V4 },
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testCase, behavior, odataVersion, testConfiguration) =>
            {
                var td = new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.PrimitiveProperty(null, string.Empty)
                                     .XmlRepresentation("<p:value xmlns:p='" + testCase.NamespaceUri + "'/>"),
                    ExpectedException = testCase.ExpectedException(behavior, odataVersion)
                };

                testConfiguration = testConfiguration.CloneAndApplyBehavior(behavior);

                td.RunTest(testConfiguration);
            });
        }
Example #27
0
        /// <summary>
        /// Creates invalid error representations in JSON (e.g., extra properties where they are not allowed,
        /// invalid property value types, etc.) - no duplicate properties.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use for the generated <see cref="PayloadReaderTestDescriptor"/>.</param>
        /// <param name="isJsonLight">true if the payloads should be in Json lite format; false if they should be in verbose Json.</param>
        /// <returns>An enumerable of <see cref="PayloadReaderTestDescriptor"/> representing the invalid error payloads.</returns>
        public static IEnumerable<PayloadReaderTestDescriptor> CreateInvalidErrorDescriptors(PayloadReaderTestDescriptor.Settings settings, bool isJsonLight)
        {
            string errorPropertyName = JsonLightConstants.ODataErrorPropertyName;

            return new PayloadReaderTestDescriptor[]
                   {
                       #region Extra properties at the top-level
                       // extra properties in top-level object
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error("foo").Message("msg1")
                               .JsonRepresentation("{ \"foo\": \"bar\" }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonErrorDeserializer_TopLevelErrorWithInvalidProperty", "foo"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error("foo").Message("msg1")
                               .JsonRepresentation("{ \"foo\": \"bar\", \"" + errorPropertyName + "\": { } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonErrorDeserializer_TopLevelErrorWithInvalidProperty", "foo"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error("foo").Message("msg1")
                               .JsonRepresentation("{ \"" + errorPropertyName + "\": { }, \"foo\": \"bar\" }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonErrorDeserializer_TopLevelErrorWithInvalidProperty", "foo"),
                       },

                       // extra properties in top-level error object
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"foo\": \"bar\" } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightErrorDeserializer_TopLevelErrorValueWithInvalidProperty", "foo"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error("foo").Message("msg1")
                               .JsonRepresentation("{ \"" + errorPropertyName + "\": { \"message\": \"msg1\", \"foo\": \"bar\" } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightErrorDeserializer_TopLevelErrorValueWithInvalidProperty", "foo"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error("foo").Message("msg1")
                               .JsonRepresentation("{ \"" + errorPropertyName + "\": { \"foo\": \"bar\", \"message\": \"msg1\" , \"foo2\": \"bar2\" } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightErrorDeserializer_TopLevelErrorValueWithInvalidProperty", "foo"),
                       },
                       #endregion Extra properties at the top-level

                       #region Invalid property values
                       // invalid property values for top-level error property
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": null }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "PrimitiveValue"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": 42 }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "PrimitiveValue"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": [ ] }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "StartArray"),
                       },

                       // invalid property values for message property
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"message\": [ ] }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"message\": 42 }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_CannotReadPropertyValueAsString", "42", "message"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"message\": {} }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                       },

                       // invalid property values for innererror value property
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": 42 }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "PrimitiveValue"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": [ ] }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "StartArray"),
                       },

                       // invalid property values for message property on innererror value
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"message\": { } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"message\": [ ] } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                       },

                       // invalid property values for stacktrace property on innererror value
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"stacktrace\": { } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"stacktrace\": [ ] } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                       },

                       // invalid property values for type name property on innererror value
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"type\": { } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"type\": [ ] } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                       },

                       // invalid property values for internal exception property on innererror value
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": 42 }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "PrimitiveValue"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": [ ] } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "StartObject", "StartArray"),
                       },

                       // invalid property values for message property on internal exception property value
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": { \"message\": { } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": { \"message\": [ ] } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                       },

                       // invalid property values for stacktrace property on internal exception property value
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": { \"stacktrace\": { } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": { \"stacktrace\": [ ] } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                       },

                       // invalid property values for type name property on internal exception property value
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": { \"type\": { } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject"),
                       },
                       new PayloadReaderTestDescriptor(settings)
                       {
                           PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"" + errorPropertyName + "\": { \"innererror\": { \"internalexception\": { \"type\": [ ] } } }"),
                           ExpectedException = ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartArray"),
                       },
                       #endregion Invalid property values
                   };
        }
        public void UndeclaredValuePropertyTests()
        {
            IEdmModel model = TestModels.BuildTestModel();

            IEnumerable <UndeclaredPropertyTestCase> testCases = new[]
            {
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number without type",
                    Json             = "\"UndeclaredProperty\":42",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity(),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "String without type",
                    Json             = "\"UndeclaredProperty\":\"value\"",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity(),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "null without type",
                    Json             = "\"UndeclaredProperty\":null",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity(),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Boolean without type",
                    Json             = "\"UndeclaredProperty\":false",
                    IsValue          = true,
                    ExpectedEntity   = PayloadBuilder.Entity(),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number with type",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"Edm.Int16\"," +
                        "\"UndeclaredProperty\":42",
                    IsValue        = true,
                    ExpectedEntity = PayloadBuilder.Entity(),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number with invalid type - should work, the type is ignored",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.Unknown\"," +
                        "\"UndeclaredProperty\":42",
                    IsValue        = true,
                    ExpectedEntity = PayloadBuilder.Entity(),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Number with another odata annotation - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/reference\"," +
                        "\"UndeclaredProperty\":42",
                    IsValue           = true,
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightPropertyAndValueDeserializer_UnexpectedDataPropertyAnnotation", "UndeclaredProperty", JsonLightConstants.ODataBindAnnotationName)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Property without value and with no recognized annotations - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation") + "\":\"value\"",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithUnknownType", "UndeclaredProperty")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Property without value and with known annotation - should fail",
                    Json             =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataBindAnnotationName) + "\":\"http://odata.org/reference\"",
                    ExpectedEntity    = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithUnknownType", "UndeclaredProperty")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                TestReaderUtils.ODataUndeclaredPropertyBehaviorKindsCombinations,
                // Undeclared properties are only allowed in responses
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                (testCase, undeclaredPropertyBehaviorKinds, testConfiguration) =>
            {
                PayloadReaderTestDescriptor testDescriptor = testCase.ToTestDescriptor(this.Settings, model, undeclaredPropertyBehaviorKinds);
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                testConfiguration.MessageReaderSettings.UndeclaredPropertyBehaviorKinds = undeclaredPropertyBehaviorKinds;

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();
                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void TopLevelInvalidErrorTestWithDuplicateDataProperties()
        {
            PayloadReaderTestDescriptor.Settings settings = this.Settings;
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                #region Duplicate properties
                // duplicate 'error' property
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"message\": \"Error message\" }, \"error\": { \"message\": \"Error message\" } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonReaderUtils_MultipleErrorPropertiesWithSameName", "error"),
                },

                // duplicate 'code' property
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"code\": \"Error code\", \"code\": \"Error code\" } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "code"),
                },

                // duplicate 'message' property
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"message\": \"Error message\", \"message\": \"Error message\" } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "message"),
                },

                // duplicate 'innererror' property
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"code\": \"Error code\", \"innererror\": { }, \"innererror\": { } } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "innererror"),
                },

                // duplicate 'message' property (on the inner error)
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"code\": \"Error code\", \"innererror\": { \"message\": \"Inner msg\", \"message\": \"Inner msg\" } } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "message"),
                },

                // duplicate 'type' property (on the inner error)
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"code\": \"Error code\", \"innererror\": { \"type\": \"Some typename\", \"type\": \"Some typename\" } } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "type"),
                },

                // duplicate 'stacktrace' property (on the inner error)
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"code\": \"Error code\", \"innererror\": { \"stacktrace\": \"stack trace\", \"stacktrace\": \"stack trace\" } } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "stacktrace"),
                },

                // duplicate 'internalexception' property (on the inner error)
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().JsonRepresentation("{ \"error\": { \"code\": \"Error code\", \"innererror\": { \"internalexception\": { }, \"internalexception\": { } } } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "internalexception"),
                },
                #endregion Duplicate properties
            };
            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                // Disable WCF DS Server behavior since in that case duplicate properties are eliminated and the code will not see them.
                TestReaderUtils.ODataBehaviorKinds.Where(behavior => behavior != TestODataBehaviorKind.WcfDataServicesServer),
                (testDescriptor, testConfiguration, behavior) =>
                {
                    // These descriptors are already tailored specifically for Json Light and 
                    // do not require normalization.
                    testDescriptor.TestDescriptorNormalizers.Clear();
                    testDescriptor.RunTest(testConfiguration.CloneAndApplyBehavior(behavior));
                });
        }
        public void UndeclaredNavigationLinkTests()
        {
            IEdmModel model = TestModels.BuildTestModel();

            IEnumerable<UndeclaredPropertyTestCase> testCases = new[]
            {
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just navigation link",
                    Json = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just association link",
                    Json = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", null, "http://odata.org/associationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Navigation and association link",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink", "http://odata.org/associationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Navigation and association link with custom annotation",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation") + "\":null," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink", "http://odata.org/associationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Navigation link with odata.type annotation",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"TestModel.OfficeType\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Association link with another odata.mediaEditLink annotation - should fail",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_UnexpectedStreamPropertyAnnotation", "UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded feed navigation link",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"UndeclaredProperty\":[]",
                    IsLink = true,
                    IsValue = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink"),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded entry navigation link",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"," +
                        "\"UndeclaredProperty\":{}",
                    IsLink = true,
                    IsValue = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", null, "http://odata.org/associationlink"),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded null entry navigation link",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataAssociationLinkUrlAnnotationName) + "\":\"http://odata.org/associationlink\"," +
                        "\"UndeclaredProperty\":null",
                    IsLink = true,
                    IsValue = true,
                    ExpectedEntity = PayloadBuilder.Entity().NavigationProperty("UndeclaredProperty", "http://odata.org/navigationlink", "http://odata.org/associationlink"),
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Expanded navigation link with wrong value",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataNavigationLinkUrlAnnotationName) + "\":\"http://odata.org/navigationlink\"," +
                        "\"UndeclaredProperty\":42",
                    IsLink = true,
                    IsValue = true,
                    ExpectedEntity = PayloadBuilder.Entity(),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_CannotReadNestedResource", "UndeclaredProperty")
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                new[] { false, true },
                // Undeclared properties are only allowed in responses
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                (testCase, throwOnUndeclaredPropertyForNonOpenType, testConfiguration) =>
                {
                    PayloadReaderTestDescriptor testDescriptor = testCase.ToTestDescriptor(this.Settings, model, throwOnUndeclaredPropertyForNonOpenType);
                    testConfiguration = new ReaderTestConfiguration(testConfiguration);
                    if (!throwOnUndeclaredPropertyForNonOpenType)
                    {
                        testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;
                    }

                    // These descriptors are already tailored specifically for Json Light and
                    // do not require normalization.
                    testDescriptor.TestDescriptorNormalizers.Clear();
                    testDescriptor.RunTest(testConfiguration);
                });
        }
        public void TopLevelErrorAnnotationsTest()
        {
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                #region "error" object scope
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Should fail on duplicate custom instance annotations inside the \"error\" object.",
                    PayloadElement = PayloadBuilder.Error()
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""@cn.foo"": ""ignored"",
                                                    ""@cn.foo"": ""something else""
                                                }
                                            }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationNotAllowed", "cn.foo")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Custom property annotation inside the \"error\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error().Code("123")
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""*****@*****.**"": ""ignored"",
                                                    ""code"": ""123""
                                                }
                                            }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Should fail on duplicates of custom property annotation inside the \"error\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error().Code("123")
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""*****@*****.**"": ""ignored"",
                                                    ""*****@*****.**"": ""something else"",
                                                    ""code"": ""123""
                                                }
                                            }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationForPropertyNotAllowed", "cn.foo", "code"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Property annotation without property inside the \"error\" object should fail.",
                    PayloadElement = PayloadBuilder.Error()
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""*****@*****.**"": ""fail""
                                                }
                                            }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightErrorDeserializer_PropertyAnnotationWithoutPropertyForError", "code")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "OData instance annotations inside the \"error\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error()
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""@odata.foo"": ""fail""
                                                }
                                            }"),
                    ExpectedException = (ExpectedException)null
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "OData property annotations inside the \"error\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error().Code("123")
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""*****@*****.**"": ""fail"",
                                                    ""code"": ""123""
                                                }
                                            }"),
                    ExpectedException = (ExpectedException)null
                },
                
                #endregion "error" object scope

                #region "innererror" object scope
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Custom instance annotation inside the \"innererror\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError())
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""innererror"": 
                                                    {
                                                        ""@cn.foo"": ""ignored""
                                                    }
                                                }
                                            }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Should fail on duplicate custom instance annotations inside the \"innererror\" object.",
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError())
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""innererror"": 
                                                    {
                                                        ""@cn.foo"": ""ignored"",
                                                        ""@cn.foo"": ""something else""
                                                    }
                                                }
                                            }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationNotAllowed", "cn.foo")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Custom property annotations inside the \"innererror\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("msg"))
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""innererror"": 
                                                    {
                                                        ""*****@*****.**"": ""ignored"",
                                                        ""message"": ""msg""
                                                    }
                                                }
                                            }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Should fail on duplicate custom property annotations inside the \"innererror\" object.",
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("msg"))
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""innererror"": 
                                                    {
                                                        ""*****@*****.**"": ""ignored"",
                                                        ""*****@*****.**"": ""something else"",
                                                        ""message"": ""msg""
                                                    }
                                                }
                                            }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicateAnnotationForPropertyNotAllowed", "cn.foo", "message")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Should not fail on custom instance annotations with the same name at different nesting levels inside the \"innererror\" object.",
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(PayloadBuilder.InnerError()))
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""@cn.foo"": ""ignored"",
                                                    ""innererror"": 
                                                    {
                                                        ""@cn.foo"": ""ignored"",
                                                        ""internalexception"":
                                                        {
                                                            ""@cn.foo"": ""ignored""
                                                        }
                                                    }
                                                }
                                            }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Should not fail on custom property annotations with the same name at different nesting levels inside the \"innererror\" object.",
                    PayloadElement = PayloadBuilder.Error()
                                        .Message(string.Empty)
                                        .InnerError(PayloadBuilder.InnerError()
                                            .Message("msg")
                                            .InnerError(PayloadBuilder.InnerError()
                                                .Message("msg")))
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""*****@*****.**"": ""ignored"",
                                                    ""message"": """",
                                                    ""innererror"": 
                                                    {
                                                        ""*****@*****.**"": ""ignored"",
                                                        ""message"": ""msg"",
                                                        ""internalexception"":
                                                        {
                                                            ""*****@*****.**"": ""ignored"",
                                                            ""message"": ""msg""
                                                        }
                                                    }
                                                }
                                            }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Property annotation without property inside the \"innererror\" object should fail.",
                    PayloadElement = PayloadBuilder.Error()
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""innererror"": 
                                                    {
                                                        ""*****@*****.**"": ""fail""
                                                    }
                                                }
                                            }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightErrorDeserializer_PropertyAnnotationWithoutPropertyForError", "message")
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "OData instance annotations inside the \"innererror\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error().InnerError(new ODataInternalExceptionPayload())
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""innererror"": 
                                                    {
                                                        ""@odata.foo"": ""fail""
                                                    }
                                                }
                                            }"),
                    ExpectedException = (ExpectedException)null
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Unknown odata property annotations inside the \"innererror\" object should be ignored.",
                    PayloadElement = PayloadBuilder.Error().InnerError(new ODataInternalExceptionPayload().Message("msg"))
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""innererror"": 
                                                    {
                                                        ""*****@*****.**"": ""bar"",
                                                        ""message"": ""msg""
                                                    }
                                                }
                                            }"),
                    ExpectedException = (ExpectedException)null
                },
                #endregion "innererror" object scope

                #region "message" object scope
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Read empty error message.",
                    PayloadElement = PayloadBuilder.Error().Message(string.Empty)
                        .JsonRepresentation(@"
                                            { 
                                                ""error"":
                                                {
                                                    ""message"": """"          
                                                }
                                            }"),
                },
                #endregion "message" object scope
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                TestReaderUtils.ODataBehaviorKinds,
                (testDescriptor, testConfiguration, behavior) =>
                {
                    // These descriptors are already tailored specifically for Json Light and 
                    // do not require normalization.
                    testDescriptor.TestDescriptorNormalizers.Clear();
                    testDescriptor.RunTest(testConfiguration.CloneAndApplyBehavior(behavior));
                });
        }
Example #32
0
        public void ReadBindableODataOperationTest()
        {
            EdmModel           model            = Test.OData.Utils.Metadata.TestModels.BuildTestModel() as EdmModel;
            EdmEntityContainer defaultContainer = model.FindEntityContainer("DefaultContainer") as EdmEntityContainer;
            IEdmEntitySet      cities           = defaultContainer.FindEntitySet("Cities");
            IEdmEntityType     cityType         = (IEdmEntityType)model.FindDeclaredType("TestModel.CityType");

            var addressInCity1BindableFunctionWithOverload = defaultContainer.AddActionAndActionImport(model, "AddressInCity", EdmCoreModel.Instance.GetBoolean(isNullable: true), null, true);
            var addressInCity1Action = addressInCity1BindableFunctionWithOverload.Action.AsEdmAction();

            addressInCity1Action.AddParameter("city", new EdmEntityTypeReference(cityType, isNullable: true));
            addressInCity1Action.AddParameter("address", EdmCoreModel.Instance.GetString(isNullable: true));

            var funcWithOneParamImport = defaultContainer.AddFunctionAndFunctionImport(model, "BindableFunctionWithOverload", EdmCoreModel.Instance.GetInt32(true), null, false, true);
            var funcWithOneParam       = funcWithOneParamImport.Function.AsEdmFunction();

            funcWithOneParam.AddParameter("p1", new EdmEntityTypeReference(cityType, isNullable: true));

            var funcWithTwoParamImport = defaultContainer.AddFunctionAndFunctionImport(model, "BindableFunctionWithOverload", EdmCoreModel.Instance.GetInt32(true), null, false, true);
            var funcWithTwoParam       = funcWithTwoParamImport.Function.AsEdmFunction();

            funcWithTwoParam.AddParameter("p1", new EdmEntityTypeReference(cityType, isNullable: true));
            funcWithTwoParam.AddParameter("p2", EdmCoreModel.Instance.GetString(isNullable: true));

            var testCases = new[]
            {
                new
                {
                    DebugDescription = "No always bindable operations in payload",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)"
                        },
                    }
                },
                new
                {
                    DebugDescription = "Always bindable operations from default container and always bindable function group in payload",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload", Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload"
                        },
                    }
                },
                new
                {
                    DebugDescription = "Always bindable operations and function group with namespace from default container in payload",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload", Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload"
                        },
                    }
                },
                new
                {
                    DebugDescription = "Always bindable operations from non-default container and function overload with 1 param in payload",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload(p1)\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)"
                        },
                    }
                },
                new
                {
                    DebugDescription = "Always bindable operations and function overload with 2 params, with namespace from non-default container in payload",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload(p1)\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)"
                        },
                    }
                },
                new
                {
                    DebugDescription = "All of the always bindable operations in payload",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{}," +
                                       "\"#TestModel.BindableFunctionWithOverload(p1)\":{},\"#TestModel.BindableFunctionWithOverload(p1,p2)\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)"
                        },
                    }
                },
                new
                {
                    DebugDescription = "All of the always bindable operations with namespace in payload",
                    Json             = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{}," +
                                       "\"#TestModel.BindableFunctionWithOverload(p1)\":{},\"#TestModel.BindableFunctionWithOverload(p1,p2)\":{}",
                    ExpectedServiceOperationDescriptor = new[]
                    {
                        new ServiceOperationDescriptor {
                            IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload"
                        },
                        new ServiceOperationDescriptor {
                            IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)"
                        },
                    }
                },
            };

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = testCases.Select(
                t => new PayloadReaderTestDescriptor(this.Settings)
            {
                DebugDescription = t.DebugDescription,
                PayloadEdmModel  = model,
                PayloadElement   = PayloadBuilder.Entity("TestModel.CityType")
                                   .JsonRepresentation(
                    "{" +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#DefaultContainer.Cities/$entity\"," +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.CityType\"," +
                    "\"Id\":1," +
                    "\"Name\":\"New York\"," +
                    t.Json +
                    "}")
                                   .ExpectedEntityType(cityType, cities),
                ExpectedResultPayloadElement = (tc) =>
                {
                    var entityInstance = PayloadBuilder.Entity("TestModel.CityType").
                                         PrimitiveProperty("Id", 1).
                                         PrimitiveProperty("Name", "New York").
                                         StreamProperty("Skyline", "http://odata.org/test/Cities(1)/Skyline", "http://odata.org/test/Cities(1)/Skyline").
                                         NavigationProperty("CityHall", "http://odata.org/test/Cities(1)/CityHall").
                                         NavigationProperty("DOL", "http://odata.org/test/Cities(1)/DOL").
                                         NavigationProperty("PoliceStation", "http://odata.org/test/Cities(1)/PoliceStation");
                    foreach (var op in t.ExpectedServiceOperationDescriptor)
                    {
                        entityInstance.OperationDescriptor(op);
                    }
                    return(entityInstance);
                },
                SkipTestConfiguration = tc => tc.IsRequest
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                if (testConfiguration.IsRequest)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);
                    testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize);
                }

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();

                testDescriptor.RunTest(testConfiguration);
            });
        }
        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);
            });
        }
Example #34
0
        public void ReadODataOperationErrorTest()
        {
            IEdmModel           model     = Test.OData.Utils.Metadata.TestModels.BuildTestModel();
            IEdmEntityContainer container = model.FindEntityContainer("DefaultContainer");
            IEdmEntitySet       cities    = container.FindEntitySet("Cities");
            IEdmType            cityType  = model.FindType("TestModel.CityType");

            var testCases = new[]
            {
                new
                {
                    DebugDescription  = "Metadata reference property not supported in request.",
                    Json              = "\"#operationMetadata\":{}",
                    SkipForRequest    = false,
                    SkipForResponse   = true,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_MetadataReferencePropertyInRequest"),
                },
                new
                {
                    DebugDescription  = "Duplicated metadata reference property names.",
                    Json              = "\"#TestModel.PrimitiveResultOperation\":{}, \"#TestModel.PrimitiveResultOperation\":{}",
                    SkipForRequest    = true,
                    SkipForResponse   = false,
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "#TestModel.PrimitiveResultOperation"),
                },
                new
                {
                    DebugDescription  = "Operation value must start with start array or start object.",
                    Json              = "\"#TestModel.PrimitiveResultOperation\":null",
                    SkipForRequest    = true,
                    SkipForResponse   = false,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonOperationsDeserializerUtils_OperationsPropertyMustHaveObjectValue", "#TestModel.PrimitiveResultOperation", "PrimitiveValue"),
                },
                new
                {
                    DebugDescription  = "Operation value can only have at most 1 title.",
                    Json              = "\"#TestModel.PrimitiveResultOperation\":{\"title\":\"PrimitiveResultOperation\",\"title\":\"PrimitiveResultOperation\"}",
                    SkipForRequest    = true,
                    SkipForResponse   = false,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_MultipleOptionalPropertiesInOperation", "title", "#TestModel.PrimitiveResultOperation"),
                },
                new
                {
                    DebugDescription  = "Operation value can only have at most 1 target.",
                    Json              = "\"#TestModel.PrimitiveResultOperation\":{\"target\":\"http://www.example.com/foo\",\"target\":\"http://www.example.com/foo\"}",
                    SkipForRequest    = true,
                    SkipForResponse   = false,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_MultipleOptionalPropertiesInOperation", "target", "#TestModel.PrimitiveResultOperation"),
                },
                new
                {
                    DebugDescription  = "Operation values inside an array must have target.",
                    Json              = "\"#TestModel.PrimitiveResultOperation\":[{},{}]",
                    SkipForRequest    = true,
                    SkipForResponse   = false,
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_OperationMissingTargetProperty", "#TestModel.PrimitiveResultOperation"),
                },
            };

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = testCases.Select(
                t => new PayloadReaderTestDescriptor(this.Settings)
            {
                IgnorePropertyOrder = true,
                DebugDescription    = t.DebugDescription,
                PayloadEdmModel     = model,
                PayloadElement      = PayloadBuilder.Entity("TestModel.CityType")
                                      .JsonRepresentation(
                    "{" +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#DefaultContainer.Cities/$entity\"," +
                    "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.CityType\"," +
                    "\"Id\":1," +
                    t.Json +
                    "}")
                                      .ExpectedEntityType(cityType, cities),
                ExpectedException     = t.ExpectedException,
                SkipTestConfiguration = tc => tc.IsRequest ? t.SkipForRequest : t.SkipForResponse
            });

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                if (testConfiguration.IsRequest)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);
                    testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize);
                }

                // These descriptors are already tailored specifically for Json Light and
                // do not require normalization.
                testDescriptor.TestDescriptorNormalizers.Clear();

                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void ExpandedLinkTest()
        {
            IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            // TODO: add test cases that use relative URIs

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreateDeferredNavigationLinkTestDescriptors(this.Settings, true);

            // Generate interesting payloads around the navigation property
            // Note that this will actually expand the deferred nav links as well.
            testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            IEnumerable <PayloadReaderTestDescriptor> customTestDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Expanded null entry
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.Entity("TestModel.CityType")
                                        .PrimitiveProperty("Id", 1)
                                        .ExpandedNavigationProperty("PoliceStation", PayloadBuilder.NullEntity()),
                },
                // Expanded null entry after another expanded collection link
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.Entity("TestModel.CityType")
                                        .PrimitiveProperty("Id", 1)
                                        .ExpandedNavigationProperty("CityHall", PayloadBuilder.EntitySet())
                                        .ExpandedNavigationProperty("PoliceStation", PayloadBuilder.NullEntity()),
                },
                // incorrect type at related end
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.Entity("TestModel.CityType")
                                        .PrimitiveProperty("Id", 1)
                                        .ExpandedNavigationProperty("PoliceStation", PayloadBuilder.Entity("TestModel.CityType")),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_EntryTypeNotAssignableToExpectedType", "TestModel.CityType", "TestModel.OfficeType"),
                },
                // Nested entry of depth 4 should fail because we set MaxNestingDepth = 3 below
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 1),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_MaxDepthOfNestedEntriesExceeded", "3"),
                }.InEntryWithExpandedLink(true /* isSingleton */)
                .InEntryWithExpandedLink(true)
                .InEntryWithExpandedLink(true),

                // Nested entry of depth 4 within expanded feeds should fail
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 1),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_MaxDepthOfNestedEntriesExceeded", "3"),
                }.InFeed()
                .InEntryWithExpandedLink(false /* isSingleton */)
                .InFeed()
                .InEntryWithExpandedLink(false)
                .InFeed()
                .InEntryWithExpandedLink(false),

                // Nested entry of depth 3 should succeed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 1)
                }.InEntryWithExpandedLink(true /* isSingleton */)
                .InEntryWithExpandedLink(true),

                // Nested entry of depth 3 within expanded feeds should succeed
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 1)
                }.InFeed()
                .InEntryWithExpandedLink(false /* isSingleton */)
                .InFeed()
                .InEntryWithExpandedLink(false),

                // Expanded feed with a number of child entries greater than recursive depth limit should succeed.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadDescriptor = new PayloadTestDescriptor(),
                    PayloadEdmModel   = model,
                    PayloadElement    = PayloadBuilder.EntitySet().Append(
                        PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 1),
                        PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 2),
                        PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 3),
                        PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 4),
                        PayloadBuilder.Entity("TestModel.Person").PrimitiveProperty("Id", 5)),
                }.InEntryWithExpandedLink(false /* isSingleton */)
                .InEntryWithExpandedLink(true),
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors.Concat(customTestDescriptors),
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                testConfiguration.MessageReaderSettings.MessageQuotas.MaxNestingDepth = 3;

                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void InvalidEntityReferenceLinksReaderAtomTest()
        {
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                #region Wrong name and namespace
                // Wrong name
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.LinkCollection().XmlRepresentation("<m:Ref></m:Ref>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_InvalidEntityReferenceLinksStartElement", "Ref", TestAtomConstants.ODataMetadataNamespace)
                },
                // Wrong namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.LinkCollection().XmlRepresentation("<m:ref></m:ref>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_InvalidEntityReferenceLinksStartElement", "ref", TestAtomConstants.ODataMetadataNamespace)
                },
                #endregion

                #region Duplicate error elements
                // duplicate 'm:count' element
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.LinkCollection().InlineCount(1).XmlRepresentation("<feed><m:count>1</m:count><m:count>2</m:count><m:ref id=\"http://odata.org/refid\"></m:ref></feed>"),
                    ExpectedResultCallback = tc =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ExpectedPayloadElement = PayloadBuilder.LinkCollection(),
                            ExpectedException =  ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_MultipleEntityReferenceLinksElementsWithSameName", TestAtomConstants.ODataMetadataNamespace, TestAtomConstants.ODataCountElementName)
                        }
                },

                // duplicate 'd:next' element
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.LinkCollection().NextLink("http://odata.org/next1").XmlRepresentation("<feed><d:next>http://odata.org/next1</d:next><d:next>http://odata.org/next2</d:next></feed>"),
                    ExpectedResultCallback = tc =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ExpectedPayloadElement = PayloadBuilder.LinkCollection(),
                            ExpectedException =  ODataExpectedExceptions.ODataException("ODataAtomEntityReferenceLinkDeserializer_MultipleEntityReferenceLinksElementsWithSameName", TestAtomConstants.ODataNamespace, TestAtomConstants.ODataNextLinkElementName)
                        }
                },
                #endregion Duplicate error elements

                #region Element content in string elements
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.LinkCollection().InlineCount(1).XmlRepresentation("<feed><m:count><foo></foo>1<bar /></m:count></feed>"),
                    ExpectedResultCallback = tc =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ExpectedPayloadElement = PayloadBuilder.LinkCollection(),
                            ExpectedException =  ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                        }
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.LinkCollection().NextLink("http://odata.org/next1").XmlRepresentation("<feed><d:next><foo></foo>http://odata.org/next1<bar /></d:next></feed>"),
                    ExpectedResultCallback = tc =>
                        new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings)
                        {
                            ExpectedPayloadElement = PayloadBuilder.LinkCollection(),
                            ExpectedException =  ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                        }
                },
                #endregion Element content in string elements
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (testDescriptor, testConfiguration) =>
                {
                    testDescriptor.RunTest(testConfiguration);
                });
        }
 /// <summary>
 /// Modifies a test descriptor so that it can be used in a Json Lite test configuration.
 /// </summary>
 /// <param name="testDescriptor">The test descriptor to modify.</param>
 /// <remarks>The test descriptor is modified in place, though the payload element and model are cloned prior to change.</remarks>
 public static void Fixup(PayloadReaderTestDescriptor testDescriptor)
 {
     testDescriptor.PayloadElement = testDescriptor.PayloadElement.DeepCopy();
     new JsonLightPayloadElementFixup(testDescriptor).Recurse(testDescriptor.PayloadElement);
 }
 private JsonLightPayloadElementFixup(PayloadReaderTestDescriptor testDescriptor)
 {
     this.testDescriptor = testDescriptor;
     this.payloadElementStack = new Stack<ODataPayloadElement>();
 }
        // TODO: Change the payload of null top-level properties #645
        public void NonNullablePropertiesWithNullValuesTest()
        {
            IEnumerable <NonNullablePropertyTest> testCases = new NonNullablePropertyTest[]
            {
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetString(false), TypeName = "Edm.String"
                },
                new NonNullablePropertyTest {
                    Value = "foo", DataType = EdmCoreModel.Instance.GetString(false), TypeName = "Edm.String"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetBinary(false), TypeName = "Edm.Binary"
                },
                new NonNullablePropertyTest {
                    Value = new byte[] { 1, 2, 3 }, DataType = EdmCoreModel.Instance.GetBinary(false), TypeName = "Edm.Binary"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetBoolean(false), TypeName = "Edm.Boolean"
                },
                new NonNullablePropertyTest {
                    Value = true, DataType = EdmCoreModel.Instance.GetBoolean(false), TypeName = "Edm.Boolean"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetByte(false), TypeName = "Edm.Byte"
                },
                new NonNullablePropertyTest {
                    Value = (byte)1, DataType = EdmCoreModel.Instance.GetByte(false), TypeName = "Edm.Byte"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetDateTimeOffset(false), TypeName = "Edm.DateTimeOffset"
                },
                new NonNullablePropertyTest {
                    Value = new DateTimeOffset(new DateTime(2011, 08, 31), TimeSpan.Zero), DataType = EdmCoreModel.Instance.GetDateTimeOffset(false), TypeName = "Edm.DateTimeOffset"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetDecimal(false), TypeName = "Edm.Decimal"
                },
                new NonNullablePropertyTest {
                    Value = (decimal)1.0, DataType = EdmCoreModel.Instance.GetDecimal(false), TypeName = "Edm.Decimal"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetDouble(false), TypeName = "Edm.Double"
                },
                new NonNullablePropertyTest {
                    Value = (double)1.0, DataType = EdmCoreModel.Instance.GetDouble(false), TypeName = "Edm.Double"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetSingle(false), TypeName = "Edm.Single"
                },
                new NonNullablePropertyTest {
                    Value = (float)1.0, DataType = EdmCoreModel.Instance.GetSingle(false), TypeName = "Edm.Single"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetSByte(false), TypeName = "Edm.SByte"
                },
                new NonNullablePropertyTest {
                    Value = (sbyte)1, DataType = EdmCoreModel.Instance.GetSByte(false), TypeName = "Edm.SByte"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetInt16(false), TypeName = "Edm.Int16"
                },
                new NonNullablePropertyTest {
                    Value = (Int16)1, DataType = EdmCoreModel.Instance.GetInt16(false), TypeName = "Edm.Int16"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetInt32(false), TypeName = "Edm.Int32"
                },
                new NonNullablePropertyTest {
                    Value = (Int32)1, DataType = EdmCoreModel.Instance.GetInt32(false), TypeName = "Edm.Int32"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetInt64(false), TypeName = "Edm.Int64"
                },
                new NonNullablePropertyTest {
                    Value = (Int64)1, DataType = EdmCoreModel.Instance.GetInt64(false), TypeName = "Edm.Int64"
                },
                new NonNullablePropertyTest {
                    Value = null, DataType = EdmCoreModel.Instance.GetGuid(false), TypeName = "Edm.Guid"
                },
                new NonNullablePropertyTest {
                    Value = Guid.NewGuid(), DataType = EdmCoreModel.Instance.GetGuid(false), TypeName = "Edm.Guid"
                },
            };

            IEnumerable <PayloadReaderTestDescriptor> testDescriptors =
                testCases.Select(testCase => new PayloadReaderTestDescriptor(this.Settings)
            {
                PayloadElement    = PayloadBuilder.PrimitiveValue(testCase.Value).WithTypeAnnotation(testCase.DataType),
                PayloadEdmModel   = new EdmModel().Fixup(),
                ExpectedException = testCase.Value == null
                        ? ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "value", testCase.TypeName)
                        : null,
            });

            testDescriptors = testDescriptors.Select(td => td.InProperty("propertyName"));
            testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td));

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (testDescriptor, testConfiguration) =>
            {
                if (!(testDescriptor.PayloadElement is PrimitiveProperty) &&
                    testDescriptor.ExpectedException != null)
                {
                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);
                    testDescriptor.ExpectedException = ODataExpectedExceptions.ODataException(
                        "ReaderValidationUtils_NullNamedValueForNonNullableType",
                        "propertyName",
                        testDescriptor.ExpectedException.ExpectedMessage.Arguments.ElementAt(1));
                }

                var property = testDescriptor.PayloadElement as PropertyInstance;

                testDescriptor.RunTest(testConfiguration);
            });
        }
        public void UndeclaredStreamPropertyTests()
        {
            IEdmModel model = TestModels.BuildTestModel();

            IEnumerable<UndeclaredPropertyTestCase> testCases = new[]
            {
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just edit link",
                    Json = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", null, "http://odata.org/mediaeditlink", null, null)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just read link",
                    Json = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/mediareadlink\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", "http://odata.org/mediareadlink", null, null, null)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just content type",
                    Json = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"media/contenttype\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", null, null, "media/contenttype", null)
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Just ETag",
                    Json = "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"etag\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", null, null, null, "etag")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Everything",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/mediareadlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"media/contenttype\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"etag\"",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", "http://odata.org/mediareadlink", "http://odata.org/mediaeditlink", "media/contenttype", "etag")
                },
                new UndeclaredPropertyTestCase
                {
                    DebugDescription = "Everything with custom annotations",
                    Json =
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaReadLinkAnnotationName) + "\":\"http://odata.org/mediareadlink\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation") + "\":\"value\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaContentTypeAnnotationName) + "\":\"media/contenttype\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaETagAnnotationName) + "\":\"etag\"," +
                        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", "custom.annotation2") + "\":42",
                    IsLink = true,
                    ExpectedEntity = PayloadBuilder.Entity().StreamProperty("UndeclaredProperty", "http://odata.org/mediareadlink", "http://odata.org/mediaeditlink", "media/contenttype", "etag")
                },
                //new UndeclaredPropertyTestCase
                //{
                //    DebugDescription = "Stream property with odata.type annotation",
                //    Json =
                //        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                //        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName) + "\":\"#Stream\"",
                //    IsLink = true,
                //    ExpectedEntity = PayloadBuilder.Entity(),
                //    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_UnexpectedStreamPropertyAnnotation", "UndeclaredProperty", JsonLightConstants.ODataTypeAnnotationName)
                //},
                //new UndeclaredPropertyTestCase
                //{
                //    DebugDescription = "Stream property with a value",
                //    Json =
                //        "\"" + JsonLightUtils.GetPropertyAnnotationName("UndeclaredProperty", JsonLightConstants.ODataMediaEditLinkAnnotationName) + "\":\"http://odata.org/mediaeditlink\"," +
                //        "\"UndeclaredProperty\":null",
                //    IsLink = true,
                //    ExpectedEntity = PayloadBuilder.Entity(),
                //    ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_StreamPropertyWithValue", "UndeclaredProperty")
                //},
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testCases,
                new[] { false, true },
                // Undeclared properties are only allowed in responses
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                (testCase, throwOnUndeclaredPropertyForNonOpenType, testConfiguration) =>
                {
                    var settings = testConfiguration.Format == ODataFormat.Json ? this.JsonLightSettings : this.Settings;
                    PayloadReaderTestDescriptor testDescriptor = testCase.ToTestDescriptor(settings, model, throwOnUndeclaredPropertyForNonOpenType);
                    testConfiguration = new ReaderTestConfiguration(testConfiguration);
                    if (!throwOnUndeclaredPropertyForNonOpenType)
                    {
                        testConfiguration.MessageReaderSettings.Validations &= ~ValidationKinds.ThrowOnUndeclaredPropertyForNonOpenType;
                    }

                    // These descriptors are already tailored specifically for Json Light and
                    // do not require normalization.
                    testDescriptor.TestDescriptorNormalizers.Clear();
                    testDescriptor.RunTest(testConfiguration);
                });
        }
 /// <summary>
 /// Constructor for NavigationLinkTestCaseDescriptor.
 /// </summary>
 /// <param name="settings">The settings.</param>
 public NavigationLinkTestCaseDescriptor(PayloadReaderTestDescriptor.Settings settings)
     : base(settings)
 {
 }
        /// <summary>
        /// Creates invalid error representations in ATOM (e.g., extra properties where they are not allowed,
        /// invalid property value types, etc.)
        /// </summary>
        /// <param name="settings">The test descriptor settings to use for the generated <see cref="PayloadReaderTestDescriptor"/>.</param>
        /// <returns>An enumerable of <see cref="PayloadReaderTestDescriptor"/> representing the invalid error payloads.</returns>
        private static IEnumerable<PayloadReaderTestDescriptor> CreateInvalidErrorDescriptors(PayloadReaderTestDescriptor.Settings settings)
        {
            return new PayloadReaderTestDescriptor[]
            {
                #region Duplicate error elements
                // duplicate 'm:code' element
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().Code("ErrorCode").XmlRepresentation("<m:error><m:code>ErrorCode</m:code><m:code>ErrorCode2</m:code></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomErrorDeserializer_MultipleErrorElementsWithSameName", "code")
                },
                // duplicate 'm:message' element
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().Message("ErrorMessage").XmlRepresentation("<m:error><m:message>ErrorMessage</m:message><m:message>ErrorMessage2</m:message></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomErrorDeserializer_MultipleErrorElementsWithSameName", "message")
                },
                // duplicate 'm:innererror' element
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(new ODataInternalExceptionPayload()).XmlRepresentation("<m:error><m:innererror></m:innererror><m:innererror></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomErrorDeserializer_MultipleErrorElementsWithSameName", "innererror")
                },
                // duplicate (inner) 'm:message' element
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(new ODataInternalExceptionPayload().Message("InnerMessage")).XmlRepresentation("<m:error><m:innererror><m:message>InnerMessage</m:message><m:message>InnerMessage2</m:message></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomErrorDeserializer_MultipleInnerErrorElementsWithSameName", "message")
                },
                // duplicate (inner) 'm:type' element
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(new ODataInternalExceptionPayload().TypeName("TypeName")).XmlRepresentation("<m:error><m:innererror><m:type>TypeName</m:type><m:type>TypeName2</m:type></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomErrorDeserializer_MultipleInnerErrorElementsWithSameName", "type")
                },
                // duplicate (inner) 'm:stacktrace' element
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(new ODataInternalExceptionPayload().StackTrace("StackTrace")).XmlRepresentation("<m:error><m:innererror><m:stacktrace>StackTrace</m:stacktrace><m:stacktrace>StackTrace2</m:stacktrace></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomErrorDeserializer_MultipleInnerErrorElementsWithSameName", "stacktrace")
                },
                // duplicate (inner) 'm:internalexception' element
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(new ODataInternalExceptionPayload().InnerError(new ODataInternalExceptionPayload())).XmlRepresentation("<m:error><m:innererror><m:internalexception></m:internalexception><m:internalexception></m:internalexception></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomErrorDeserializer_MultipleInnerErrorElementsWithSameName", "internalexception")
                },
                #endregion Duplicate error elements

                #region Element content in string elements
                // Element content in <m:code>
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().Code("ErrorCode").XmlRepresentation("<m:error><m:code><foo></foo>ErrorCode<bar /></m:code></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                // Element content in <m:message>
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().Message("Message").XmlRepresentation("<m:error><m:message><foo></foo>Message<bar /></m:message></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                // Element content in <m:message> (inner)
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("Message"))
                        .XmlRepresentation("<m:error><m:innererror><m:message><foo></foo>Message<bar /></m:message></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                // Element content in <m:type> (inner)
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().TypeName("Type"))
                        .XmlRepresentation("<m:error><m:innererror><m:type><foo></foo>TypeName<bar /></m:type></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                // Element content in <m:stacktrace> (inner)
                new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().StackTrace("StackTrace"))
                        .XmlRepresentation("<m:error><m:innererror><m:stacktrace><foo></foo>StackTrace<bar /></m:stacktrace></m:innererror></m:error>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("XmlReaderExtension_InvalidNodeInStringValue", "Element"),
                },
                #endregion Element content in string elements
            };
        }
        public void TopLevelErrorTest()
        {
            // we don't allow extra properties at the top-level, so the only thing to test is extra properties on inner errors
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // extra properties in inner error
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError())
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"foo\": \"bar\" } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("msg1"))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"message\": \"msg1\", \"foo\": \"bar\" } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("msg1"))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"foo\": \"bar\", \"message\": \"msg1\" } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("msg1"))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"foo1\": \"bar1\", \"message\": \"msg1\", \"foo2\": \"bar2\" } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    // NOTE: in JSON, we don't fail on unrecognized duplicate properties, but we do in JSON light.
                    DebugDescription = "Unrecognized properties should fail if duplicated.",
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().Message("msg1"))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"foo\": \"bar1\", \"message\": \"msg1\", \"foo\": \"bar2\" } } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "foo")
                },

                // extra properties in nested inner error
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(PayloadBuilder.InnerError()))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"internalexception\": { \"foo\": \"bar\" } } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(PayloadBuilder.InnerError().Message("msg1")))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"internalexception\": { \"message\": \"msg1\", \"foo\": \"bar\" } } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(PayloadBuilder.InnerError().Message("msg1")))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"internalexception\": { \"foo\": \"bar\", \"message\": \"msg1\" } } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(PayloadBuilder.InnerError().Message("msg1")))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"internalexception\": { \"foo1\": \"bar1\", \"message\": \"msg1\", \"foo2\": \"bar2\" } } } }"),
                },
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    DebugDescription = "Unrecognized properties in nested inner error should fail if duplicated.",
                    PayloadElement = PayloadBuilder.Error().InnerError(PayloadBuilder.InnerError().InnerError(PayloadBuilder.InnerError().Message("msg1")))
                        .JsonRepresentation("{ \"error\": { \"innererror\": { \"internalexception\": { \"foo\": \"bar1\", \"message\": \"msg1\", \"foo\": \"bar2\" } } } }"),
                    ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "foo")
                },
            };
            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest),
                TestReaderUtils.ODataBehaviorKinds,
                (testDescriptor, testConfiguration, behavior) =>
                {
                    // These descriptors are already tailored specifically for Json Light and 
                    // do not require normalization.
                    testDescriptor.TestDescriptorNormalizers.Clear();
                    testDescriptor.RunTest(testConfiguration.CloneAndApplyBehavior(behavior));
                });
        }