/// <summary>
            /// Visits a stream reference value item.
            /// </summary>
            /// <param name="streamReferenceValue">The stream reference value item to visit.</param>
            /// <returns>An ODataPayloadElement representing the stream reference value.</returns>
            protected override ODataPayloadElement VisitStreamReferenceValue(ODataStreamReferenceValue streamReferenceValue)
            {
                ExceptionUtilities.CheckArgumentNotNull(streamReferenceValue, "streamReferenceValue");

                NamedStreamInstance namedStreamInstance = (NamedStreamInstance)base.VisitStreamReferenceValue(streamReferenceValue);

                AtomStreamReferenceMetadata streamMetadata = streamReferenceValue.GetAnnotation <AtomStreamReferenceMetadata>();

                if (streamMetadata != null)
                {
                    if (streamMetadata.EditLink != null)
                    {
                        AtomLinkMetadata editMetadata = streamMetadata.EditLink;
                        namedStreamInstance.AtomNamedStreamLink(editMetadata.Href == null ? null : editMetadata.Href.OriginalString, editMetadata.Relation, editMetadata.MediaType, editMetadata.HrefLang, editMetadata.Title, ToString(editMetadata.Length));
                    }

                    if (streamMetadata.SelfLink != null)
                    {
                        AtomLinkMetadata selfMetadata = streamMetadata.SelfLink;
                        namedStreamInstance.AtomNamedStreamLink(selfMetadata.Href == null ? null : selfMetadata.Href.OriginalString, selfMetadata.Relation, selfMetadata.MediaType, selfMetadata.HrefLang, selfMetadata.Title, ToString(selfMetadata.Length));
                    }
                }

                return(namedStreamInstance);
            }
        /// <summary>
        /// Visits the payload element
        /// </summary>
        /// <param name="payloadElement">The payload element to visit</param>
        public override void Visit(NamedStreamInstance payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
            ExceptionUtilities.CheckObjectNotNull(this.currentXElement, "Current XElement is not defined");

            if (payloadElement.SourceLink != null)
            {
                XElement sourceLinkElement = CreateAtomLinkElement(
                    this.currentXElement,
                    ODataConstants.DataServicesMediaResourceNamespaceName + payloadElement.Name,
                    payloadElement.SourceLink,
                    payloadElement.SourceLinkContentType);

                PostProcessXElement(payloadElement, sourceLinkElement);
            }

            if (payloadElement.EditLink != null)
            {
                XElement editLinkElement = CreateAtomLinkElement(
                    this.currentXElement,
                    ODataConstants.DataServicesMediaResourceEditNamespaceName + payloadElement.Name,
                    payloadElement.EditLink,
                    payloadElement.EditLinkContentType,
                    payloadElement.ETag);

                PostProcessXElement(payloadElement, editLinkElement);
            }
        }
예제 #3
0
        /// <summary>
        /// Annotates the named stream with atom:link values for the 'source' link.
        /// </summary>
        /// <param name="namedStream">The named stream to annotate.</param>
        /// <param name="href">The value of the atom:link's href property</param>
        /// <param name="type">The value of the atom:link's type property</param>
        /// <param name="hrefLang">The optional value of the atom:link's hrefLang property</param>
        /// <param name="title">The optional value of the atom:link's title property</param>
        /// <param name="length">The optional value of the atom:link's length property</param>
        /// <returns>The named stream with the annotations applied.</returns>
        public static NamedStreamInstance AtomNamedStreamSourceLink(this NamedStreamInstance namedStream, string href, string type, string hrefLang = null, string title = null, string length = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(namedStream, "namedStream");

            string relation = TestAtomConstants.ODataStreamPropertyMediaResourceRelatedLinkRelationPrefix + namedStream.Name;

            return(namedStream.AtomNamedStreamLink(href, relation, type, hrefLang, title, length));
        }
예제 #4
0
            /// <summary>
            /// Visits a property item.
            /// </summary>
            /// <param name="property">The property to visit.</param>
            protected override ODataPayloadElement VisitProperty(ODataProperty property)
            {
                ExceptionUtilities.CheckArgumentNotNull(property, "property");

                object value = property.Value;

                if (value == null)
                {
                    return(new PrimitiveProperty()
                    {
                        Name = property.Name, Value = new PrimitiveValue(null, null)
                    });
                }
                else
                {
                    ODataComplexValue complexValue = value as ODataComplexValue;
                    if (complexValue != null)
                    {
                        return(new ComplexProperty(property.Name, (ComplexInstance)this.Visit(complexValue)));
                    }
                    else
                    {
                        ODataCollectionValue collectionValue = value as ODataCollectionValue;
                        if (collectionValue != null)
                        {
                            ODataPayloadElementCollection collection        = (ODataPayloadElementCollection)this.Visit(collectionValue);
                            ComplexMultiValue             complexCollection = collection as ComplexMultiValue;
                            if (complexCollection != null)
                            {
                                return(new ComplexMultiValueProperty(property.Name, complexCollection));
                            }
                            else
                            {
                                return(new PrimitiveMultiValueProperty(property.Name, (PrimitiveMultiValue)collection));
                            }
                        }
                        else
                        {
                            ODataStreamReferenceValue streamReferenceValue = value as ODataStreamReferenceValue;
                            if (streamReferenceValue != null)
                            {
                                NamedStreamInstance namedStream = (NamedStreamInstance)this.Visit(streamReferenceValue);
                                namedStream.Name = property.Name;
                                return(namedStream);
                            }
                            else
                            {
                                return(new PrimitiveProperty()
                                {
                                    Name = property.Name, Value = (PrimitiveValue)this.Visit(value)
                                });
                            }
                        }
                    }
                }
            }
예제 #5
0
        /// <summary>
        /// Visits the children of the given payload element and replaces it with a copy if any child changes
        /// </summary>
        /// <param name="payloadElement">The payload element to potentially replace</param>
        /// <returns>The original element or a copy to replace it with</returns>
        public virtual ODataPayloadElement Visit(NamedStreamInstance payloadElement)
        {
            ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
            if (this.alwaysReplace)
            {
                return(payloadElement.ReplaceWith <NamedStreamInstance>(new NamedStreamInstance()
                {
                    Name = payloadElement.Name,
                    EditLink = payloadElement.EditLink,
                    EditLinkContentType = payloadElement.EditLinkContentType,
                    ETag = payloadElement.ETag,
                    SourceLink = payloadElement.SourceLink,
                    SourceLinkContentType = payloadElement.SourceLinkContentType
                }));
            }

            return(payloadElement);
        }
예제 #6
0
        /// <summary>
        /// Generates all interesting reader payloads for the given <paramref name="streamReferencePayload"/>.
        /// </summary>
        /// <param name="streamReferencePayload">The stream reference value payload to use in the generated payloads.</param>
        /// <returns>All interesting reader payloads for the given <paramref name="streamReferencePayload"/>.</returns>
        /// <remarks>
        /// This method assumes that the <paramref name="streamReferencePayload"/> represents a single stream reference value (named stream).
        /// It will return the stream reference value as part of different entity payloads.
        /// </remarks>
        private IEnumerable <T> GenerateNamedStreamPayloads <T>(T streamReferencePayload) where T : PayloadTestDescriptor
        {
            this.Assert.IsNotNull(streamReferencePayload, "streamReferencePayload != null");
            this.Assert.IsNotNull(streamReferencePayload.PayloadElement, "streamReferencePayload.PayloadElement != null");

            NamedStreamInstance namedStreamInstance = streamReferencePayload.PayloadElement as NamedStreamInstance;

            this.Assert.IsNotNull(namedStreamInstance, "namedStreamInstance != null");

            // return the named stream as the only property in an entity (not counting the required key property)
            yield return(streamReferencePayload.InEntity());

            // return the named stream with some properties before and after it
            yield return(streamReferencePayload.InEntity(2, 2));

            // return the named stream with many properties before and after it
            yield return(streamReferencePayload.InEntity(15, 15));
        }
