예제 #1
0
 /// <summary>
 /// Puts the specified <paramref name="payload"/> into a property.
 /// </summary>
 /// <param name="payload">The payload to put into a property. This payload must represent a simple value (primitive, complex, collection).</param>
 /// <param name="propertyName">Optional name of the property to generate.</param>
 /// <returns>A property payload with the <paramref name="payload"/> as its value.</returns>
 public static PayloadReaderTestDescriptor InProperty(this PayloadReaderTestDescriptor payload, string propertyName = null)
 {
     return(new PayloadReaderTestDescriptor(payload)
     {
         PayloadDescriptor = payload.PayloadDescriptor.InProperty(propertyName)
     });
 }
예제 #2
0
 /// <summary>
 /// Takes the <paramref name="navPropertyPayload"/> that represents a deferred navigation property and expands it by creating a new entity type,
 /// adding it to the model and then creating <paramref name="count"/> entities for the new type that act as content of the expanded link.
 /// </summary>
 /// <param name="navPropertyPayload">The deferred navigation property payload to be expanded.</param>
 /// <param name="isSingleton">true if a singleton navigation property should be expanded; otherwise false.</param>
 /// <param name="count">The number of entries to be used as expanded payload. Has to be '1' for singleton navigation properties.</param>
 /// <param name="nextLink">An optional next link to be used in an expanded link with a feed payload (requires <paramref name="isSingleton"/> to be false).</param>
 /// <returns>A new test descriptor with the expanded navigation property.</returns>
 public static PayloadReaderTestDescriptor ExpandNavigationProperty(this PayloadReaderTestDescriptor payload, bool isSingleton, uint count = 1, string nextLink = null)
 {
     return(new PayloadReaderTestDescriptor(payload)
     {
         PayloadDescriptor = payload.PayloadDescriptor.ExpandNavigationProperty(isSingleton, count, nextLink)
     });
 }
예제 #3
0
 /// <summary>
 /// Makes sure to ignore top-level feed payloads in requests if the version is greater than V1.
 /// This is needed because for feeds in requests the MS-OData spec does not define a format and we
 /// thus use the V1 format.
 /// </summary>
 /// <param name="descriptor">The test descriptor to filter.</param>
 /// <returns>
 /// The same or a new <see cref="PayloadReaderTestDescriptor"/> that ensures that top-level feed
 /// payloads are ignored in requests of versions greater than V1.
 /// </returns>
 public static PayloadReaderTestDescriptor FilterTopLevelFeed(this PayloadReaderTestDescriptor payload)
 {
     return(new PayloadReaderTestDescriptor(payload)
     {
         PayloadDescriptor = payload.PayloadDescriptor.FilterTopLevelFeed()
     });
 }
        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);
                });
        }
 /// <summary>
 /// Creates a set of interesting entity reference link instances.
 /// </summary>
 /// <param name="settings">The test descriptor settings to use.</param>
 /// <returns>List of test descriptors with interesting entity reference link instances as payload.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateEntityReferenceLinkDescriptors(PayloadReaderTestDescriptor.Settings settings)
 {
     return CreateEntityReferenceLinkValues().Select(erl =>
         new PayloadReaderTestDescriptor(settings)
         {
             PayloadElement = erl,
         });
 }
예제 #6
0
        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);
                });
        }
 /// <summary>
 /// Creates a set of test descriptors with interesting error payloads.
 /// </summary>
 /// <param name="settings">The test descriptor settings to use.</param>
 /// <returns>List of test descriptors with interesting errors as payload.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateErrorReaderTestDescriptors(PayloadReaderTestDescriptor.Settings settings)
 {
     return TestErrors.CreateErrorTestDescriptors().Select(err =>
         new PayloadReaderTestDescriptor(settings)
         {
             PayloadElement = err.PayloadElement,
             SkipTestConfiguration = tc => tc.IsRequest
         });
 }
예제 #8
0
 /// <summary>
 /// Puts the specified <paramref name="payload"/> into a primitive or complex collection.
 /// </summary>
 /// <param name="payload">The payload to put into a collection. This payload must represent a value.</param>
 /// <param name="propertiesValuesBefore">Number of properties to put in the complex value before the <paramref name="payload"/>.</param>
 /// <param name="propertiesValuesAfter">Number of properties to put in the complex value after the <paramref name="payload"/>.</param>
 /// <returns>A collection payload with the <paramref name="payload"/> as one of its properties.</returns>
 public static PayloadReaderTestDescriptor InCollection(
     this PayloadReaderTestDescriptor payload,
     int propertiesValuesBefore = 0,
     int propertiesValuesAfter  = 0)
 {
     return(new PayloadReaderTestDescriptor(payload)
     {
         PayloadDescriptor = payload.PayloadDescriptor.InCollection(propertiesValuesBefore, propertiesValuesAfter)
     });
 }
예제 #9
0
 /// <summary>
 /// Puts the specified <paramref name="payload"/> into an entity.
 /// </summary>
 /// <param name="payload">The payload to put into an entity. This payload must represent a property instance.</param>
 /// <param name="propertiesBefore">Number of properties to put in the entity before the <paramref name="payload"/>.</param>
 /// <param name="propertiesAfter">Number of properties to put in the entity after the <paramref name="payload"/>.</param>
 /// <returns>An entity payload with the <paramref name="payload"/> as one of its properties.</returns>
 public static PayloadReaderTestDescriptor InEntity(
     this PayloadReaderTestDescriptor payload,
     int propertiesBefore = 0,
     int propertiesAfter  = 0)
 {
     return(new PayloadReaderTestDescriptor(payload)
     {
         PayloadDescriptor = payload.PayloadDescriptor.InEdmEntity(propertiesBefore, propertiesAfter)
     });
 }
예제 #10
0
 /// <summary>
 /// Puts the specified <paramref name="payload"/> into an expanded link inside of a newly constructed entry.
 /// </summary>
 /// <param name="payload">The payload to be used as content for the expanded link.</param>
 /// <param name="isSingletonRelationship">true if the navigation property is of singleton cardinality; false for a cardinality many. Default is false.</param>
 /// <param name="randomDataGeneratorResolver">Random dataGeneration resolver</param>
 /// <param name="randomNumberGenerator">random number generator</param>
 /// <returns>An entry payload with an expanded link that contains the specified <paramref name="payload"/>.</returns>
 public static PayloadReaderTestDescriptor InEntryWithExpandedLink(
     this PayloadReaderTestDescriptor payload,
     bool isSingletonRelationship = false,
     IRandomDataGeneratorResolver randomDataGeneratorResolver = null,
     IRandomNumberGenerator randomNumberGenerator             = null)
 {
     return(new PayloadReaderTestDescriptor(payload)
     {
         PayloadDescriptor = payload.PayloadDescriptor.InEntryWithExpandedLink(isSingletonRelationship, randomDataGeneratorResolver, randomNumberGenerator)
     });
 }
예제 #11
0
 /// <summary>
 /// Puts the specified <paramref name="payload"/> into a feed. It accepts optional parameters to control other
 /// properties of the feed and the position of the <paramref name="payload"/> inside the feed.
 /// </summary>
 /// <param name="payload">The payload to be used inside of the feed. This must represent an entity instance payload.</param>
 /// <param name="inlineCount">An optional inline count value for the feed.</param>
 /// <param name="nextLink">An optional next-link value for the feed.</param>
 /// <param name="elementsBefore">An optional number of entries that should exist before the <paramref name="payload"/> in the feed.</param>
 /// <param name="elementsAfter">An optional number of entries that should exist after the <paramref name="payload"/> in the feed.</param>
 /// <returns>A feed payload with the <paramref name="payload"/> as one of its entities.</returns>
 public static PayloadReaderTestDescriptor InFeed(
     this PayloadReaderTestDescriptor payload,
     long?inlineCount   = null,
     string nextLink    = null,
     int elementsBefore = 0,
     int elementsAfter  = 0)
 {
     return(new PayloadReaderTestDescriptor(payload)
     {
         PayloadDescriptor = payload.PayloadDescriptor.InFeed(inlineCount, nextLink, elementsBefore, elementsAfter)
     });
 }
예제 #12
0
        /// <summary>
        /// Creates a set of interesting service document instances.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <param name="withTitles">true if workspaces and collections should have a title; otherwise false.</param>
        /// <returns>List of test descriptors with interesting service documents as payload.</returns>
        internal static IEnumerable <PayloadReaderTestDescriptor> CreateServiceDocumentDescriptors(PayloadReaderTestDescriptor.Settings settings, string baseUri, bool withTitles)
        {
            return(TestServiceDocuments.CreateServiceDocuments(withTitles, baseUri).Select(sd =>
            {
                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = sd,
                    SkipTestConfiguration = tc => tc.IsRequest         // service docs are only allowed in responses
                };

                return testDescriptor;
            }));
        }
        /// <summary>
        /// Creates a set of interesting service document instances.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <param name="withTitles">true if workspaces and collections should have a title; otherwise false.</param>
        /// <returns>List of test descriptors with interesting service documents as payload.</returns>
        internal static IEnumerable<PayloadReaderTestDescriptor> CreateServiceDocumentDescriptors(PayloadReaderTestDescriptor.Settings settings, string baseUri, bool withTitles)
        {
            return TestServiceDocuments.CreateServiceDocuments(withTitles, baseUri).Select(sd =>
                {
                    PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(settings)
                    {
                        PayloadElement = sd,
                        SkipTestConfiguration = tc => tc.IsRequest     // service docs are only allowed in responses
                    };

                    return testDescriptor;
                });
        }
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="other">The other payload test descriptor to copy</param>
 public PayloadReaderTestDescriptor(PayloadReaderTestDescriptor other)
     : base(other)
 {
     this.settings                     = other.settings;
     this.PayloadDescriptor            = new PayloadTestDescriptor(other.PayloadDescriptor);
     this.ExpectedResultPayloadElement = other.ExpectedResultPayloadElement;
     this.ExpectedException            = other.ExpectedException;
     this.PayloadNormalizers           = new List <Func <ReaderTestConfiguration, Func <ODataPayloadElement, ODataPayloadElement> > >(other.PayloadNormalizers);
     this.ExpectedResultNormalizers    = new List <Func <ReaderTestConfiguration, Func <ODataPayloadElement, ODataPayloadElement> > >(other.ExpectedResultNormalizers);
     this.UrlResolver                  = other.UrlResolver;
     this.TestMessageWrapper           = other.TestMessageWrapper;
     this.IgnorePropertyOrder          = other.IgnorePropertyOrder;
     this.TestDescriptorNormalizers    = new List <Func <ReaderTestConfiguration, Action <PayloadReaderTestDescriptor> > >(other.TestDescriptorNormalizers);
 }