예제 #7
0
        /// <summary>
        /// Computes the XmlTreeAnnotation for a stream property from the <see cref="NamedStreamAtomLinkMetadataAnnotation"/>.
        /// </summary>
        /// <param name="streampProperty">The stream property to compute the Xml annotation for.</param>
        /// <param name="relation">The relation of the link we are converting</param>
        /// <returns>The <see cref="XmlTreeAnnotation"/> for the link with the specified <paramref name="relation"/>.</returns>
        private XmlTreeAnnotation GetStreamPropertyLinkXmlTreeAnnotation(NamedStreamInstance streampProperty, string relation)
        {
            // Look it up again since it was created above.
            NamedStreamAtomLinkMetadataAnnotation linkAnnotation = streampProperty.Annotations.OfType <NamedStreamAtomLinkMetadataAnnotation>().SingleOrDefault(a => a.Relation == relation);

            if (linkAnnotation == null)
            {
                return(null);
            }

            List <XmlTreeAnnotation> attributes = new List <XmlTreeAnnotation>();

            if (linkAnnotation.Href != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkHrefAttributeName, linkAnnotation.Href));
            }

            if (linkAnnotation.HrefLang != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkHrefLangAttributeName, linkAnnotation.HrefLang));
            }

            if (linkAnnotation.Length != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkLengthAttributeName, linkAnnotation.Length));
            }

            if (linkAnnotation.Relation != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkRelationAttributeName, linkAnnotation.Relation));
            }

            if (linkAnnotation.Title != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkTitleAttributeName, linkAnnotation.Title));
            }

            if (linkAnnotation.Type != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkTypeAttributeName, linkAnnotation.Type));
            }

            return(XmlTreeAnnotation.Atom(TestAtomConstants.AtomLinkElementName, null, attributes.ToArray()));
        }
        /// <summary>
        /// Normalizes named stream specific atom metadata.
        /// </summary>
        /// <param name="payloadElement">The payload element to normalize.</param>
        public override void Visit(NamedStreamInstance payloadElement)
        {
            // Edit Link
            string editRelationValue = TestAtomConstants.ODataStreamPropertyEditMediaRelatedLinkRelationPrefix + payloadElement.Name;
            NamedStreamAtomLinkMetadataAnnotation editLinkAnnotation = payloadElement.Annotations.OfType <NamedStreamAtomLinkMetadataAnnotation>().SingleOrDefault(a => a.Relation == editRelationValue);

            NormalizeNamedStreamLinkValue(
                payloadElement,
                editLinkAnnotation,
                (annotation) => annotation.Href,
                (annotation, value) => annotation.Href = value,
                (namedStream) => namedStream.EditLink,
                (namedStream, value) => namedStream.EditLink = value);

            NormalizeNamedStreamLinkValue(
                payloadElement,
                editLinkAnnotation,
                (annotation) => annotation.Type,
                (annotation, value) => annotation.Type = value,
                (namedStream) => namedStream.EditLinkContentType,
                (namedStream, value) => namedStream.EditLinkContentType = value);

            // Source Link
            string sourceRelationValue = TestAtomConstants.ODataStreamPropertyMediaResourceRelatedLinkRelationPrefix + payloadElement.Name;
            NamedStreamAtomLinkMetadataAnnotation sourceLinkAnnotation = payloadElement.Annotations.OfType <NamedStreamAtomLinkMetadataAnnotation>().SingleOrDefault(a => a.Relation == sourceRelationValue);

            NormalizeNamedStreamLinkValue(
                payloadElement,
                sourceLinkAnnotation,
                (annotation) => annotation.Href,
                (annotation, value) => annotation.Href = value,
                (namedStream) => namedStream.SourceLink,
                (namedStream, value) => namedStream.SourceLink = value);

            NormalizeNamedStreamLinkValue(
                payloadElement,
                sourceLinkAnnotation,
                (annotation) => annotation.Type,
                (annotation, value) => annotation.Type = value,
                (namedStream) => namedStream.SourceLinkContentType,
                (namedStream, value) => namedStream.SourceLinkContentType = value);

            base.Visit(payloadElement);
        }
            /// <summary>
            /// Visits a payload element whose root is a NamedStreamProperty.  this will validate the content types and etags
            /// </summary>
            /// <param name="expected">The root node of payload element being visited.</param>
            public void Visit(NamedStreamInstance expected)
            {
                ExceptionUtilities.CheckArgumentNotNull(expected, "expected");
                var observed = this.GetNextObservedElement <NamedStreamInstance>();

                using (this.Assert.WithMessage("Named stream '{0}' did not match expectation", expected.Name))
                {
                    this.Assert.AreEqual(expected.Name, observed.Name, "Stream name did not match expectation");

                    if (this.comparingJsonLightResponse && expected.EditLink == null)
                    {
                        this.Assert.IsNotNull(observed.EditLink, "Conventional template evaluation should compute the EditLink.");
                    }
                    else
                    {
                        this.Assert.AreEqual(expected.EditLink, observed.EditLink, "Edit link did not match expectation");
                    }

                    if (this.comparingJsonLightResponse && (expected.EditLinkContentType != null || expected.SourceLinkContentType != null))
                    {
                        this.Assert.IsNotNull(observed.EditLinkContentType, "Conventional template evaluation should compute the edit link content type.");
                        this.Assert.IsNotNull(observed.SourceLinkContentType, "Conventional template evaluation should compute the source link content type.");
                    }
                    else
                    {
                        this.Assert.AreEqual(expected.EditLinkContentType, observed.EditLinkContentType, "Edit link content type did not match expectation");
                        this.Assert.AreEqual(expected.SourceLinkContentType, observed.SourceLinkContentType, "Source link content type did not match expectation");
                    }

                    this.Assert.AreEqual(expected.ETag, observed.ETag, "ETag did not match expectation");

                    if (this.comparingJsonLightResponse && expected.SourceLink == null)
                    {
                        this.Assert.IsNotNull(observed.SourceLink, "Conventional template evaluation should compute the SourceLink.");
                    }
                    else
                    {
                        this.Assert.AreEqual(expected.SourceLink, observed.SourceLink, "Source link did not match expectation");
                    }

                    this.CompareAnnotations(expected.Annotations, observed.Annotations);
                }
            }
예제 #10
0
        /// <summary>
        /// Annotates the named stream with atom:link values.
        /// </summary>
        /// <param name="namedStream">The named stream to annotate.</param>
        /// <param name="href">The value of the atom:link's href property</param>
        /// <param name="rel">The value of the atom:link's rel property</param>
        /// <param name="type">The value of the atom:link's type property</param>
        /// <param name="hrefLang">The optional value of the atom:link's hrefLang property</param>
        /// <param name="title">The optional value of the atom:link's title property</param>
        /// <param name="length">The optional value of the atom:link's length property</param>
        /// <returns>The named stream with the annotations applied.</returns>
        public static NamedStreamInstance AtomNamedStreamLink(this NamedStreamInstance namedStream, string href, string rel, string type, string hrefLang = null, string title = null, string length = null)
        {
            ExceptionUtilities.CheckArgumentNotNull(namedStream, "namedStream");

            // The Test OM representation for Named Streams does not allow individual annotation of the two links that it represents.
            // Thus, we special case Named Streams, and apply two annotations to represent ATOM link metadata - one for serialization and one for comparison.

            // This annotation will replace the standard serialization of the NamedStreamInstance with the link XElement.
            var xmlAnnotation = namedStream.Annotations.OfType <XmlPayloadElementRepresentationAnnotation>().SingleOrDefault();

            if (xmlAnnotation == null)
            {
                xmlAnnotation = new XmlPayloadElementRepresentationAnnotation {
                    XmlNodes = new XNode[0]
                };
                namedStream.AddAnnotation(xmlAnnotation);
            }

            XElement linkElement = new XElement(TestAtomConstants.AtomXNamespace.GetName(TestAtomConstants.AtomLinkElementName));

            AddXAttribute(linkElement, TestAtomConstants.AtomLinkHrefAttributeName, href);
            AddXAttribute(linkElement, TestAtomConstants.AtomLinkRelationAttributeName, rel);
            AddXAttribute(linkElement, TestAtomConstants.AtomLinkTypeAttributeName, type);
            AddXAttribute(linkElement, TestAtomConstants.AtomLinkHrefLangAttributeName, hrefLang);
            AddXAttribute(linkElement, TestAtomConstants.AtomLinkTitleAttributeName, title);
            AddXAttribute(linkElement, TestAtomConstants.AtomLinkLengthAttributeName, length);

            xmlAnnotation.XmlNodes = xmlAnnotation.XmlNodes.Union(new[] { linkElement }).ToArray();

            // This annotation captures the link metadata values for comparison with test result.
            namedStream.AddAnnotation(
                new NamedStreamAtomLinkMetadataAnnotation
            {
                Href     = href,
                HrefLang = hrefLang,
                Length   = length,
                Relation = rel,
                Title    = title,
                Type     = type,
            });

            return(namedStream);
        }