예제 #15
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);
                });
        }
 /// <summary>
 /// Creates a set of interesting entity set instances along with metadata.
 /// </summary>
 /// <param name="settings">The test descriptor settings to use.</param>
 /// <param name="model">If non-null, the method creates types as needed and adds them to the model.</param>
 /// <param name="withTypeNames">true if the payloads should specify type names.</param>
 /// <returns>List of test descriptors with interesting entity instances as payload.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateEntitySetInstanceDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     EdmModel model,
     bool withTypeNames)
 {
     List<PayloadReaderTestDescriptor> testDescriptors = new List<PayloadReaderTestDescriptor>();
     foreach (var payloadDescriptor in TestFeeds.CreateEntitySetTestDescriptors(model, withTypeNames))
     {
         testDescriptors.Add(new PayloadReaderTestDescriptor(settings)
         {
             PayloadDescriptor = payloadDescriptor,
             PayloadEdmModel = payloadDescriptor.PayloadEdmModel,
             SkipTestConfiguration = tc => payloadDescriptor.SkipTestConfiguration == null ? false : payloadDescriptor.SkipTestConfiguration(tc)
         });
     }
     return testDescriptors;
 }
예제 #17
0
        internal static IEnumerable <PayloadReaderTestDescriptor> CreateEntityInstanceDescriptors(
            PayloadReaderTestDescriptor.Settings settings,
            EdmModel model,
            bool withTypeNames)
        {
            List <PayloadReaderTestDescriptor> testDescriptors = new List <PayloadReaderTestDescriptor>();

            foreach (var payloadDescriptor in TestEntityInstances.CreateEntityInstanceTestDescriptors(model, withTypeNames))
            {
                // NOTE so far we don't have version-specific entity instances so we don't have to specify a
                //      minimum version or skip function; once we do we'll have to change that
                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(settings)
                {
                    PayloadDescriptor = payloadDescriptor
                };
                testDescriptors.Add(testDescriptor);
            }
            return(testDescriptors);
        }
예제 #18
0
        /// <summary>
        /// Creates a set of interesting homogeneous collection value test descriptors along with metadata.
        /// </summary>
        /// <param name="settings">The settings for the payload reader test descriptor to use.</param>
        /// <param name="withMetadata">true if the generated test descriptors should have metadata.</param>
        /// <param name="withTypeNames">true if the collection value payloads should specify type names.</param>
        /// <param name="withExpectedType">true if an expected type annotation should be added to the generated payload element; otherwise false.</param>
        /// <param name="withcollectionName">true if the collection is not in the top level, otherwise false</param>
        /// <param name="fullSet">true if all available collection values should be returned, false if only the most interesting subset should be returned.</param>
        /// <returns>List of interesting test descriptors.</returns>
        internal static IEnumerable <PayloadReaderTestDescriptor> CreateHomogeneousCollectionValueTestDescriptors(
            PayloadReaderTestDescriptor.Settings settings,
            bool withMetadata,
            bool withTypeNames,
            bool withExpectedType,
            bool withcollectionName,
            bool fullSet = true)
        {
            EdmModel model = withMetadata ? new EdmModel() : null;
            IEnumerable <ODataPayloadElementCollection> collectionValues = TestValues.CreateHomogeneousCollectionValues(model, withTypeNames, withExpectedType, withcollectionName, fullSet);

            return(collectionValues.Select(collectionValue =>
            {
                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = collectionValue,
                    PayloadEdmModel = model
                };

                if (withExpectedType && !withTypeNames)
                {
                    // fill in the type names for the expected result payload since they will be added based on the expected type
                    testDescriptor.ExpectedResultNormalizers.Add(tc => FillTypeNamesFromTypeAnnotationsPayloadElementVisitor.Visit);
                }

                if (!withExpectedType)
                {
                    testDescriptor.ExpectedResultNormalizers.Add(
                        tc => (Func <ODataPayloadElement, ODataPayloadElement>)null);
                }

                // Do not run the test descriptor if we do not have an expected type in JSON Light because it would fail.
                testDescriptor.SkipTestConfiguration = tc => tc.Format == ODataFormat.Json && !withExpectedType;

                return testDescriptor;
            }));
        }
예제 #19
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="other"><see cref="PayloadReaderTestDescriptor"/> to initialize this instance.</param>
 public ReaderContentTypeTestDescriptor(PayloadReaderTestDescriptor other)
     : base(other)
 {
 }
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateEntityInstanceDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     EdmModel model,
     bool withTypeNames)
 {
     List<PayloadReaderTestDescriptor> testDescriptors = new List<PayloadReaderTestDescriptor>();
     foreach (var payloadDescriptor in TestEntityInstances.CreateEntityInstanceTestDescriptors(model, withTypeNames))
     {
         // NOTE so far we don't have version-specific entity instances so we don't have to specify a
         //      minimum version or skip function; once we do we'll have to change that
         PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(settings)
         {
             PayloadDescriptor = payloadDescriptor
         };
         testDescriptors.Add(testDescriptor);
     }
     return testDescriptors;
 }
        public void ServiceDocumentReaderInvalidAtomMetadataTest()
        {
            // The ExpectedExceptions in the following test descriptors only apply when ATOM metadata reading is on.
            // When ATOM metadata reading is off, invalid ATOM metadata should cause no failures, and ExpectedException is ignored.
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                // Multiple atom:title elements inside the workspace element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection("Products", baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                    <workspace>
                                                        <atom:title>Default</atom:title>
                                                        <atom:title>Default</atom:title>
                                                        <collection href='" + baseUri + @"Products'>
                                                            <atom:title>Products</atom:title>   
                                                        </collection>
                                                    </workspace>
                                                 </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentMetadataDeserializer_MultipleTitleElementsFound", "workspace"),
                },

                // Invalid value for "fixed" attribute on a categories element
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection("Products", baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                    <workspace>
                                                        <collection href='" + baseUri + @"Products'>
                                                            <atom:title>Products</atom:title>
                                                            <categories fixed='foo' scheme='http://baseschema.org'>
                                                                <atom:category term='Some Term'/>
                                                            </categories> 
                                                        </collection>
                                                    </workspace>
                                                 </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentMetadataDeserializer_InvalidFixedAttributeValue", "foo"),
                },

                // Multiple app:accept attributes inside a collection
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Products", baseUri + "Products")
                                    .AppAccept("application/atom+xml;type=entry")
                                    .AppInlineCategories("yes", null,
                                        AtomMetadataBuilder.AtomCategory("SomeTerm", "http://someschema.org/", null))))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products'>
                                                        <atom:title>Products</atom:title>
                                                        <accept>application/atom+xml;type=entry</accept>
                                                        <categories fixed='yes'>
                                                            <atom:category scheme='http://someschema.org/' term='SomeTerm'/>
                                                        </categories>
                                                        <accept>application/atom+xml;type=entry</accept>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                       ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentMetadataDeserializer_MultipleAcceptElementsFoundInCollection"),
                },
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest),
                new bool[] { true, false },
                (testDescriptor, testConfiguration, enableAtomMetadataReading) =>
                {
                    testConfiguration = new ReaderTestConfiguration(testConfiguration);
                    testConfiguration.MessageReaderSettings.EnableAtomMetadataReading = enableAtomMetadataReading;

                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);

                    if (!enableAtomMetadataReading)
                    {
                        testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveAtomMetadataFromPayloadElementVisitor.Visit);
                        testDescriptor.ExpectedException = null;
                    }

                    testDescriptor.RunTest(testConfiguration);
                });
        }
        public void EntryPayloadOrderTest()
        {
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new[]
            {
                // Nothing
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity()
                        .XmlRepresentation("<entry></entry>")
                        .PayloadOrderItems("__StartEntry__")
                },
                // Just type name after nav. link - type name should be reported first.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("MyType").NavigationProperty("Category", "http://odata.org/Category")
                        .XmlRepresentation(
                            "<entry>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Category' type='application/atom+xml;type=entry' href='http://odata.org/Category'/>" +
                                "<category term='MyType' scheme='http://docs.oasis-open.org/odata/ns/scheme'/>" +
                            "</entry>")
                        .PayloadOrderItems(
                            "TypeName",
                            "__StartEntry__",
                            "NavigationLink_Category")
                },
                // Type name properties and other things after link - type name and etag should be reported first, the rest after the link
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("MyType")
                        .ETag("bar")
                        .NavigationProperty("Category", "http://odata.org/Category")
                        .WithSelfLink("http://odata.org")
                        .PrimitiveProperty("Name", "Foo")
                        .XmlRepresentation(
                            "<entry m:etag='bar'>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Category' type='application/atom+xml;type=entry' href='http://odata.org/Category'/>" +
                                "<category term='MyType' scheme='http://docs.oasis-open.org/odata/ns/scheme'/>" +
                                "<content type='application/xml'><m:properties><d:Name>Foo</d:Name></m:properties></content>" + 
                                "<link rel='self' href='http://odata.org'/>" +
                            "</entry>")
                        .PayloadOrderItems(
                            "TypeName",
                            "ETag",
                            "__StartEntry__",
                            "NavigationLink_Category",
                            "ReadLink",
                            "Property_Name"),
                    // [Astoria-ODataLib-Integration] Parsing of URLs on OData recognized places may fail, but Astoria server doesn't
                    SkipTestConfiguration = config => config.RunBehaviorKind == TestODataBehaviorKind.WcfDataServicesServer         
                },
                // Everything before nav. link
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("MyType")
                        .ETag("bar")
                        .PrimitiveProperty("Name", "Foo")
                        .NavigationProperty("Category", "http://odata.org/Category")
                        .WithSelfLink("http://odata.org")
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsAction = true, Metadata = "/actionMetadata", Target = "http://odata.org/action" })
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsFunction = true, Metadata = "/functionMetadata", Target = "http://odata.org/function" })
                        .XmlRepresentation(
                            "<entry m:etag='bar'>" +
                                "<category term='MyType' scheme='http://docs.oasis-open.org/odata/ns/scheme'/>" +
                                "<content type='application/xml'><m:properties><d:Name>Foo</d:Name></m:properties></content>" + 
                                "<link rel='self' href='http://odata.org'/>" +
                                "<m:action metadata='/actionMetadata' target='http://odata.org/action'/>" +
                                "<m:function metadata='/functionMetadata' target='http://odata.org/function'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/relatedlinks/PoliceStation' href='http://odata.org/associationlink' type='application/xml'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Category' type='application/atom+xml;type=entry' href='http://odata.org/Category'/>" +
                            "</entry>")
                        .PayloadOrderItems(
                            "TypeName",
                            "ReadLink",
                            "ETag",
                            "Action_/actionMetadata",
                            "Function_/functionMetadata",
                            "Property_Name",
                            "__StartEntry__",
                            "NavigationLink_Category"),
                    // [Astoria-ODataLib-Integration] Parsing of URLs on OData recognized places may fail, but Astoria server doesn't
                    SkipTestConfiguration = config => config.RunBehaviorKind == TestODataBehaviorKind.WcfDataServicesServer || config.IsRequest
                },
                // Everything before nav. link - Server behavior - server ignores most of links
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("MyType")
                        .ETag("bar")
                        .PrimitiveProperty("Name", "Foo")
                        .NavigationProperty("Category", "http://odata.org/Category")
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsAction = true, Metadata = "/actionMetadata", Target = "http://odata.org/action" })
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsFunction = true, Metadata = "/functionMetadata", Target = "http://odata.org/function" })
                        .XmlRepresentation(
                            "<entry m:etag='bar'>" +
                                "<category term='MyType' scheme='http://docs.oasis-open.org/odata/ns/scheme'/>" +
                                "<content type='application/xml'><m:properties><d:Name>Foo</d:Name></m:properties></content>" + 
                                "<link rel='self' href='http://odata.org'/>" +
                                "<m:action metadata='/actionMetadata' target='http://odata.org/action'/>" +
                                "<m:function metadata='/functionMetadata' target='http://odata.org/function'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/relatedlinks/PoliceStation' href='http://odata.org/associationlink' type='application/xml'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Category' type='application/atom+xml;type=entry' href='http://odata.org/Category'/>" +
                            "</entry>")
                        .PayloadOrderItems(
                            "TypeName",
                            "ETag",
                            "Action_/actionMetadata",
                            "Function_/functionMetadata",
                            "Property_Name",
                            "__StartEntry__",
                            "NavigationLink_Category"),
                    SkipTestConfiguration = config => config.RunBehaviorKind != TestODataBehaviorKind.WcfDataServicesServer || config.IsRequest
                }, 
                // Everything between nav. links
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("MyType")
                        .ETag("bar")
                        .NavigationProperty("Order", "http://odata.org/Order")
                        .PrimitiveProperty("Name", "Foo")
                        .NavigationProperty("Category", "http://odata.org/Category")
                        .WithSelfLink("http://odata.org")
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsAction = true, Metadata = "/actionMetadata", Target = "http://odata.org/action" })
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsFunction = true, Metadata = "/functionMetadata", Target = "http://odata.org/function" })
                        .XmlRepresentation(
                            "<entry m:etag='bar'>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Order' type='application/atom+xml;type=entry' href='http://odata.org/Order'/>" +
                                "<category term='MyType' scheme='http://docs.oasis-open.org/odata/ns/scheme'/>" +
                                "<content type='application/xml'><m:properties><d:Name>Foo</d:Name></m:properties></content>" + 
                                "<link rel='self' href='http://odata.org'/>" +
                                "<m:action metadata='/actionMetadata' target='http://odata.org/action'/>" +
                                "<m:function metadata='/functionMetadata' target='http://odata.org/function'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/relatedlinks/PoliceStation' href='http://odata.org/associationlink' type='application/xml'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Category' type='application/atom+xml;type=entry' href='http://odata.org/Category'/>" +
                            "</entry>")
                        .PayloadOrderItems(
                            "TypeName",
                            "ETag",
                            "__StartEntry__",
                            "NavigationLink_Order",
                            "ReadLink",
                            "Action_/actionMetadata",
                            "Function_/functionMetadata",
                            "Property_Name",
                            "NavigationLink_Category"),
                    // [Astoria-ODataLib-Integration] Parsing of URLs on OData recognized places may fail, but Astoria server doesn't
                    SkipTestConfiguration = config => config.RunBehaviorKind == TestODataBehaviorKind.WcfDataServicesServer || config.IsRequest
                },
                // Everything between nav. links - server behavior
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.Entity("MyType")
                        .ETag("bar")
                        .NavigationProperty("Order", "http://odata.org/Order")
                        .PrimitiveProperty("Name", "Foo")
                        .NavigationProperty("Category", "http://odata.org/Category")
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsAction = true, Metadata = "/actionMetadata", Target = "http://odata.org/action" })
                        .OperationDescriptor(new ServiceOperationDescriptor() { IsFunction = true, Metadata = "/functionMetadata", Target = "http://odata.org/function" })
                        .XmlRepresentation(
                            "<entry m:etag='bar'>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Order' type='application/atom+xml;type=entry' href='http://odata.org/Order'/>" +
                                "<category term='MyType' scheme='http://docs.oasis-open.org/odata/ns/scheme'/>" +
                                "<content type='application/xml'><m:properties><d:Name>Foo</d:Name></m:properties></content>" + 
                                "<link rel='self' href='http://odata.org'/>" +
                                "<m:action metadata='/actionMetadata' target='http://odata.org/action'/>" +
                                "<m:function metadata='/functionMetadata' target='http://odata.org/function'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/relatedlinks/PoliceStation' href='http://odata.org/associationlink' type='application/xml'/>" +
                                "<link rel='http://docs.oasis-open.org/odata/ns/related/Category' type='application/atom+xml;type=entry' href='http://odata.org/Category'/>" +
                            "</entry>")
                        .PayloadOrderItems(
                            "TypeName",
                            "ETag",
                            "__StartEntry__",
                            "NavigationLink_Order",
                            "Action_/actionMetadata",
                            "Function_/functionMetadata",
                            "Property_Name",
                            "NavigationLink_Category"),
                    SkipTestConfiguration = config => config.RunBehaviorKind != TestODataBehaviorKind.WcfDataServicesServer || config.IsRequest
                },
                // EPM
                //new PayloadReaderTestDescriptor(this.Settings)
                //{
                //    PayloadElement = PayloadBuilder.Entity("TestModel.EpmEntity")
                //        .NavigationProperty("Order", "http://odata.org/Order")
                //        .PrimitiveProperty("Name", "Foo")
                //        .NavigationProperty("Orders", "http://odata.org/Orders")
                //        .PrimitiveProperty("Description", "Bart")
                //        .XmlRepresentation(
                //            "<entry>" +
                //                "<link rel='http://docs.oasis-open.org/odata/ns/related/Order' type='application/atom+xml;type=entry' href='http://odata.org/Order'/>" +
                //                "<category term='TestModel.EpmEntity' scheme='http://docs.oasis-open.org/odata/ns/scheme'/>" +
                //                "<content type='application/xml'><m:properties><d:Name>Foo</d:Name></m:properties></content>" + 
                //                "<link rel='http://docs.oasis-open.org/odata/ns/related/Orders' type='application/atom+xml;type=feed' href='http://odata.org/Orders'/>" +
                //                "<author><name>Bart</name></author>" +
                //            "</entry>")
                //        .PayloadOrderItems(
                //            "TypeName",
                //            "__StartEntry__",
                //            "NavigationLink_Order",
                //            "Property_Name",
                //            "NavigationLink_Orders",
                //            "Property_Description"),
                //    PayloadModel = model
                //}
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                TestReaderUtils.ODataBehaviorKinds,
                (testDescriptor, testConfiguration, behavior) =>
                {
                    // In WCF DS Server mode the reader reports the StartEntry as soon as it finds a type name.
                    //   Since the ETag is always on the start element it will be reported in StartEntry as well.
                    if (behavior == TestODataBehaviorKind.WcfDataServicesServer)
                    {
                        ODataPayloadElement element = testDescriptor.PayloadElement.DeepCopy();
                        PayloadOrderODataPayloadElementAnnotation payloadOrderAnnotation = element.GetAnnotation<PayloadOrderODataPayloadElementAnnotation>();
                        int startEntryPosition = 0;
                        if (payloadOrderAnnotation.PayloadItems[0] == "TypeName")
                        {
                            startEntryPosition++;
                        }

                        if (payloadOrderAnnotation.PayloadItems.Contains("ETag"))
                        {
                            payloadOrderAnnotation.PayloadItems.Remove("ETag");
                            payloadOrderAnnotation.PayloadItems.Insert(1, "ETag");
                            startEntryPosition++;
                        }

                        payloadOrderAnnotation.PayloadItems.Remove("__StartEntry__");
                        payloadOrderAnnotation.PayloadItems.Insert(startEntryPosition, "__StartEntry__");

                        testDescriptor = new PayloadReaderTestDescriptor(testDescriptor)
                        {
                            PayloadElement = element
                        };
                    }

                    // We must remove any payload normalizers since we are now supersensitive to ordering issues in this test.
                    testDescriptor.ExpectedResultNormalizers.Clear();
                    testDescriptor.RunTest(testConfiguration.CloneAndApplyBehavior(behavior));
                });
        }
        public void ServiceDocumentReaderWithAtomMetadataTest()
        {
            IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
            {
                #region tests related to atom:title
                
                // Verify that a title inside a collection is read into the Name property and (if ATOM metadata reading is enabled) the Title property of the metadata annotation.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection("Products", baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                            xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                            <workspace>
                                                <collection href='" + baseUri + @"Products'>
                                                    <atom:title>Products</atom:title>
                                                </collection>
                                            </workspace>
                                            </service>"),
                },

                // Title inside a workspace should be read when ATOM metadata reading is on, but ignored otherwise.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .AtomTitle("Default", TestAtomConstants.AtomTextConstructTextKind)
                            .ResourceCollection("Products", baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <atom:title>Default</atom:title>
                                                    <collection href='" + baseUri + @"Products'>
                                                        <atom:title>Products</atom:title>
                                                    </collection>
                                                </workspace>
                                             </service>"),
                },

                // Multiple atom:title elements inside the collection element should throw when metadata reading is both on and off.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                    <workspace>
                                                        <collection href='" + baseUri + @"Products'>
                                                            <atom:title>Products</atom:title>
                                                            <atom:title>Products</atom:title>   
                                                        </collection>
                                                    </workspace>
                                                 </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentMetadataDeserializer_MultipleTitleElementsFound", "collection"),
                },
                
                #endregion tests related to atom:title

                #region app:collection element

                // Collection element with no children.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products'>
                                                    </collection>
                                                </workspace>
                                                </service>"),
                },
                
                // Empty collection element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products' />
                                                </workspace>
                                                </service>"),
                },

                // Multiple collections
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .AtomTitle("Default", TestAtomConstants.AtomTextConstructTextKind)
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Collection1", baseUri + "Collection1")
                                    .AppAccept("image/png")
                                    .AppOutOfLineCategories("http://somecategories.com"))
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Collection2", baseUri + "Collection2")
                                    .AppAccept("image/gif")
                                    .AppOutOfLineCategories("http://othercategories.com")))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <atom:title>Default</atom:title>
                                                    <collection href='" + baseUri + @"Collection1'>
                                                        <atom:title>Collection1</atom:title>
                                                        <accept>image/png</accept>
                                                        <categories href='http://somecategories.com'/>
                                                    </collection>
                                                    <collection href='" + baseUri + @"Collection2'>
                                                        <atom:title>Collection2</atom:title>
                                                        <accept>image/gif</accept>
                                                        <categories href='http://othercategories.com'/>
                                                    </collection>
                                                </workspace>
                                             </service>"),
                },

                #endregion app:collection element

                #region app:accept and app:categories element 

                // app:accept and app:categories element inside the collection element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Products", baseUri + "Products")
                                    .AppAccept("application/atom+xml;type=entry")
                                    .AppInlineCategories("yes", null,
                                        AtomMetadataBuilder.AtomCategory("SomeTerm", "http://someschema.org/", null))))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products'>
                                                        <atom:title>Products</atom:title>
                                                        <accept>application/atom+xml;type=entry</accept>
                                                        <categories fixed='yes'>
                                                            <atom:category scheme='http://someschema.org/' term='SomeTerm'/>
                                                        </categories>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                },

                // Out of line app:categories element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .AtomTitle("Default", TestAtomConstants.AtomTextConstructTextKind)
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Products", baseUri + "Products")
                                    .AppOutOfLineCategories("http://example.com/categories")))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <atom:title>Default</atom:title>
                                                    <collection href='" + baseUri + @"Products'>
                                                        <atom:title>Products</atom:title>
                                                        <categories href='http://example.com/categories' />
                                                    </collection>
                                                </workspace>
                                              </service>"),
                },

                // Attributes of the "categories" element in a non-empty namespace should be ignored.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Products", baseUri + "Products")
                                    .AppInlineCategories(null, null,
                                        AtomMetadataBuilder.AtomCategory("SomeTerm", "http://someschema.org", "SomeLabel"))))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'
                                                xmlns:foo='http://foo.org'>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products'>
                                                        <atom:title>Products</atom:title>
                                                        <categories foo:fixed='yes' atom:scheme='http://baseschema.org'>
                                                            <atom:category term='SomeTerm' scheme='http://someschema.org' label='SomeLabel'/>
                                                        </categories>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                },
                
                #endregion app:accept and app:categories element

                #region atom:category element

                // Attributes of the "category" element in a non-empty namespace should be ignored.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Products", baseUri + "Products")
                                    .AppInlineCategories("yes", "http://baseschema.org", 
                                        AtomMetadataBuilder.AtomCategory(null, null, null))))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'
                                                xmlns:foo='http://foo.org'>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products'>
                                                        <atom:title>Products</atom:title>
                                                        <categories fixed='yes' scheme='http://baseschema.org'>
                                                            <atom:category foo:term='SomeTerm' app:scheme='http://someschema.org' atom:label='SomeLabel'/>
                                                        </categories>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                },

                // Multiple atom:category elements.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .AtomTitle("Default", TestAtomConstants.AtomTextConstructTextKind)
                            .ResourceCollection(
                                PayloadBuilder.ResourceCollection("Products", baseUri + "Products")
                                    .AppInlineCategories("no", "http://baseschema.org", 
                                        AtomMetadataBuilder.AtomCategory("FirstCategory", null, null),
                                        AtomMetadataBuilder.AtomCategory("SecondCategory", null, "SomeLabel"))))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <atom:title>Default</atom:title>
                                                    <collection href='" + baseUri + @"Products'>
                                                        <atom:title>Products</atom:title>
                                                        <categories fixed='no' scheme='http://baseschema.org'>
                                                            <atom:category term='FirstCategory'/>
                                                            <atom:category term='SecondCategory' label='SomeLabel'/>
                                                        </categories>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                },

                #endregion atom:category element

                #region extra nodes

                // comments at different places in the service document.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:cn='http://customnamespace' xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <!-- some comments -->
                                                <workspace>
                                                    <!-- more comments -->
                                                    <collection href='" + baseUri + @"Products'>
                                                       <!-- more comments -->                                                    
                                                    </collection>
                                                    <!-- more comments -->
                                                </workspace>
                                                <!-- more comments -->            
                                              </service>"),
                },

                // elements having additional irrelevant attributes 
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom' foo2='bar2'>
                                                <workspace foo='bar'>
                                                    <collection href='" + baseUri + @"Products' foo1='bar1'>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                },

                // irrelevant child elements inside a workspace or collection element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace()
                            .ResourceCollection(null, baseUri + "Products")
                            .ResourceCollection(null, baseUri + "Orders"))
                        .XmlRepresentation(@"<service xmlns:cn='http://customnamespace' xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <cn:foo foo1='bar1' />
                                                    <collection href='" + baseUri + @"Products'>
                                                        <cn:foo href='" + baseUri + @"Products'>
                                                        </cn:foo>
                                                    </collection>
                                                    <cn:foo2 foo3='bar3' />
                                                    <cn:foo2 foo3='bar3' />
                                                    <collection href='" + baseUri + @"Orders'>
                                                        <atom:foo href='" + baseUri + @"Orders'>
                                                        </atom:foo>
                                                    </collection>
                                                </workspace>
                                             </service>"),
                },

                // irrelevant element before and after the workspace 
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                       .XmlRepresentation(@"<service xmlns:cn='http://customnamespace' xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <cn:some_element>some text</cn:some_element>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products'>
                                                    </collection>
                                                </workspace>
                                                <cn:some_element>some text</cn:some_element>
                                             </service>"),
                },

                #endregion extra elements
            };

            this.CombinatorialEngineProvider.RunCombinations(
                testDescriptors,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest),
                new bool[] { true, false },
                (testDescriptor, testConfiguration, enableAtomMetadataReading) =>
                {
                    testConfiguration = new ReaderTestConfiguration(testConfiguration);
                    testConfiguration.MessageReaderSettings.EnableAtomMetadataReading = enableAtomMetadataReading;

                    testDescriptor = new PayloadReaderTestDescriptor(testDescriptor);

                    if (!enableAtomMetadataReading)
                    {
                        // 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);
                    }

                    // 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(testConfiguration));

                    testDescriptor.RunTest(testConfiguration);
                });
        }