예제 #11
0
        /// <summary>
        /// Creates a new ODataStreamReferenceValue for the named stream and initializes it.
        /// </summary>
        /// <param name="payloadElement">The named stream to process.</param>
        public override void Visit(NamedStreamInstance payloadElement)
        {
            var odataNamedStream = new ODataStreamReferenceValue()
            {
                ETag        = payloadElement.ETag,
                ContentType = payloadElement.EditLink == null ? payloadElement.SourceLinkContentType : payloadElement.EditLinkContentType,
                ReadLink    = payloadElement.SourceLink == null ? null : new Uri(payloadElement.SourceLink),
                EditLink    = payloadElement.EditLink == null ? null : new Uri(payloadElement.EditLink),
            };

            var odataNamedStreamProperty = new ODataProperty()
            {
                Name  = payloadElement.Name,
                Value = odataNamedStream
            };

            this.currentProperties.Add(odataNamedStreamProperty);
            base.Visit(payloadElement);
        }
예제 #12
0
        private bool TryGetNamedStream(JsonObject jsonObject, out ODataPayloadElement elem)
        {
            if (jsonObject.Properties.Count() == 1 && jsonObject.Properties.Single().Name == MediaResourceFieldName)
            {
                JsonProperty namedStreamProperty = jsonObject.Properties.Single();

                NamedStreamInstance nsi = new NamedStreamInstance(namedStreamProperty.Name);

                JsonObject streamJsonObject = (JsonObject)namedStreamProperty.Value;
                var        editLink         = streamJsonObject.Properties.SingleOrDefault(a => a.Name.Equals(EditMediaFieldName));
                if (editLink != null)
                {
                    nsi.EditLink = (string)((JsonPrimitiveValue)editLink.Value).Value;
                }

                var sourceLink = streamJsonObject.Properties.SingleOrDefault(a => a.Name.Equals(MediaSrcFieldName));
                if (sourceLink != null)
                {
                    nsi.SourceLink = (string)((JsonPrimitiveValue)sourceLink.Value).Value;
                }

                var etag = streamJsonObject.Properties.SingleOrDefault(a => a.Name.Equals(MediaETagFieldName));
                if (etag != null)
                {
                    nsi.ETag = (string)((JsonPrimitiveValue)etag.Value).Value;
                }

                var contentType = streamJsonObject.Properties.SingleOrDefault(a => a.Name.Equals(ContentTypeFieldName));
                if (contentType != null)
                {
                    nsi.SourceLinkContentType = nsi.EditLinkContentType = (string)((JsonPrimitiveValue)contentType.Value).Value;
                }

                elem = nsi;
                return(true);
            }

            elem = null;
            return(false);
        }
        /// <summary>
        /// Normalizes an named stream's Atom link property value between a NamedStreamAtomLinkMetadataAnnotation and another property.
        /// </summary>
        /// <param name="namedStream">The named stream to normalize.</param>
        /// <param name="annotation">The annotation to use for normalizing.</param>
        /// <param name="getAnnotationValue">Function for retrieving the annotation value for the link property.</param>
        /// <param name="setAnnotationValue">Delegate for setting the annotation value for the link property.</param>
        /// <param name="getPropertyValue">Function for retrieving the property value for the link property.</param>
        /// <param name="setPropertyValue">Delegate for setting the property value for the link property.</param>
        private void NormalizeNamedStreamLinkValue(
            NamedStreamInstance namedStream,
            NamedStreamAtomLinkMetadataAnnotation annotation,
            Func <NamedStreamAtomLinkMetadataAnnotation, string> getAnnotationValue,
            Action <NamedStreamAtomLinkMetadataAnnotation, string> setAnnotationValue,
            Func <NamedStreamInstance, string> getPropertyValue,
            Action <NamedStreamInstance, string> setPropertyValue)
        {
            string propertyValue = getPropertyValue(namedStream);

            if (propertyValue != null)
            {
                if (annotation != null)
                {
                    string annotationValue = getAnnotationValue(annotation);
                    if (annotationValue == null)
                    {
                        setAnnotationValue(annotation, propertyValue);
                    }
                    else
                    {
                        ExceptionUtilities.Assert(propertyValue == annotationValue, "Link '" + annotation.Relation + "' has different values : Property=" + propertyValue + ", Annotation=" + annotationValue);
                    }
                }
                else
                {
                    var newAnnotation = new NamedStreamAtomLinkMetadataAnnotation {
                        Relation = annotation.Relation
                    };
                    setAnnotationValue(newAnnotation, propertyValue);
                    namedStream.Add(newAnnotation);
                }
            }
            else if (annotation != null)
            {
                setPropertyValue(namedStream, getAnnotationValue(annotation));
            }
        }
예제 #14
0
        /// <summary>
        /// Creates a new ODataStreamReferenceValue for the named stream and initializes it.
        /// </summary>
        /// <param name="payloadElement">The named stream to process.</param>
        public override void Visit(NamedStreamInstance payloadElement)
        {
            var odataNamedStream = new ODataStreamReferenceValue()
            {
                ETag        = payloadElement.ETag,
                ContentType = payloadElement.EditLink == null ? payloadElement.SourceLinkContentType : payloadElement.EditLinkContentType,
                ReadLink    = payloadElement.SourceLink == null ? null : new Uri(payloadElement.SourceLink),
                EditLink    = payloadElement.EditLink == null ? null : new Uri(payloadElement.EditLink),
            };

            var odataNamedStreamProperty = new ODataProperty()
            {
                Name  = payloadElement.Name,
                Value = odataNamedStream
            };

            var parent = this.items.Peek();

            if (parent != null)
            {
                var entry = parent as ODataResource;
                if (entry != null)
                {
                    var properties = (List <ODataProperty>)entry.Properties;
                    properties.Add(odataNamedStreamProperty);
                }

                var complex = parent as ODataComplexValue;
                if (complex != null)
                {
                    var properties = (List <ODataProperty>)complex.Properties;
                    properties.Add(odataNamedStreamProperty);
                }
            }

            base.Visit(payloadElement);
        }
        private IEnumerable <NamedStreamInstance> DeserializeNamedStreamProperties(IEnumerable <XElement> links)
        {
            // This is a bit complex, but the goal here is to take all the edit and source links for named streams
            // and produce representations without leaving any information out. So, if duplicate edit or source links
            // with the same name are present, we want to represent them *somehow* so that later verification can fail.
            // However, edit/source links with the same name should be combined based on the order in which they appear.
            // The algorithm for this is as follows:
            //  Gather all source and edit links
            //  For each link:
            //    determine if it is an edit or source link
            //    if there is not an un-matched source/edit link with the same name:
            //      create a new instance and add it to the list of un-matched edit/source links
            //    else
            //      remove the link for the list of un-matched links, and update its properties
            //
            // find any media links and convert them into named stream properties
            var mediaLinks = links
                             .Select(link => link.Attribute(Rel))
                             .Where(rel => rel != null)
                             .Where(rel => rel.Value.StartsWith(ODataConstants.DataServicesMediaResourceEditNamespaceName, StringComparison.Ordinal) ||
                                    rel.Value.StartsWith(ODataConstants.DataServicesMediaResourceNamespaceName, StringComparison.Ordinal))
                             .Select(rel => rel.Parent)
                             .ToList();

            // go through the links, generating named-stream-instances or updating instances created on earlier passes
            // when source/edit links can be combined
            List <NamedStreamInstance> results = new List <NamedStreamInstance>(mediaLinks.Count);
            var unmatchedEditLinks             = new List <NamedStreamInstance>();
            var unmatchedSourceLinks           = new List <NamedStreamInstance>();

            foreach (var mediaLink in mediaLinks)
            {
                var    rel = mediaLink.Attribute(Rel).Value;
                string name;
                bool   isEdit;
                List <NamedStreamInstance> possibleMatches;
                List <NamedStreamInstance> unmatchedList;

                // edit links should be matched with source links, and vice versa
                if (rel.StartsWith(ODataConstants.DataServicesMediaResourceEditNamespaceName, StringComparison.Ordinal))
                {
                    isEdit          = true;
                    name            = rel.Substring(ODataConstants.DataServicesMediaResourceEditNamespaceName.Length);
                    possibleMatches = unmatchedSourceLinks;
                    unmatchedList   = unmatchedEditLinks;
                }
                else
                {
                    ExceptionUtilities.Assert(rel.StartsWith(ODataConstants.DataServicesMediaResourceNamespaceName, StringComparison.Ordinal), "Unexpected rel: {0}", rel);
                    isEdit          = false;
                    name            = rel.Substring(ODataConstants.DataServicesMediaResourceNamespaceName.Length);
                    possibleMatches = unmatchedEditLinks;
                    unmatchedList   = unmatchedSourceLinks;
                }

                var namedStreamInstance = possibleMatches.FirstOrDefault(n => n.Name == name);
                if (namedStreamInstance == null)
                {
                    namedStreamInstance = new NamedStreamInstance(name);
                    results.Add(namedStreamInstance);
                    unmatchedList.Add(namedStreamInstance);
                }
                else
                {
                    possibleMatches.Remove(namedStreamInstance);
                }

                // get the media link href
                var href = mediaLink.Attribute(Href);
                if (href != null)
                {
                    if (isEdit)
                    {
                        namedStreamInstance.EditLink = href.Value;
                    }
                    else
                    {
                        namedStreamInstance.SourceLink = href.Value;
                    }
                }

                // get the media link type
                var type = mediaLink.Attribute(Type);
                if (type != null)
                {
                    if (isEdit)
                    {
                        namedStreamInstance.EditLinkContentType = type.Value;
                    }
                    else
                    {
                        namedStreamInstance.SourceLinkContentType = type.Value;
                    }
                }

                // get the media link etag
                var etag = mediaLink.Attribute(MetadataETag);
                if (etag != null)
                {
                    namedStreamInstance.ETag = etag.Value;
                }
            }

            return(results);
        }
예제 #16
0
            /// <summary>
            /// Visits an entry item.
            /// </summary>
            /// <param name="entry">The entry to visit.</param>
            protected override ODataPayloadElement VisitEntry(ODataResource entry)
            {
                ExceptionUtilities.CheckArgumentNotNull(entry, "entry");

                EntityInstance entity = new EntityInstance(entry.TypeName, false);

                if (this.payloadContainsIdentityMetadata)
                {
                    entity.Id = entry.Id == null ? null : entry.Id.OriginalString;

                    if (entry.ReadLink != null)
                    {
                        entity.WithSelfLink(entry.ReadLink.OriginalString);
                    }

                    if (entry.EditLink != null)
                    {
                        entity.WithEditLink(entry.EditLink.OriginalString);
                    }
                }

                if (this.payloadContainsEtagPropertiesForType(entry.TypeName))
                {
                    entity.ETag = entry.ETag;
                }

                ODataStreamReferenceValue mediaResource = entry.MediaResource;

                if (mediaResource != null)
                {
                    entity = entity.AsMediaLinkEntry();
                    NamedStreamInstance namedStreamInstance = (NamedStreamInstance)this.Visit(mediaResource);
                    entity.StreamETag        = namedStreamInstance.ETag;
                    entity.StreamSourceLink  = namedStreamInstance.SourceLink;
                    entity.StreamEditLink    = namedStreamInstance.EditLink;
                    entity.StreamContentType = namedStreamInstance.SourceLinkContentType ?? namedStreamInstance.EditLinkContentType;

                    foreach (var namedStreamAtomLinkMetadataAnnotation in namedStreamInstance.Annotations.OfType <NamedStreamAtomLinkMetadataAnnotation>())
                    {
                        entity.AddAnnotation(namedStreamAtomLinkMetadataAnnotation);
                    }
                }

                // convert properties and navigation links
                entry.ProcessPropertiesPreservingPayloadOrder(
                    property => entity.Add((PropertyInstance)this.Visit(property)),
                    navigationLink => entity.Add((PropertyInstance)this.Visit(navigationLink)));

                var actions = entry.Actions;

                if (actions != null)
                {
                    foreach (var operation in actions)
                    {
                        var serviceOperationDescriptor = this.Visit(operation) as ServiceOperationDescriptor;
                        entity.Add(serviceOperationDescriptor);
                    }
                }

                var functions = entry.Functions;

                if (functions != null)
                {
                    foreach (var operation in functions)
                    {
                        var serviceOperationDescriptor = this.Visit(operation) as ServiceOperationDescriptor;
                        entity.Add(serviceOperationDescriptor);
                    }
                }

                this.ConvertSerializationTypeNameAnnotation(entry, entity);

                return(entity);
            }
 /// <summary>
 /// Visits a payload element whose root is a NamedStreamProperty.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public void Visit(NamedStreamInstance payloadElement)
 {
     throw new TaupoNotSupportedException("Json serialization does not allow element of type: " + payloadElement.ElementType.ToString());
 }
 /// <summary>
 /// Visits the payload element and determines the version of it
 /// </summary>
 /// <param name="payloadElement">The payload element to visit</param>
 public override void Visit(NamedStreamInstance payloadElement)
 {
     this.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4);
 }