예제 #24
0
        /// <summary>
        /// Creates the input message for the test descriptor
        /// </summary>
        /// <param name="testConfiguration">the test configuration to use</param>
        /// <param name="readerTestDescriptor">The test descriptor</param>
        /// <param name="settings">The test descriptor settings</param>
        /// <param name="applyPayloadTransformations">Whether or not to apply payload transformations</param>
        /// <returns>The message for the test</returns>
        public static TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration,
                                                     PayloadReaderTestDescriptor readerTestDescriptor,
                                                     PayloadReaderTestDescriptor.Settings settings,
                                                     bool?applyPayloadTransformations)
        {
            TestMessage testMessage;
            bool        originalApplyTransformValue = false;
            var         odataTransformFactory       = settings.PayloadTransformFactory as ODataLibPayloadTransformFactory;

            try
            {
                if (applyPayloadTransformations.HasValue && odataTransformFactory != null)
                {
                    originalApplyTransformValue          = odataTransformFactory.ApplyTransform;
                    odataTransformFactory.ApplyTransform = applyPayloadTransformations.Value;
                }

                if (readerTestDescriptor.TestDescriptorNormalizers != null)
                {
                    foreach (var testDescriptorNormalizer in readerTestDescriptor.TestDescriptorNormalizers)
                    {
                        var normalizerAction = testDescriptorNormalizer(testConfiguration);
                        if (normalizerAction != null)
                        {
                            normalizerAction(readerTestDescriptor);
                        }
                    }
                }

                MemoryStream memoryStream  = new MemoryStream(GetPayload(testConfiguration, readerTestDescriptor.PayloadNormalizers, settings, readerTestDescriptor.PayloadElement));
                TestStream   messageStream = new TestStream(memoryStream);
                if (testConfiguration.Synchronous)
                {
                    messageStream.FailAsynchronousCalls = true;
                }
                else
                {
                    messageStream.FailSynchronousCalls = true;
                }

                testMessage = TestReaderUtils.CreateInputMessageFromStream(
                    messageStream,
                    testConfiguration,
                    readerTestDescriptor.PayloadElement.GetPayloadKindFromPayloadElement(),
                    readerTestDescriptor.PayloadElement.GetCustomContentTypeHeader(), readerTestDescriptor.UrlResolver);

                if (readerTestDescriptor.TestMessageWrapper != null)
                {
                    testMessage = readerTestDescriptor.TestMessageWrapper(testMessage);
                }

                return(testMessage);
            }
            finally
            {
                if (applyPayloadTransformations.HasValue && odataTransformFactory != null)
                {
                    odataTransformFactory.ApplyTransform = originalApplyTransformValue;
                }
            }
        }
 /// <summary>
 /// Copy constructor.
 /// </summary>
 /// <param name="other">The other payload test descriptor to copy</param>
 public PayloadReaderTestDescriptor(PayloadReaderTestDescriptor other)
     : base(other)
 {
     this.settings = other.settings;
     this.PayloadDescriptor = new PayloadTestDescriptor(other.PayloadDescriptor);
     this.ExpectedResultPayloadElement = other.ExpectedResultPayloadElement;
     this.ExpectedException = other.ExpectedException;
     this.PayloadNormalizers = new List<Func<ReaderTestConfiguration, Func<ODataPayloadElement, ODataPayloadElement>>>(other.PayloadNormalizers);
     this.ExpectedResultNormalizers = new List<Func<ReaderTestConfiguration, Func<ODataPayloadElement, ODataPayloadElement>>>(other.ExpectedResultNormalizers);
     this.UrlResolver = other.UrlResolver;
     this.TestMessageWrapper = other.TestMessageWrapper;
     this.IgnorePropertyOrder = other.IgnorePropertyOrder;
     this.TestDescriptorNormalizers = new List<Func<ReaderTestConfiguration, Action<PayloadReaderTestDescriptor>>>(other.TestDescriptorNormalizers);
 }
 /// <summary>
 /// Creates a set of interesting collections with complex items test descriptors along with metadata.
 /// </summary>
 /// <param name="withTypeNames">true if the complex value payloads should specify type names.</param>
 /// <param name="fullSet">true if all available complex collections should be returned, false if only the most interesting subset should be returned.</param>
 /// <returns>List of interesting test descriptors.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateComplexCollectionTestDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     bool withTypeNames,
     bool fullSet = true)
 {
     EdmModel model = new EdmModel().Fixup();
     IEnumerable<ComplexMultiValue> complexCollections = TestValues.CreateComplexCollections(model, withTypeNames, fullSet);
     
     return complexCollections.Select(collection =>
         new PayloadReaderTestDescriptor(settings)
         {
             PayloadElement = collection,
             PayloadEdmModel = model,
             SkipTestConfiguration = tc => tc.Version < ODataVersion.V4,
         });
 }
        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);
                    });
            }
        }