예제 #19
0
        public void EntryReadingBaseUriTest()
        {
            EdmModel model = (EdmModel)Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel();

            model.Fixup();

            Action <EntityInstance, Uri, ReaderTestConfiguration>[] setUriActions = new Action <EntityInstance, Uri, ReaderTestConfiguration>[]
            {
                // Setting the read link of an entry
                (instance, uri, testConfig) =>
                {
                    instance.SetAnnotation(new SelfLinkAnnotation(UriToString(uri)));
                },
                // Setting the edit link of an entry
                (instance, uri, testConfig) =>
                {
                    instance.WithEditLink(UriToString(uri));
                },

                // Setting the navigation link of an entry
                (instance, uri, testConfig) =>
                {
                    NavigationPropertyInstance navProperty = instance.GetProperty("CityHall") as NavigationPropertyInstance;
                    this.Assert.IsNotNull(navProperty, "Did not find expected navigation property 'CityHall'.");
                    DeferredLink deferredLink = navProperty.Value as DeferredLink;
                    this.Assert.IsNotNull(deferredLink, "Did not find expected deferred link.");
                    deferredLink.UriString = UriToString(uri);
                },

                // Setting the association link of an entry
                (instance, uri, testConfig) =>
                {
                    NavigationPropertyInstance navProperty = instance.GetProperty("CityHall") as NavigationPropertyInstance;
                    this.Assert.IsNotNull(navProperty, "Did not find expected navigation property 'CityHall'.");
                    DeferredLink deferredLink = navProperty.AssociationLink as DeferredLink;
                    this.Assert.IsNotNull(deferredLink, "Did not find expected assocation link.");
                    deferredLink.UriString = UriToString(uri);
                },

                // Setting the read link of a stream property
                (instance, uri, testConfig) =>
                {
                    NamedStreamInstance namedStream = instance.GetProperty("Skyline") as NamedStreamInstance;
                    this.Assert.IsNotNull(namedStream, "Did not find expected stream property 'Skyline'.");
                    namedStream.SourceLink = UriToString(uri);
                },

                // Setting the edit link of a stream property
                (instance, uri, testConfig) =>
                {
                    NamedStreamInstance namedStream = instance.GetProperty("Skyline") as NamedStreamInstance;
                    this.Assert.IsNotNull(namedStream, "Did not find expected stream property 'Skyline'.");
                    namedStream.EditLink = UriToString(uri);
                },

                // Setting the read link of the default stream
                (instance, uri, testConfig) =>
                {
                    instance.StreamSourceLink = UriToString(uri);
                },

                // Setting the edit link of the default stream
                (instance, uri, testConfig) =>
                {
                    instance.StreamEditLink = UriToString(uri);
                },

                // TODO: add tests for operation links (not yet supported in the test infrastructure).
            };

            EntityInstance entry = PayloadBuilder.Entity("TestModel.CityWithMapType")
                                   .PrimitiveProperty("Id", 1)
                                   .Property(PayloadBuilder.NavigationProperty("CityHall", /*url*/ "http://odata.org/dummy", /*associationUrl*/ "http://odata.org/dummy").IsCollection(true))
                                   .StreamProperty("Skyline", "http://odata.org./dummy")
                                   .AsMediaLinkEntry()
                                   .StreamSourceLink("http://odata.org/dummy");

            this.CombinatorialEngineProvider.RunCombinations(
                payloadUris,
                baseUriValues,
                resolvers,
                setUriActions,
                this.ReaderTestConfigurationProvider.AtomFormatConfigurations,
                (payloadUri, baseUriValue, resolver, setUriAction, testConfiguration) =>
            {
                this.CombinatorialEngineProvider.RunCombinations(
                    new bool[] { false, true },
                    runInBatch =>
                {
                    this.RunBaseUriReadingTest(entry, setUriAction, model, payloadUri, baseUriValue, resolver, testConfiguration, runInBatch);
                });
            });
        }
        /// <summary>
        /// Creates a new ODataStreamReferenceValue for the named stream and initializes it.
        /// </summary>
        /// <param name="payloadElement">The named stream to process.</param>
        public override void Visit(NamedStreamInstance payloadElement)
        {
            var odataNamedStream = new ODataStreamReferenceValue()
            {
                ETag = payloadElement.ETag,
                ContentType = payloadElement.EditLink == null ? payloadElement.SourceLinkContentType : payloadElement.EditLinkContentType,
                ReadLink = payloadElement.SourceLink == null ? null : new Uri(payloadElement.SourceLink),
                EditLink = payloadElement.EditLink == null ? null : new Uri(payloadElement.EditLink),
            };

            var odataNamedStreamProperty = new ODataProperty()
            {
                Name = payloadElement.Name,
                Value = odataNamedStream
            };

            this.currentProperties.Add(odataNamedStreamProperty);
            base.Visit(payloadElement);
        }
 /// <summary>
 /// Removes ATOM link metadata annotations from a <see cref="NamedStreamInstance"/>.
 /// </summary>
 /// <param name="payloadElement">The named stream instance to visit.</param>
 public override void Visit(NamedStreamInstance payloadElement)
 {
     payloadElement.RemoveAnnotations(typeof(NamedStreamAtomLinkMetadataAnnotation));
     base.Visit(payloadElement);
 }
 /// <summary>
 /// Removes ATOM link metadata annotations from a <see cref="NamedStreamInstance"/>.
 /// </summary>
 /// <param name="payloadElement">The named stream instance to visit.</param>
 public override void Visit(NamedStreamInstance payloadElement)
 {
     payloadElement.RemoveAnnotations(typeof(NamedStreamAtomLinkMetadataAnnotation));
     base.Visit(payloadElement);
 }
        private IEnumerable<NamedStreamInstance> DeserializeNamedStreamProperties(IEnumerable<XElement> links)
        {
            // This is a bit complex, but the goal here is to take all the edit and source links for named streams
            // and produce representations without leaving any information out. So, if duplicate edit or source links
            // with the same name are present, we want to represent them *somehow* so that later verification can fail.
            // However, edit/source links with the same name should be combined based on the order in which they appear.
            // The algorithm for this is as follows:
            //  Gather all source and edit links
            //  For each link:
            //    determine if it is an edit or source link
            //    if there is not an un-matched source/edit link with the same name:
            //      create a new instance and add it to the list of un-matched edit/source links
            //    else
            //      remove the link for the list of un-matched links, and update its properties
            //
            // find any media links and convert them into named stream properties
            var mediaLinks = links
                .Select(link => link.Attribute(Rel))
                .Where(rel => rel != null)
                .Where(rel => rel.Value.StartsWith(ODataConstants.DataServicesMediaResourceEditNamespaceName, StringComparison.Ordinal)
                    || rel.Value.StartsWith(ODataConstants.DataServicesMediaResourceNamespaceName, StringComparison.Ordinal))
                .Select(rel => rel.Parent)
                .ToList();

            // go through the links, generating named-stream-instances or updating instances created on earlier passes
            // when source/edit links can be combined
            List<NamedStreamInstance> results = new List<NamedStreamInstance>(mediaLinks.Count);
            var unmatchedEditLinks = new List<NamedStreamInstance>();
            var unmatchedSourceLinks = new List<NamedStreamInstance>();
            foreach (var mediaLink in mediaLinks)
            {
                var rel = mediaLink.Attribute(Rel).Value;
                string name;
                bool isEdit;
                List<NamedStreamInstance> possibleMatches;
                List<NamedStreamInstance> unmatchedList;

                // edit links should be matched with source links, and vice versa
                if (rel.StartsWith(ODataConstants.DataServicesMediaResourceEditNamespaceName, StringComparison.Ordinal))
                {
                    isEdit = true;
                    name = rel.Substring(ODataConstants.DataServicesMediaResourceEditNamespaceName.Length);
                    possibleMatches = unmatchedSourceLinks;
                    unmatchedList = unmatchedEditLinks;
                }
                else
                {
                    ExceptionUtilities.Assert(rel.StartsWith(ODataConstants.DataServicesMediaResourceNamespaceName, StringComparison.Ordinal), "Unexpected rel: {0}", rel);
                    isEdit = false;
                    name = rel.Substring(ODataConstants.DataServicesMediaResourceNamespaceName.Length);
                    possibleMatches = unmatchedEditLinks;
                    unmatchedList = unmatchedSourceLinks;
                }

                var namedStreamInstance = possibleMatches.FirstOrDefault(n => n.Name == name);
                if (namedStreamInstance == null)
                {
                    namedStreamInstance = new NamedStreamInstance(name);
                    results.Add(namedStreamInstance);
                    unmatchedList.Add(namedStreamInstance);
                }
                else
                {
                    possibleMatches.Remove(namedStreamInstance);
                }

                // get the media link href
                var href = mediaLink.Attribute(Href);
                if (href != null)
                {
                    if (isEdit)
                    {
                        namedStreamInstance.EditLink = href.Value;
                    }
                    else
                    {
                        namedStreamInstance.SourceLink = href.Value;
                    }
                }

                // get the media link type
                var type = mediaLink.Attribute(Type);
                if (type != null)
                {
                    if (isEdit)
                    {
                        namedStreamInstance.EditLinkContentType = type.Value;
                    }
                    else
                    {
                        namedStreamInstance.SourceLinkContentType = type.Value;
                    }
                }

                // get the media link etag
                var etag = mediaLink.Attribute(MetadataETag);
                if (etag != null)
                {
                    namedStreamInstance.ETag = etag.Value;
                }
            }

            return results;
        }
 /// <summary>
 /// Visits the payload element and determines the version of it
 /// </summary>
 /// <param name="payloadElement">The payload element to visit</param>
 public override void Visit(NamedStreamInstance payloadElement)
 {
     this.IncreaseVersionIfRequired(DataServiceProtocolVersion.V4); 
 }
        /// <summary>
        /// Computes the XmlTreeAnnotation for a stream property from the <see cref="NamedStreamAtomLinkMetadataAnnotation"/>.
        /// </summary>
        /// <param name="streampProperty">The stream property to compute the Xml annotation for.</param>
        /// <param name="relation">The relation of the link we are converting</param>
        /// <returns>The <see cref="XmlTreeAnnotation"/> for the link with the specified <paramref name="relation"/>.</returns>
        private XmlTreeAnnotation GetStreamPropertyLinkXmlTreeAnnotation(NamedStreamInstance streampProperty, string relation)
        {
            // Look it up again since it was created above.
            NamedStreamAtomLinkMetadataAnnotation linkAnnotation = streampProperty.Annotations.OfType<NamedStreamAtomLinkMetadataAnnotation>().SingleOrDefault(a => a.Relation == relation);
            if (linkAnnotation == null)
            {
                return null;
            }

            List<XmlTreeAnnotation> attributes = new List<XmlTreeAnnotation>();

            if (linkAnnotation.Href != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkHrefAttributeName, linkAnnotation.Href));
            }

            if (linkAnnotation.HrefLang != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkHrefLangAttributeName, linkAnnotation.HrefLang));
            }

            if (linkAnnotation.Length != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkLengthAttributeName, linkAnnotation.Length));
            }

            if (linkAnnotation.Relation != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkRelationAttributeName, linkAnnotation.Relation));
            }

            if (linkAnnotation.Title != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkTitleAttributeName, linkAnnotation.Title));
            }

            if (linkAnnotation.Type != null)
            {
                attributes.Add(XmlTreeAnnotation.AtomAttribute(TestAtomConstants.AtomLinkTypeAttributeName, linkAnnotation.Type));
            }

            return XmlTreeAnnotation.Atom(TestAtomConstants.AtomLinkElementName, null, attributes.ToArray());
        }
        /// <summary>
        /// Creates a new ODataStreamReferenceValue for the named stream and initializes it.
        /// </summary>
        /// <param name="payloadElement">The named stream to process.</param>
        public override void Visit(NamedStreamInstance payloadElement)
        {
            var odataNamedStream = new ODataStreamReferenceValue()
            {
                ETag = payloadElement.ETag,
                ContentType = payloadElement.EditLink == null ? payloadElement.SourceLinkContentType : payloadElement.EditLinkContentType,
                ReadLink = payloadElement.SourceLink == null ? null : new Uri(payloadElement.SourceLink),
                EditLink = payloadElement.EditLink == null ? null : new Uri(payloadElement.EditLink),
            };

            var odataNamedStreamProperty = new ODataProperty()
            {
                Name = payloadElement.Name,
                Value = odataNamedStream
            };

            var parent = this.items.Peek();
            if (parent != null)
            {
                var entry = parent as ODataEntry;
                if (entry != null)
                {
                    var properties = (List<ODataProperty>)entry.Properties;
                    properties.Add(odataNamedStreamProperty);
                }

                var complex = parent as ODataComplexValue;
                if (complex != null)
                {
                    var properties = (List<ODataProperty>)complex.Properties;
                    properties.Add(odataNamedStreamProperty);
                }
            }
            
            base.Visit(payloadElement);
        }