예제 #28
0
        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_NullValueForNonNullableType", 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(0));
                    }

                    var property = testDescriptor.PayloadElement as PropertyInstance;
                    if (property != null && testConfiguration.Format == ODataFormat.Atom)
                    {
                        property.Name = null;
                    }

                    testDescriptor.RunTest(testConfiguration);
                });
        }
예제 #29
0
        /// <summary>
        /// Converts a <see cref="PayloadReaderTestDescriptor"/> to an in-stream error <see cref="PayloadReaderTestDescriptor"/>.
        /// </summary>
        /// <param name="descriptor">The <see cref="PayloadReaderTestDescriptor"/> to convert.</param>
        /// <param name="format">The <see cref="ODataFormat"/> the test descriptor is created for.</param>
        /// <returns>An in-stream error <see cref="PayloadReaderTestDescriptor"/> based on the <paramref name="descriptor"/>.</returns>
        /// <remarks>The <paramref name="descriptor"/> is expected to represent a top-level error payload test descriptor.</remarks>
        internal static PayloadReaderTestDescriptor ToInStreamErrorTestDescriptor(this PayloadReaderTestDescriptor descriptor, ODataFormat format)
        {
            ExceptionUtilities.CheckArgumentNotNull(descriptor, "descriptor");
            ExceptionUtilities.CheckArgumentNotNull(format, "format");
            ExceptionUtilities.Assert(descriptor.PayloadElement.ElementType == ODataPayloadElementType.ODataErrorPayload, "Only error payloads expected.");
            ExceptionUtilities.Assert(descriptor.ExpectedResultCallback == null, "No expected results callback expected.");
            ExceptionUtilities.Assert(descriptor.PayloadEdmModel == null, "No model expected.");

            // Model that defines the CityType to be used for wrapping the error payload to convert it into an in-stream error.
            IEdmModel testModel = Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            bool isValidTopLevelError = descriptor.ExpectedException == null;

            ODataPayloadElement wrappedPayloadElement = null;
            ExpectedException   expectedException     = null;

            if (format == ODataFormat.Atom)
            {
                var atomRepresentation = (XmlPayloadElementRepresentationAnnotation)descriptor.PayloadElement.GetAnnotation(typeof(XmlPayloadElementRepresentationAnnotation));
                ExceptionUtilities.Assert(atomRepresentation != null, "Expected a format-specific annotation.");
                XNode xmlRepresentation = atomRepresentation.XmlNodes.Single();

                XElement wrapperObject = new XElement(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomEntryElementName,
                                                      new XElement(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomCategoryElementName,
                                                                   new XAttribute(TestAtomConstants.AtomCategoryTermAttributeName, "TestModel.CityType"),
                                                                   new XAttribute(TestAtomConstants.AtomCategorySchemeAttributeName, TestAtomConstants.ODataSchemeNamespace),
                                                                   new XElement(TestAtomConstants.AtomXNamespace + TestAtomConstants.AtomContentElementName,
                                                                                new XAttribute(TestAtomConstants.AtomTypeAttributeName, "application/xml"),
                                                                                new XElement(TestAtomConstants.ODataMetadataXNamespace + TestAtomConstants.AtomPropertiesElementName,
                                                                                             new XElement(TestAtomConstants.ODataXNamespace + "PoliceStation", xmlRepresentation)))));

                // replace the payload and ATOM representation of the test descriptor and set the expected error message
                wrappedPayloadElement = PayloadBuilder.Entity("TestModel.CityType").XmlRepresentation(wrapperObject);

                if (isValidTopLevelError)
                {
                    // if we have a valid top-level error we expect an ODataErrorException to be thrown.
                    ODataError error = ConvertErrorPayload((ODataErrorPayload)descriptor.PayloadElement, /*forAtom*/ true);
                    expectedException = ODataExpectedExceptions.ODataErrorException(error, "ODataErrorException_GeneralError");
                }
                else
                {
                    expectedException = descriptor.ExpectedException;
                }
            }
            else if (format == ODataFormat.Json)
            {
                IEdmEntitySet  citiesSet = testModel.EntityContainer.FindEntitySet("Cities");
                IEdmEntityType cityType  = testModel.FindType("TestModel.CityType") as IEdmEntityType;

                var jsonRepresentation = (JsonPayloadElementRepresentationAnnotation)descriptor.PayloadElement.GetAnnotation(typeof(JsonPayloadElementRepresentationAnnotation));
                ExceptionUtilities.Assert(jsonRepresentation != null, "Expected a format-specific annotation.");
                JsonObject jsonObject = (JsonObject)jsonRepresentation.Json;

                // wrap the existing payload in an entity of type 'CityType'; the existing payload is used as value of the 'PoliceStation' property
                JsonObject wrapperObject = (JsonObject)JsonTextPreservingParser.ParseValue(new StringReader("{ \"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities/$entity\" }"));
                wrapperObject.Add(new JsonProperty("PoliceStation", jsonObject));

                // replace the payload and Json representation of the test descriptor and set the expected error message
                wrappedPayloadElement = PayloadBuilder.Entity("TestModel.CityType")
                                        .ExpectedEntityType(cityType, citiesSet)
                                        .JsonRepresentation(wrapperObject);

                if (isValidTopLevelError)
                {
                    // if we have a valid top-level error we expect an ODataErrorException to be thrown.
                    ODataError error = ConvertErrorPayload((ODataErrorPayload)descriptor.PayloadElement, /*forAtom*/ false);
                    expectedException = ODataExpectedExceptions.ODataErrorException(error, "ODataErrorException_GeneralError");
                }
                else
                {
                    // if the top-level error is too deeply recursive, we expect to fail in the same way for the in-stream error.
                    if (descriptor.ExpectedException.ExpectedMessage.ResourceIdentifier == "ValidationUtils_RecursionDepthLimitReached")
                    {
                        expectedException = descriptor.ExpectedException;
                    }
                    else
                    {
                        // otherwise, if the top-level error is not valid, we expect an error message that the first
                        // property of the invalid top-level error object is not defined on type OfficeType.
                        string firstPropertyName = jsonObject.Properties.First().Name;
                        expectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", firstPropertyName, "TestModel.OfficeType");
                    }
                }
            }
            else
            {
                throw new TaupoInvalidOperationException("Unsupported format for error test descriptor found: " + format.GetType().Name);
            }

            return(new PayloadReaderTestDescriptor(descriptor)
            {
                PayloadElement = wrappedPayloadElement,
                PayloadEdmModel = testModel,
                ExpectedResultPayloadElement = tc => descriptor.PayloadElement,
                ExpectedException = expectedException,
            });
        }