예제 #27
0
 /// <summary>
 /// Visits the payload element
 /// </summary>
 /// <param name="payloadElement">The payload element to visit</param>
 public virtual void Visit(NamedStreamInstance payloadElement)
 {
     ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");
 }
        /// <summary>
        /// Asserts that two payload elements are equal.
        /// </summary>
        /// <param name="expected">The expected element</param>
        /// <param name="observed">The actual, observed element</param>
        public void Compare(ODataPayloadElement expected, ODataPayloadElement observed)
        {
            if (expected == null)
            {
                this.Assert.IsNull(observed, "Observed element must be null");
                return;
            }

            this.Assert.AreEqual(expected.ElementType, observed.ElementType, "Element types are not equal.");
            this.Assert.AreEqual(expected.Annotations.Count, observed.Annotations.Count, "Annotation counts are not equal");

            Compare(expected.Annotations, observed.Annotations);

            switch (expected.ElementType)
            {
            case ODataPayloadElementType.EntitySetInstance:
                EntitySetInstance expectedSet = expected as EntitySetInstance;
                EntitySetInstance observedSet = observed as EntitySetInstance;
                this.Assert.AreEqual(expectedSet.NextLink, observedSet.NextLink, "Next links are not equal");
                this.Assert.AreEqual(expectedSet.InlineCount, observedSet.InlineCount, "Inline counts are not equal");

                this.Assert.AreEqual(expectedSet.Count, observedSet.Count, "Entity counts are not equal");

                for (int i = 0; i < expectedSet.Count; i++)
                {
                    Compare(expectedSet[i], observedSet[i]);
                }

                break;

            case ODataPayloadElementType.EntityInstance:
                EntityInstance expectedEntity = expected as EntityInstance;
                EntityInstance observedEntity = observed as EntityInstance;
                this.Assert.AreEqual(expectedEntity.Id, observedEntity.Id, "Entity IDs are not equal");
                this.Assert.AreEqual(expectedEntity.ETag, observedEntity.ETag, "ETags are not equal");
                this.Assert.AreEqual(expectedEntity.IsNull, observedEntity.IsNull, "IsNull flags are not equal");
                this.Assert.AreEqual(expectedEntity.FullTypeName, observedEntity.FullTypeName, "FullTypeNames are not equal");
                this.Assert.AreEqual(expectedEntity.StreamContentType, observedEntity.StreamContentType, "Stream content types are not equal");
                this.Assert.AreEqual(expectedEntity.StreamEditLink, observedEntity.StreamEditLink, "Stream edit links are not equal");
                this.Assert.AreEqual(expectedEntity.StreamETag, observedEntity.StreamETag, "Stream ETags are not equal");
                this.Assert.AreEqual(expectedEntity.StreamSourceLink, observedEntity.StreamSourceLink, "Stream source links are not equal");
                this.Assert.AreEqual(expectedEntity.Properties.Count(), observedEntity.Properties.Count(), "Property counts are not equal");
                for (int i = 0; i < expectedEntity.Properties.Count(); i++)
                {
                    Compare(expectedEntity.Properties.ElementAt(i), observedEntity.Properties.ElementAt(i));
                }

                break;

            case ODataPayloadElementType.ComplexInstance:
                ComplexInstance expectedCI = expected as ComplexInstance;
                ComplexInstance observedCI = observed as ComplexInstance;
                this.Assert.AreEqual(expectedCI.IsNull, observedCI.IsNull, "IsNull flags are not equal");
                this.Assert.AreEqual(expectedCI.FullTypeName, observedCI.FullTypeName, "Full type names are not equal");
                this.Assert.AreEqual(expectedCI.Properties.Count(), observedCI.Properties.Count(), "Property counts are not equal");
                for (int i = 0; i < expectedCI.Properties.Count(); i++)
                {
                    Compare(expectedCI.Properties.ElementAt(i), observedCI.Properties.ElementAt(i));
                }

                break;

            case ODataPayloadElementType.NamedStreamInstance:
                NamedStreamInstance expectedNsi = expected as NamedStreamInstance;
                NamedStreamInstance observedNsi = observed as NamedStreamInstance;
                this.Assert.AreEqual(expectedNsi.Name, observedNsi.Name, "Stream names are not equal");
                this.Assert.AreEqual(expectedNsi.ETag, observedNsi.ETag, "Stream ETags are not equal");
                this.Assert.AreEqual(expectedNsi.EditLink, observedNsi.EditLink, "Edit links are not equal");
                this.Assert.AreEqual(expectedNsi.EditLinkContentType, observedNsi.EditLinkContentType, "Edit link content types are not equal");
                this.Assert.AreEqual(expectedNsi.SourceLink, observedNsi.SourceLink, "Source links are not equal");
                this.Assert.AreEqual(expectedNsi.SourceLinkContentType, observedNsi.SourceLinkContentType, "Source links content types are not equal");
                break;

            case ODataPayloadElementType.NavigationPropertyInstance:
                NavigationPropertyInstance expectedNav = expected as NavigationPropertyInstance;
                NavigationPropertyInstance observedNav = observed as NavigationPropertyInstance;
                Assert.AreEqual(expectedNav.Name, observedNav.Name, "Navigation property names are not equal");
                Compare(expectedNav.AssociationLink, observedNav.AssociationLink);
                Compare(expectedNav.Value, observedNav.Value);
                break;

            case ODataPayloadElementType.ComplexProperty:
                ComplexProperty expectedCP = expected as ComplexProperty;
                ComplexProperty observedCP = observed as ComplexProperty;
                this.Assert.AreEqual(expectedCP.Name, observedCP.Name, "Complex property names are not equal");
                Compare(expectedCP.Value, observedCP.Value);
                break;

            case ODataPayloadElementType.PrimitiveProperty:
                PrimitiveProperty expectedProperty = expected as PrimitiveProperty;
                PrimitiveProperty observedProperty = observed as PrimitiveProperty;
                this.Assert.AreEqual(expectedProperty.Name, observedProperty.Name, "Primitive property names are not equal");
                Compare(expectedProperty.Value, observedProperty.Value);
                break;

            case ODataPayloadElementType.PrimitiveValue:
                PrimitiveValue expectedValue = expected as PrimitiveValue;
                PrimitiveValue observedValue = observed as PrimitiveValue;
                this.Assert.AreEqual(expectedValue.IsNull, observedValue.IsNull, "IsNull flags are not equal");
                if (expectedValue.FullTypeName != null)
                {
                    if (expectedValue.FullTypeName.Equals("Edm.String"))
                    {
                        this.Assert.IsTrue(string.IsNullOrEmpty(observedValue.FullTypeName) || observedValue.FullTypeName.Equals("Edm.String"), "FullTypeName should be null or Edm.String");
                    }
                    else
                    {
                        this.Assert.AreEqual(expectedValue.FullTypeName, observedValue.FullTypeName, "Full type names are not equal");
                    }
                }
                else
                {
                    this.Assert.IsNull(observedValue.FullTypeName, "observed full type name should be null");
                }

                this.Assert.AreEqual(expectedValue.ClrValue, observedValue.ClrValue, "Clr values are not equal");
                break;

            case ODataPayloadElementType.DeferredLink:
                DeferredLink expectedLink = expected as DeferredLink;
                DeferredLink observedLink = observed as DeferredLink;
                this.Assert.AreEqual(expectedLink.UriString, observedLink.UriString, "Uris are not equal");
                break;

            case ODataPayloadElementType.ExpandedLink:
                ExpandedLink expectedExpand = expected as ExpandedLink;
                ExpandedLink observedExpand = observed as ExpandedLink;
                Compare(expectedExpand.ExpandedElement, observedExpand.ExpandedElement);
                break;

            case ODataPayloadElementType.LinkCollection:
                LinkCollection expectedLinks = expected as LinkCollection;
                LinkCollection observedLinks = observed as LinkCollection;
                this.Assert.AreEqual(expectedLinks.Count, observedLinks.Count, "Link counts are not equal");
                this.Assert.AreEqual(expectedLinks.InlineCount, observedLinks.InlineCount, "Link inline counts are not equal");
                for (int i = 0; i < expectedLinks.Count; i++)
                {
                    Compare(expectedLinks[i], observedLinks[i]);
                }

                break;

            case ODataPayloadElementType.PrimitiveMultiValueProperty:
                var expectedPrimitiveCollectionProperty = expected as PrimitiveMultiValueProperty;
                var observedPrimitiveCollectionProperty = observed as PrimitiveMultiValueProperty;
                this.Assert.AreEqual(expectedPrimitiveCollectionProperty.Name, observedPrimitiveCollectionProperty.Name, "Property names are not equal");
                this.Assert.AreEqual(expectedPrimitiveCollectionProperty.Value.FullTypeName, observedPrimitiveCollectionProperty.Value.FullTypeName, "Full type names are not equal");
                this.Assert.AreEqual(expectedPrimitiveCollectionProperty.Value.Count, observedPrimitiveCollectionProperty.Value.Count, "Collection counts are not equal");
                for (int i = 0; i < expectedPrimitiveCollectionProperty.Value.Count; i++)
                {
                    Compare(expectedPrimitiveCollectionProperty.Value[i], observedPrimitiveCollectionProperty.Value[i]);
                }

                break;

            case ODataPayloadElementType.ComplexMultiValueProperty:
                var expectedComplexCollectionProperty = expected as ComplexMultiValueProperty;
                var observedComplexCollectionProperty = observed as ComplexMultiValueProperty;
                this.Assert.AreEqual(expectedComplexCollectionProperty.Name, observedComplexCollectionProperty.Name, "Property names are not equal");
                this.Assert.AreEqual(expectedComplexCollectionProperty.Value.FullTypeName, observedComplexCollectionProperty.Value.FullTypeName, "Full type names are not equal");
                this.Assert.AreEqual(expectedComplexCollectionProperty.Value.Count, observedComplexCollectionProperty.Value.Count, "Collection counts are not equal");
                for (int i = 0; i < expectedComplexCollectionProperty.Value.Count; i++)
                {
                    Compare(expectedComplexCollectionProperty.Value[i], observedComplexCollectionProperty.Value[i]);
                }

                break;

            case ODataPayloadElementType.PrimitiveCollection:
                var expectedPrimitiveCollection = expected as PrimitiveCollection;
                var observedPrimitiveCollection = observed as PrimitiveCollection;
                this.Assert.AreEqual(expectedPrimitiveCollection.Count, observedPrimitiveCollection.Count, "Collection counts are not equal");
                for (int i = 0; i < expectedPrimitiveCollection.Count; i++)
                {
                    Compare(expectedPrimitiveCollection[i], observedPrimitiveCollection[i]);
                }

                break;

            case ODataPayloadElementType.ComplexInstanceCollection:
                var expectedComplexCollection = expected as ComplexInstanceCollection;
                var observedComplexCollection = observed as ComplexInstanceCollection;
                this.Assert.AreEqual(expectedComplexCollection.Count, observedComplexCollection.Count, "Collection counts are not equal");
                for (int i = 0; i < expectedComplexCollection.Count; i++)
                {
                    Compare(expectedComplexCollection[i], observedComplexCollection[i]);
                }

                break;

            case ODataPayloadElementType.NullPropertyInstance:
            case ODataPayloadElementType.EmptyUntypedCollection:
                break;

            default:
                this.Assert.Fail("Case " + expected.ElementType + " unhandled");
                break;
            }
        }