예제 #30
0
        public void DuplicatePropertyNamesTest()
        {
            PropertyInstance primitiveProperty = PayloadBuilder.PrimitiveProperty("DuplicateProperty", 42);
            PropertyInstance complexProperty = PayloadBuilder.Property("DuplicateProperty", 
                PayloadBuilder.ComplexValue("TestModel.DuplicateComplexType").PrimitiveProperty("Name", "foo"));
            PropertyInstance collectionProperty = PayloadBuilder.Property("DuplicateProperty",
                PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.String")).WithTypeAnnotation(EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetString(false))));

            PropertyInstance[] allProperties = new[] { primitiveProperty, complexProperty, collectionProperty };
            PropertyInstance[] propertiesWithPossibleDuplication = new[] { primitiveProperty, complexProperty };
            PropertyInstance[] propertiesWithNoDuplication = new[] { collectionProperty };

            IEnumerable<DuplicatePropertySet> duplicatePropertySets;

            // Those which may allow duplication
            duplicatePropertySets = propertiesWithPossibleDuplication
                .Variations(2).Select(properties => new DuplicatePropertySet { Properties = properties, DuplicationPotentiallyAllowed = true });

            // Then for each in those which don't allow duplication try it against all the others
            duplicatePropertySets = duplicatePropertySets.Concat(propertiesWithNoDuplication.SelectMany(
                propertyWithNoDuplication => allProperties.SelectMany(otherProperty =>
                    new[]
                    {
                        new DuplicatePropertySet { Properties = new [] { propertyWithNoDuplication, otherProperty }, DuplicationPotentiallyAllowed = false },
                        new DuplicatePropertySet { Properties = new [] { otherProperty, propertyWithNoDuplication }, DuplicationPotentiallyAllowed = false },
                    })));

            this.CombinatorialEngineProvider.RunCombinations(
                duplicatePropertySets,
                new bool[] { false, true },
                new bool[] { true, false },
                this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations,
                (duplicatePropertySet, allowDuplicateProperties, useMetadata, testConfiguration) =>
                {
                    EdmModel model = new EdmModel();
                    var complexType = model.ComplexType("DuplicateComplexType");
                    complexType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
                    model.Fixup();

                    PropertyInstance firstProperty = duplicatePropertySet.Properties.ElementAt(0);
                    PropertyInstance secondProperty = duplicatePropertySet.Properties.ElementAt(1);

                    // Non-metadata reading is not possible in JSON
                    if (!useMetadata && (testConfiguration.Format == ODataFormat.Json))
                    {
                        return;
                    }

                    // If we will have metadata then we can only allow combinations of the same kind
                    if (useMetadata)
                    {
                        if (firstProperty.ElementType != secondProperty.ElementType)
                        {
                            return;
                        }
                    }

                    // Copy the test config
                    testConfiguration = new ReaderTestConfiguration(testConfiguration);
                    if (allowDuplicateProperties)
                    {
                        testConfiguration.MessageReaderSettings.EnableODataServerBehavior();
                    }

                    // Create a descriptor with the first property
                    PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(this.Settings)
                    {
                        PayloadElement = firstProperty,
                        PayloadEdmModel = useMetadata ? model : null
                    };

                    // Now generate entity around it
                    testDescriptor = testDescriptor.InComplexValue(5, 5);

                    // Now add the second property to it
                    ((ComplexInstance)testDescriptor.PayloadElement).Add(secondProperty);

                    // [Astoria-ODataLib-Integration] Parsing of URLs on OData recognized places may fail, but Astoria server doesn't
                    // Server does not read named stream links for Atom payload therefore the expected payload needs to be normalized
                    if (testConfiguration.Format == ODataFormat.Atom)
                    {
                        testDescriptor.ExpectedResultNormalizers.Add(config => (payloadElement => WcfDsServerPayloadElementNormalizer.Normalize(payloadElement, ODataFormat.Atom, testDescriptor.PayloadEdmModel as EdmModel)));
                    }

                    // We expect failure only if we don't allow duplicates or if the property kind doesn't allow duplicates ever
                    if ((!duplicatePropertySet.DuplicationPotentiallyAllowed || !allowDuplicateProperties))
                    {
                        testDescriptor.ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "DuplicateProperty");
                    }

                    IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new PayloadReaderTestDescriptor[]
                    {
                        testDescriptor.InProperty("TopLevelProperty"),
                        testDescriptor.InProperty("ComplexProperty").InEntity(2, 2),
                        testDescriptor.InCollection(5, 5).InProperty("TopLevelCollection"),
                    };

                    this.CombinatorialEngineProvider.RunCombinations(
                        testDescriptors, 
                        td =>
                        {
                            var property = td.PayloadElement as PropertyInstance;
                            if (property != null && testConfiguration.Format == ODataFormat.Atom)
                            {
                                property.Name = null;
                            }
                            td.RunTest(testConfiguration);
                        });
                });
        }