예제 #29
0
        /// <summary>
        /// Creates a set of interesting entity instances along with metadata.
        /// </summary>
        /// <param name="settings">The test descriptor settings to use.</param>
        /// <param name="model">If non-null, the method creates complex types for the complex values 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>
        public static IEnumerable <PayloadTestDescriptor> CreateEntityInstanceTestDescriptors(
            EdmModel model,
            bool withTypeNames)
        {
            IEnumerable <PrimitiveValue>             primitiveValues       = TestValues.CreatePrimitiveValuesWithMetadata(fullSet: false);
            IEnumerable <ComplexInstance>            complexValues         = TestValues.CreateComplexValues(model, withTypeNames, fullSet: false);
            IEnumerable <NamedStreamInstance>        streamReferenceValues = TestValues.CreateStreamReferenceValues(fullSet: false);
            IEnumerable <PrimitiveMultiValue>        primitiveMultiValues  = TestValues.CreatePrimitiveCollections(withTypeNames, fullSet: false);
            IEnumerable <ComplexMultiValue>          complexMultiValues    = TestValues.CreateComplexCollections(model, withTypeNames, fullSet: false);
            IEnumerable <NavigationPropertyInstance> navigationProperties  = TestValues.CreateDeferredNavigationLinks();

            // NOTE we have to copy the EntityModelTypeAnnotation on the primitive value to the NullPropertyInstance for null values since the
            //      NullPropertyInstance does not expose a value. We will later copy it back to the value we generate for the null property.
            IEnumerable <PropertyInstance> primitiveProperties =
                primitiveValues.Select((pv, ix) => PayloadBuilder.Property("PrimitiveProperty" + ix, pv).CopyAnnotation <PropertyInstance, EntityModelTypeAnnotation>(pv));
            IEnumerable <PropertyInstance> complexProperties             = complexValues.Select((cv, ix) => PayloadBuilder.Property("ComplexProperty" + ix, cv));
            IEnumerable <PropertyInstance> primitiveMultiValueProperties = primitiveMultiValues.Select((pmv, ix) => PayloadBuilder.Property("PrimitiveMultiValueProperty" + ix, pmv));
            IEnumerable <PropertyInstance> complexMultiValueProperties   = complexMultiValues.Select((cmv, ix) => PayloadBuilder.Property("ComplexMultiValueProperty" + ix, cmv));

            PropertyInstance[][] propertyMatrix = new PropertyInstance[6][];
            propertyMatrix[0] = primitiveProperties.ToArray();
            propertyMatrix[1] = complexProperties.ToArray();
            propertyMatrix[2] = streamReferenceValues.ToArray();
            propertyMatrix[3] = primitiveMultiValueProperties.ToArray();
            propertyMatrix[4] = complexMultiValueProperties.ToArray();
            propertyMatrix[5] = navigationProperties.ToArray();

            IEnumerable <PropertyInstance[]> propertyCombinations = propertyMatrix.ColumnCombinations(0, 1, 6);

            int count = 0;

            foreach (PropertyInstance[] propertyCombination in propertyCombinations)
            {
                // build the entity type, add it to the model
                EdmEntityType      generatedEntityType = null;
                string             typeName            = "PGEntityType" + count;
                EdmEntityContainer container           = null;
                EdmEntitySet       entitySet           = null;
                if (model != null)
                {
                    // generate a new type with the auto-generated name, check that no type with this name exists and add the default key property to it.
                    Debug.Assert(model.FindDeclaredType(typeName) == null, "Entity type '" + typeName + "' already exists.");
                    generatedEntityType = new EdmEntityType("TestModel", typeName);
                    generatedEntityType.AddKeys(generatedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));
                    model.AddElement(generatedEntityType);
                    container = model.EntityContainer as EdmEntityContainer;

                    if (container == null)
                    {
                        container = new EdmEntityContainer("TestModel", "DefaultNamespace");
                        model.AddElement(container);
                    }

                    entitySet = container.AddEntitySet(typeName, generatedEntityType);
                }

                EntityInstance entityInstance = PayloadBuilder.Entity("TestModel." + typeName)
                                                .Property("Id", PayloadBuilder.PrimitiveValue(count).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false)));

                for (int i = 0; i < propertyCombination.Length; ++i)
                {
                    PropertyInstance currentProperty = propertyCombination[i];
                    entityInstance.Add(currentProperty);

                    if (model != null)
                    {
                        if (entitySet == null)
                        {
                            entitySet = container.FindEntitySet(typeName) as EdmEntitySet;
                        }

                        switch (currentProperty.ElementType)
                        {
                        case ODataPayloadElementType.ComplexProperty:
                            ComplexProperty complexProperty = (ComplexProperty)currentProperty;
                            generatedEntityType.AddStructuralProperty(complexProperty.Name,
                                                                      complexProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            break;

                        case ODataPayloadElementType.PrimitiveProperty:
                            PrimitiveProperty primitiveProperty = (PrimitiveProperty)currentProperty;
                            if (primitiveProperty.Value == null)
                            {
                                generatedEntityType.AddStructuralProperty(
                                    primitiveProperty.Name,
                                    PayloadBuilder.PrimitiveValueType(null));
                            }
                            else
                            {
                                generatedEntityType.AddStructuralProperty(primitiveProperty.Name,
                                                                          primitiveProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            }
                            break;

                        case ODataPayloadElementType.NamedStreamInstance:
                            NamedStreamInstance streamProperty = (NamedStreamInstance)currentProperty;
                            generatedEntityType.AddStructuralProperty(streamProperty.Name, EdmPrimitiveTypeKind.Stream);
                            break;

                        case ODataPayloadElementType.EmptyCollectionProperty:
                            throw new NotImplementedException();

                        case ODataPayloadElementType.NavigationPropertyInstance:
                            NavigationPropertyInstance navigationProperty = (NavigationPropertyInstance)currentProperty;
                            var navProperty = generatedEntityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
                            {
                                ContainsTarget     = false,
                                Name               = navigationProperty.Name,
                                Target             = generatedEntityType,
                                TargetMultiplicity = EdmMultiplicity.One
                            });
                            entitySet.AddNavigationTarget(navProperty, entitySet);
                            break;

                        case ODataPayloadElementType.ComplexMultiValueProperty:
                            ComplexMultiValueProperty complexMultiValueProperty = (ComplexMultiValueProperty)currentProperty;
                            generatedEntityType.AddStructuralProperty(complexMultiValueProperty.Name,
                                                                      complexMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            break;

                        case ODataPayloadElementType.PrimitiveMultiValueProperty:
                            PrimitiveMultiValueProperty primitiveMultiValueProperty = (PrimitiveMultiValueProperty)currentProperty;
                            generatedEntityType.AddStructuralProperty(primitiveMultiValueProperty.Name,
                                                                      primitiveMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType);
                            break;

                        default:
                            throw new NotSupportedException("Unsupported element type found : " + propertyCombination[i].ElementType);
                        }
                    }
                }

                if (generatedEntityType != null)
                {
                    entityInstance.AddAnnotation(new EntityModelTypeAnnotation(generatedEntityType.ToTypeReference(true)));
                }

                yield return(new PayloadTestDescriptor()
                {
                    PayloadElement = entityInstance, PayloadEdmModel = model
                });

                count++;
            }
        }
예제 #30
0
        /// <summary>
        /// Converts the given name/value pair into a property element.
        /// And infers the type of property from the converted value.
        /// </summary>
        /// <param name="jsonProperty">the property value</param>
        /// <returns>the converted property</returns>
        private PropertyInstance ConvertProperty(JsonProperty jsonProperty)
        {
            if (jsonProperty.Value.JsonType == JsonValueType.JsonPrimitiveValue && ((JsonPrimitiveValue)jsonProperty.Value).Value == null)
            {
                return(new NullPropertyInstance()
                {
                    Name = jsonProperty.Name
                });
            }
            else
            {
                ODataPayloadElement elem = this.ConvertValue(jsonProperty.Value);
                ExceptionUtilities.CheckObjectNotNull(elem, "Converted property value was null");

                if (elem.ElementType == ODataPayloadElementType.PrimitiveValue)
                {
                    return(new PrimitiveProperty(jsonProperty.Name, (PrimitiveValue)elem));
                }
                else if (elem.ElementType == ODataPayloadElementType.ComplexInstance)
                {
                    return(new ComplexProperty(jsonProperty.Name, (ComplexInstance)elem));
                }
                else if (elem.ElementType == ODataPayloadElementType.EntityInstance)
                {
                    return(new NavigationPropertyInstance(jsonProperty.Name, new ExpandedLink(elem)));
                }
                else if (elem.ElementType == ODataPayloadElementType.DeferredLink)
                {
                    DeferredLink deferredLink = (DeferredLink)elem;
                    return(new NavigationPropertyInstance(jsonProperty.Name, deferredLink));
                }
                else if (elem.ElementType == ODataPayloadElementType.EntitySetInstance)
                {
                    return(new NavigationPropertyInstance(jsonProperty.Name, elem));
                }
                else if (elem.ElementType == ODataPayloadElementType.ComplexMultiValue)
                {
                    ComplexMultiValue complexMultiValue = (ComplexMultiValue)elem;
                    return(new ComplexMultiValueProperty(jsonProperty.Name, complexMultiValue));
                }
                else if (elem.ElementType == ODataPayloadElementType.PrimitiveMultiValue)
                {
                    PrimitiveMultiValue primitiveMultiValue = (PrimitiveMultiValue)elem;
                    return(new PrimitiveMultiValueProperty(jsonProperty.Name, primitiveMultiValue));
                }
                else if (elem.ElementType == ODataPayloadElementType.ComplexInstanceCollection)
                {
                    ComplexInstanceCollection complexCollection = (ComplexInstanceCollection)elem;
                    return(new ComplexMultiValueProperty(jsonProperty.Name, new ComplexMultiValue(null, false, complexCollection.ToArray())));
                }
                else if (elem.ElementType == ODataPayloadElementType.PrimitiveCollection)
                {
                    PrimitiveCollection primitiveCollection = (PrimitiveCollection)elem;
                    return(new PrimitiveMultiValueProperty(jsonProperty.Name, new PrimitiveMultiValue(null, false, primitiveCollection.ToArray())));
                }
                else if (elem.ElementType == ODataPayloadElementType.NamedStreamInstance)
                {
                    NamedStreamInstance nsi = (NamedStreamInstance)elem;
                    nsi.Name = jsonProperty.Name;
                    return(nsi);
                }
                else
                {
                    ExceptionUtilities.Assert(elem.ElementType == ODataPayloadElementType.EmptyUntypedCollection, "Do not know how to handle element of type" + elem.ElementType);
                    return(new EmptyCollectionProperty(jsonProperty.Name, (EmptyUntypedCollection)elem));
                }
            }
        }
예제 #31
0
 /// <summary>
 /// Visits a payload element whose root is a NamedStreamProperty.
 /// </summary>
 /// <param name="payloadElement">The root node of payload element being visited.</param>
 public void Visit(NamedStreamInstance payloadElement)
 {
     throw new TaupoNotSupportedException("Json serialization does not allow element of type: " + payloadElement.ElementType.ToString());
 }
            /// <summary>
            /// Visits a payload element whose root is a NamedStreamProperty.  this will validate the content types and etags
            /// </summary>
            /// <param name="payloadElement">The root node of payload element being visited.</param>
            public void Visit(NamedStreamInstance payloadElement)
            {
                ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement");

                var current = this.expectedValueStack.Peek();
                var queryStreamValue = current as AstoriaQueryStreamValue;
                ExceptionUtilities.CheckObjectNotNull(queryStreamValue, "Value was not a stream. Value was: '{0}'", current.ToString());

                using (this.parent.Assert.WithMessage("Named stream '{0}' did not match expectation", payloadElement.Name))
                {
                    this.CompareStreamETag(queryStreamValue, payloadElement.ETag);
                    if (this.parent.ExpectedPayloadOptions.HasFlag(ODataPayloadOptions.IncludeSelfOrEditLink))
                    {
                        this.parent.Assert.IsFalse(payloadElement.EditLink == null && payloadElement.SourceLink == null, "At least one link (self/edit) should be present in the response payload");
                    }

                    if (payloadElement.EditLink != null)
                    {
                        this.CompareUri(queryStreamValue.EditLink, payloadElement.EditLink, "Edit link did not match");
                        this.parent.Assert.AreEqual(queryStreamValue.ContentType, payloadElement.EditLinkContentType, "Edit link content-type did not match");
                    }

                    if (payloadElement.SourceLink != null)
                    {
                        if (!this.parent.ExpectedPayloadOptions.HasFlag(ODataPayloadOptions.ConventionallyProducedNamedStreamSelfLink))
                        {
                            this.CompareUri(queryStreamValue.SelfLink, payloadElement.SourceLink, "Self link did not match");
                            this.parent.Assert.AreEqual(queryStreamValue.ContentType, payloadElement.SourceLinkContentType, "Self link content-type did not match");
                        }
                    }
                }
            }