예제 #31
0
        /// <summary>
        /// Returns the payload to be used for this test case and the specified test configuration.
        /// </summary>
        /// <param name="testConfiguration">The test configuration to use.</param>
        /// <returns>The payload to use for testing.</returns>
        public static byte[] GetPayload(
            ReaderTestConfiguration testConfiguration, 
            List<Func<ReaderTestConfiguration, Func<ODataPayloadElement, ODataPayloadElement>>> payloadNormalizers, 
            PayloadReaderTestDescriptor.Settings settings, 
            ODataPayloadElement payloadElement)
        {
            IPayloadSerializer payloadSerializer = null;

            // Apply all payload element transforms before serialization.
            IPayloadTransform<ODataPayloadElement> payloadElementTransform = settings.PayloadTransformFactory.GetTransform<ODataPayloadElement>();
            ODataPayloadElement transformedODataElement = null;
            if (payloadElementTransform.TryTransform(payloadElement, out transformedODataElement))
            {
                payloadElement = transformedODataElement;
            }

            ODataPayloadElement payloadElementToSerialize = payloadElement;

            // Apply all normalizers/fixups before serialization
            if (payloadNormalizers != null)
            {
                ODataPayloadElement payloadElementCopy = null;
                foreach (var getPayloadNormalizerFunc in payloadNormalizers)
                {
                    var normalizer = getPayloadNormalizerFunc(testConfiguration);
                    if (normalizer != null)
                    {
                        if (payloadElementCopy == null)
                        {
                            payloadElementCopy = payloadElementToSerialize.DeepCopy();
                        }

                        payloadElementCopy = normalizer(payloadElementCopy);
                    }
                }

                payloadElementToSerialize = payloadElementCopy ?? payloadElementToSerialize;
            }

            if (testConfiguration.Format == ODataFormat.Atom)
            {
                payloadSerializer = new XmlPayloadSerializer(settings.PayloadElementToXmlConverter);
            }
            else if (testConfiguration.Format == ODataFormat.Json)
            {
                // Create a copy of the payload element so that we can add annotations to it.
                payloadElementToSerialize = payloadElementToSerialize.DeepCopy();

                // Annotate elements with version and response/request as appropriate
                PayloadFormatVersionAnnotatingVisitor.AnnotateJsonLight(
                    payloadElementToSerialize,
                    testConfiguration.Version.ToDataServiceProtocolVersion(),
                    testConfiguration.IsRequest);

                payloadSerializer = new JsonPayloadSerializer(settings.PayloadElementToJsonLightConverter.ConvertToJsonLight);
            }
            else if (testConfiguration.Format == null)
            {
                if (payloadElementToSerialize.ElementType == ODataPayloadElementType.PrimitiveValue)
                {
                    PrimitiveValue primitiveValue = (PrimitiveValue)payloadElementToSerialize;
                    if (primitiveValue.ClrValue == null)
                    {
                        throw new NotSupportedException("Reading null values is not supported (since we don't support writing null values).");
                    }
                    else if (primitiveValue.ClrValue.GetType() == typeof(byte[]))
                    {
                        payloadSerializer = settings.BinaryValuePayloadElementConverter;
                    }
                    else
                    {
                        payloadSerializer = settings.TextValuePayloadElementConverter;
                    }
                }
                else if (payloadElementToSerialize.ElementType == ODataPayloadElementType.BatchRequestPayload || payloadElementToSerialize.ElementType == ODataPayloadElementType.BatchResponsePayload)
                {
                    return SerializeBatchPayload(payloadElementToSerialize, settings);
                }
                else
                {
                    throw new NotImplementedException("Default format not yet implemented for payload test descriptor and payload element type '" + payloadElementToSerialize.ElementType + "'.");
                }
            }
            else
            {
                throw new NotSupportedException("Unexpected format.");
            }

            // Default encoding is UTF8
            return payloadSerializer.SerializeToBinary(payloadElementToSerialize, null);
        }
 /// <summary>
 /// Creates a set of interesting primitive value test descriptors along with metadata.
 /// </summary>
 /// <param name="settings">The settings for payload reader test descriptor to use.</param>
 /// <param name="fullSet">true if all available primitive values should be returned, false if only the most interesting subset should be returned.</param>
 /// <returns>List of interesting test descriptors.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreatePrimitiveValueTestDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     bool fullSet = true)
 {
     EdmModel model = new EdmModel().Fixup();
     IEnumerable<PrimitiveValue> primitiveValues = TestValues.CreatePrimitiveValuesWithMetadata(fullSet);
     return primitiveValues.Select(c => new PayloadReaderTestDescriptor(settings) { PayloadElement = c, PayloadEdmModel = model });
 }
 /// <summary>
 /// Creates a set of interesting stream reference (named stream) test descriptors, optionally with metadata.
 /// </summary>
 /// <param name="settings">The settings for payload reader test descriptor to use.</param>
 /// <param name="withMetadata">true if the generated test descriptors should have metadata.</param>
 /// <returns>Enumeration of interesting stream reference test descriptors.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateStreamReferenceValueTestDescriptors(PayloadReaderTestDescriptor.Settings settings, bool withMetadata)
 {
     EdmModel model = withMetadata ? new EdmModel().Fixup() : null;
     IEnumerable<NamedStreamInstance> namedStreams = TestValues.CreateStreamReferenceValues();
     return namedStreams.Select(c => new PayloadReaderTestDescriptor(settings) { PayloadElement = c, PayloadEdmModel = model });
 }
 /// <summary>
 /// Creates a set of interesting complex value test descriptors along with metadata.
 /// </summary>
 /// <param name="settings">The settings for payload reader test descriptor to use.</param>
 /// <param name="withTypeNames">true if the complex value payloads should specify type names.</param>
 /// <param name="withMetadata">true if the generated test descriptors should have metadata.</param>
 /// <param name="fullSet">true if all available complex values should be returned, false if only the most interesting subset should be returned.</param>
 /// <returns>List of interesting test descriptors.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateComplexValueTestDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     bool withTypeNames,
     bool fullSet = true)
 {
     EdmModel model = new EdmModel().Fixup();
     IEnumerable<ComplexInstance> complexValues = TestValues.CreateComplexValues(model, withTypeNames, fullSet);
     return complexValues.Select(c => new PayloadReaderTestDescriptor(settings) { PayloadElement = c, PayloadEdmModel = model });
 }
 /// <summary>
 /// Creates a set of interesting deferred navigation link test descriptors along with metadata.
 /// </summary>
 /// <param name="settings">The settings for payload reader test descriptor to use.</param>
 /// <param name="withMetadata">true if the generated test descriptors should have metadata.</param>
 /// <returns>Enumeration of interesting test descriptors.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateDeferredNavigationLinkTestDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     bool withMetadata)
 {
     EdmModel model = withMetadata ? new EdmModel().Fixup() : null;
     return TestValues.CreateDeferredNavigationLinks().Select(navigationLink =>
         new PayloadReaderTestDescriptor(settings)
         {
             PayloadElement = navigationLink,
             PayloadEdmModel = model
         });
 }
 /// <summary>
 /// Creates a set of interesting collections test descriptors along with metadata.
 /// </summary>
 /// <param name="withTypeNames">true if the complex value payloads should specify type names.</param>
 /// <param name="fullSet">true if all available collections should be returned, false if only the most interesting subset should be returned.</param>
 /// <returns>List of interesting test descriptors.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateCollectionTestDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     bool withTypeNames,
     bool fullSet = true)
 {
     return CreatePrimitiveCollectionTestDescriptors(settings, withTypeNames, fullSet)
         .Concat(CreateComplexCollectionTestDescriptors(settings, withTypeNames, fullSet));
 }
        public void ServiceDocumentReaderWithoutAtomMetadataTest()
        {
            IEnumerable<PayloadReaderTestDescriptor> manualDescriptors = new PayloadReaderTestDescriptor[]
            {
                #region extra nodes
                // collection element in a different namespace.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<service xmlns:cn='http://customnamespace' xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <cn:collection href='" + baseUri + @"Products'>
                                                    </cn:collection>
                                                </workspace>
                                             </service>"),
                },

                // collection element in a ATOM namespace.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <atom:collection href='" + baseUri + @"Products'>
                                                    </atom:collection>
                                                </workspace>
                                             </service>"),
                },

                // irrelevant child element inside a workspace element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<service xmlns:cn='http://customnamespace' xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <cn:foo href='" + baseUri + @"Products'>
                                                    </cn:foo>
                                                </workspace>
                                             </service>"),
                },
                #endregion extra nodes

                // Invalid reader tests
                #region Empty service document.
                
                // Service document with no children.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument()
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                              </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_MissingWorkspaceElement"),
                },
                
                // Empty service.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument()
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom' />"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_MissingWorkspaceElement"),
                },

                #endregion Empty service document.

                #region service element with wrong name or namespace

                // Service element not named as 'service'.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<myservice xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                   <workspace/>
                                                 </myservice>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_ServiceDocumentRootElementWrongNameOrNamespace", "myservice", TestAtomConstants.AtomApplicationNamespace),
                },

                // Service element not in the 'app' namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<cn:service xmlns:cn='http://custom_namespace' xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                   <workspace/>
                                                 </cn:service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_ServiceDocumentRootElementWrongNameOrNamespace", "service", "http://custom_namespace"),
                },

                #endregion root element with wrong name or namespace

                #region workspace element with wrong name or namespace

                // Workspace element is not named as 'workspace'.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                   <myworkspace>
                                                      <collection href='" + baseUri + @"Products'/>
                                                   </myworkspace>
                                                 </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInServiceDocument", "myworkspace", TestAtomConstants.AtomApplicationNamespace),
                },

                // Workspace element not in the 'app' namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<service xmlns:cn='http://custom_namespace' xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                   <cn:workspace/>
                                                 </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_MissingWorkspaceElement"),
                },

                #endregion workspace element wrong name or namespace

                #region missing href
                
                // href in different namespace
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:cn='http://customnamespace' xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <collection cn:href='" + baseUri + @"Products'>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_ServiceDocumentElementUrlMustNotBeNull")
                },

                #endregion missing href

                #region multiple workspaces
                // multiple workspaces
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                    <collection href='" + baseUri + @"Products'>
                                                    </collection>
                                                </workspace>
                                                <workspace>
                                                    <collection href='Orders'>
                                                    </collection>
                                                </workspace>
                                              </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_MultipleWorkspaceElementsFound"),
                },

                #endregion multiple workspaces

                #region extra elements in ATOM publishing namespace

                // Element in 'app' namespace after the workspace element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                   <workspace/>
                                                   <foo baz='bar2'>somedata</foo>
                                                 </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInServiceDocument", "foo", TestAtomConstants.AtomApplicationNamespace),
                },

                // Element in 'app' namespace before the workspace document.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace())
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                    xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                   <foo baz='bar2'>somedata</foo>
                                                   <workspace/>
                                                 </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInServiceDocument", "foo", TestAtomConstants.AtomApplicationNamespace),
                },

                // Element in 'app' namespace before the collection element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                   <foo baz='bar2'>somedata</foo>
                                                   <collection href='" + baseUri + @"Products'>
                                                   </collection>
                                                </workspace> 
                                             </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInWorkspace", "foo", TestAtomConstants.AtomApplicationNamespace),
                },

                // Element in 'app' namespace after the collection element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                   <collection href='" + baseUri + @"Products'>
                                                   </collection>
                                                   <foo baz='bar2'>somedata</foo>
                                                </workspace> 
                                             </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInWorkspace", "foo", TestAtomConstants.AtomApplicationNamespace),
                },

                // Element in 'app' namespace inside the collection element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument().Workspace(
                        PayloadBuilder.Workspace().ResourceCollection(null, baseUri + "Products"))
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                   <collection href='" + baseUri + @"Products'>
                                                       <foo baz='bar2'>somedata</foo>                                                                     
                                                   </collection>
                                                </workspace> 
                                             </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInResourceCollection", "foo", TestAtomConstants.AtomApplicationNamespace),
                },

                // Nested workspace element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument()
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                   <workspace />
                                                </workspace> 
                                             </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInWorkspace", "workspace", TestAtomConstants.AtomApplicationNamespace),
                },

                // Nested collection element.
                new PayloadReaderTestDescriptor(this.Settings)
                {
                    PayloadElement = PayloadBuilder.ServiceDocument()
                        .XmlRepresentation(@"<service xmlns:app='http://www.w3.org/2007/app' 
                                                xmlns='http://www.w3.org/2007/app' xmlns:atom='http://www.w3.org/2005/Atom'>
                                                <workspace>
                                                   <collection href='" + baseUri + @"Products'>
                                                        <collection href='" + baseUri + @"Customers' />
                                                   </collection> 
                                                </workspace> 
                                             </service>"),
                    ExpectedException = ODataExpectedExceptions.ODataException("ODataAtomServiceDocumentDeserializer_UnexpectedElementInResourceCollection", "collection", TestAtomConstants.AtomApplicationNamespace),
                },
                #endregion extra elements in ATOM publishing namespace
            };

            this.CombinatorialEngineProvider.RunCombinations(
            manualDescriptors,
            this.ReaderTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest),
            new bool[] { true, false },
            (testDescriptor, testConfiguration, enableAtomMetadataReading) =>
            {
                testConfiguration = new ReaderTestConfiguration(testConfiguration);
                testConfiguration.MessageReaderSettings.EnableAtomMetadataReading = enableAtomMetadataReading;
                testDescriptor.RunTest(testConfiguration);
            });
        }
        /// <summary>
        /// Creates a set of interesting homogeneous collection value test descriptors along with metadata.
        /// </summary>
        /// <param name="settings">The settings for the payload reader test descriptor to use.</param>
        /// <param name="withMetadata">true if the generated test descriptors should have metadata.</param>
        /// <param name="withTypeNames">true if the collection value payloads should specify type names.</param>
        /// <param name="withExpectedType">true if an expected type annotation should be added to the generated payload element; otherwise false.</param>
        /// <param name="withcollectionName">true if the collection is not in the top level, otherwise false</param>
        /// <param name="fullSet">true if all available collection values should be returned, false if only the most interesting subset should be returned.</param>
        /// <returns>List of interesting test descriptors.</returns>
        internal static IEnumerable<PayloadReaderTestDescriptor> CreateHomogeneousCollectionValueTestDescriptors(
            PayloadReaderTestDescriptor.Settings settings,
            bool withMetadata,
            bool withTypeNames,
            bool withExpectedType,
            bool withcollectionName,
            bool fullSet = true)
        {
            EdmModel model = withMetadata ? new EdmModel() : null;
            IEnumerable<ODataPayloadElementCollection> collectionValues = TestValues.CreateHomogeneousCollectionValues(model, withTypeNames, withExpectedType, withcollectionName, fullSet);
             
            return collectionValues.Select(collectionValue =>
            {
                PayloadReaderTestDescriptor testDescriptor = new PayloadReaderTestDescriptor(settings)
                {
                    PayloadElement = collectionValue,
                    PayloadEdmModel = model
                };

                if (withExpectedType && !withTypeNames)
                {
                    // fill in the type names for the expected result payload since they will be added based on the expected type
                    testDescriptor.ExpectedResultNormalizers.Add(tc => FillTypeNamesFromTypeAnnotationsPayloadElementVisitor.Visit);
                }

                if (!withExpectedType)
                {
                    testDescriptor.ExpectedResultNormalizers.Add(
                        tc => (Func<ODataPayloadElement, ODataPayloadElement>)null);
                }

                // Do not run the test descriptor if we do not have an expected type in JSON Light because it would fail.
                testDescriptor.SkipTestConfiguration = tc => tc.Format == ODataFormat.Json && !withExpectedType;

                return testDescriptor;
            });
        }
예제 #39
0
 /// <summary>
 /// Wrapper to use the IPayloadGenerator for reader payloads.
 /// </summary>
 /// <param name="payload">The payload to generate reader input payloads for.</param>
 /// <param name="payloadGenerator">The implementation of the IPayloadGenerator to use.</param>
 /// <returns>A set of payloads that use the <paramref name="payload"/> in interesting places.</returns>
 internal static IEnumerable <PayloadReaderTestDescriptor> GenerateReaderPayloads(this IPayloadGenerator payloadGenerator, PayloadReaderTestDescriptor payload)
 {
     foreach (var payloadDescriptor in payloadGenerator.GeneratePayloads(payload.PayloadDescriptor))
     {
         yield return(new PayloadReaderTestDescriptor(payload)
         {
             PayloadDescriptor = payloadDescriptor,
             IsGeneratedPayload = !object.ReferenceEquals(payload.PayloadDescriptor, payloadDescriptor),
         });
     }
 }
 /// <summary>
 /// Creates a set of interesting expanded navigation link test descriptors along with metadata.
 /// </summary>
 /// <param name="settings">The settings for payload reader test descriptor to use.</param>
 /// <param name="withMetadata">true if the generated test descriptors should have metadata.</param>
 /// <returns>Enumeration of interesting test descriptors.</returns>
 internal static IEnumerable<PayloadReaderTestDescriptor> CreateExpandedNavigationLinkTestDescriptors(
     PayloadReaderTestDescriptor.Settings settings,
     bool withMetadata)
 {
     return (IEnumerable<PayloadReaderTestDescriptor>)CreateDeferredNavigationLinkTestDescriptors(settings, withMetadata).SelectMany(td => new[]
     {
         new PayloadReaderTestDescriptor(settings){ PayloadDescriptor = td.PayloadDescriptor.ExpandNavigationProperty(true) },
         new PayloadReaderTestDescriptor(settings){ PayloadDescriptor = td.PayloadDescriptor.ExpandNavigationProperty(false)},
         new PayloadReaderTestDescriptor(settings){ PayloadDescriptor = td.PayloadDescriptor.ExpandNavigationProperty(false, 5)},
         new PayloadReaderTestDescriptor(settings){ PayloadDescriptor = td.PayloadDescriptor.ExpandNavigationProperty(false, 5, "http://odata.org/expanded_navigation_link_next_feed_link")}
     });
 }
        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);
                });
        }
예제 #42
0
        /// <summary>
        /// Returns the serialized batch payload 
        /// </summary>
        /// <param name="batchPayload">batch payload</param>
        /// <returns>bytes representing batch payload</returns>
        private static byte[] SerializeBatchPayload(ODataPayloadElement batchPayload, PayloadReaderTestDescriptor.Settings settings)
        {
            string boundary = null;
            Byte[] bytes = null;

            Func<ODataPayloadElement, string> getBoundaryAnnotation = (batchPayloadElement) =>
            {
                var boundaryAnn = batchPayloadElement.Annotations.OfType<BatchBoundaryAnnotation>().Single();
                ExceptionUtilities.CheckObjectNotNull(boundaryAnn, "bounday annotation cannot be null");
                return boundaryAnn.BatchBoundaryInPayload;
            };

            var batchRequestPayload = batchPayload as BatchRequestPayload;
            if (batchRequestPayload != null)
            {
                boundary = getBoundaryAnnotation(batchRequestPayload);
                bytes = settings.BatchSerializer.SerializeBatchPayload(batchRequestPayload, boundary, Encoding.UTF8.WebName); // encoding assumed to be UTF8
            }
            else
            {
                var batchResponsePayload = batchPayload as BatchResponsePayload;
                boundary = getBoundaryAnnotation(batchResponsePayload);
                ExceptionUtilities.CheckObjectNotNull(batchResponsePayload, "the specified batch payload is neither a request payload nor a response");
                bytes = settings.BatchSerializer.SerializeBatchPayload(batchResponsePayload, boundary, Encoding.UTF8.WebName); // encoding assumed to be UTF8
            }

            return bytes;
        }
예제 #43
0
        public void ComplexValueIgnorePropertyNullValuesTest()
        {
            var versions = new Version[] {
                    null,
                    new Version(4, 0),
                };

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

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

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

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

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

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

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

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

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

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

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

                            PayloadReaderTestDescriptor testDescriptor = createTestDescriptor(testCase, testConfiguration);
                            testDescriptor.RunTest(testConfiguration);
                        });
                });
        }
        /// <summary>
        /// Creates error reader test descriptors with deeply nested internal exceptions.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <param name="depthLimit">The maximum depth limit for nested errors. Payloads with error depth over this limit should fail.</param>
        /// <returns>An enumerable of <see cref="PayloadReaderTestDescriptor"/> representing the deeply nested error payloads.</returns>
        internal static IEnumerable<PayloadReaderTestDescriptor> CreateErrorDeeplyNestedReaderTestDescriptors(PayloadReaderTestDescriptor.Settings settings, int depthLimit)
        {
            ODataInternalExceptionPayload deeplyNestedInnerError = PayloadBuilder.InnerError();

            // Create 'depthLimit' levels of depth (loop 'depthLimit - 1' times since we've already constructed one inner error).
            for (int index = 0; index < depthLimit - 1; index++)
            {
                deeplyNestedInnerError.InnerError(deeplyNestedInnerError.DeepCopy());
            }

            // Add one more level of depth to create an invalid payload.
            ODataInternalExceptionPayload tooDeeplyNestedInnerError = PayloadBuilder.InnerError().InnerError(deeplyNestedInnerError.DeepCopy());

            yield return new PayloadReaderTestDescriptor(settings)
            {
                PayloadElement = PayloadBuilder.Error().InnerError(deeplyNestedInnerError),
                SkipTestConfiguration = tc => tc.IsRequest
            };

            yield return new PayloadReaderTestDescriptor(settings)
            {
                PayloadElement = PayloadBuilder.Error().InnerError(tooDeeplyNestedInnerError),
                ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_RecursionDepthLimitReached", Convert.ToString(depthLimit)),
                SkipTestConfiguration = tc => tc.IsRequest
            };
        }
예제 #45
0
        /// <summary>
        /// Creates the input message for the test descriptor
        /// </summary>
        /// <param name="testConfiguration">the test configuration to use</param>
        /// <param name="readerTestDescriptor">The test descriptor</param>
        /// <param name="settings">The test descriptor settings</param>
        /// <param name="applyPayloadTransformations">Whether or not to apply payload transformations</param>
        /// <returns>The message for the test</returns>
        public static TestMessage CreateInputMessage(ReaderTestConfiguration testConfiguration, 
            PayloadReaderTestDescriptor readerTestDescriptor,
            PayloadReaderTestDescriptor.Settings settings, 
            bool? applyPayloadTransformations)
        {
            TestMessage testMessage;
            bool originalApplyTransformValue = false;           
            var odataTransformFactory = settings.PayloadTransformFactory as ODataLibPayloadTransformFactory;

            try
            {
                if (applyPayloadTransformations.HasValue && odataTransformFactory != null)
                {
                    originalApplyTransformValue = odataTransformFactory.ApplyTransform;
                    odataTransformFactory.ApplyTransform = applyPayloadTransformations.Value;
                }

                if (readerTestDescriptor.TestDescriptorNormalizers != null)
                {
                    foreach (var testDescriptorNormalizer in readerTestDescriptor.TestDescriptorNormalizers)
                    {
                        var normalizerAction = testDescriptorNormalizer(testConfiguration);
                        if (normalizerAction != null)
                        {
                            normalizerAction(readerTestDescriptor);
                        }
                    }
                }

                MemoryStream memoryStream = new MemoryStream(GetPayload(testConfiguration, readerTestDescriptor.PayloadNormalizers, settings, readerTestDescriptor.PayloadElement));
                TestStream messageStream = new TestStream(memoryStream);
                if (testConfiguration.Synchronous)
                {
                    messageStream.FailAsynchronousCalls = true;
                }
                else
                {
                    messageStream.FailSynchronousCalls = true;
                }

                testMessage = TestReaderUtils.CreateInputMessageFromStream(
                    messageStream, 
                    testConfiguration, 
                    readerTestDescriptor.PayloadElement.GetPayloadKindFromPayloadElement(),
                    readerTestDescriptor.PayloadElement.GetCustomContentTypeHeader(), readerTestDescriptor.UrlResolver);

                if (readerTestDescriptor.TestMessageWrapper != null)
                {
                    testMessage = readerTestDescriptor.TestMessageWrapper(testMessage);
                }

                return testMessage;
            }
            finally
            {
                if (applyPayloadTransformations.HasValue && odataTransformFactory != null)
                {
                    odataTransformFactory.ApplyTransform = originalApplyTransformValue;
                }
            }
        }