/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); XmlRewriteElementAnnotation annotation = new XmlRewriteElementAnnotation() { RewriteFunction = (node) => { XNode foundNode = null; var currentNode = node.FirstNode; if (node.Nodes().Count() > 1) { while (currentNode != null && foundNode == null) { var element = (XElement)currentNode; if (element.Name.LocalName.Equals("id")) { foundNode = currentNode; currentNode.Remove(); } currentNode = currentNode.NextNode; } if (foundNode != null) { node.FirstNode.AddBeforeSelf(foundNode); } } return(node); } }; payloadElement.Add(annotation); base.Visit(payloadElement); }
/// <summary> /// Visits an entity set instance: creates a new ODataFeed instance, calls ODataWriter.WriteStart() /// before visiting the entries and then calls ODataWriter.WriteEnd() /// </summary> /// <param name="payloadElement">The entity set instance to write.</param> public override void Visit(EntitySetInstance payloadElement) { // create an ODataFeed and write it ODataFeed feed = new ODataFeed() { // NOTE: the required Id is set when processing the annotations in AddFeedMetadata() Count = payloadElement.InlineCount, SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceEntityTypeName = "Null", NavigationSourceName = "MySet", ExpectedTypeName = "Null" } }; if (payloadElement.NextLink != null) { feed.NextPageLink = new Uri(payloadElement.NextLink); } AddFeedMetadata(payloadElement, feed); this.writer.WriteStart(feed); base.Visit(payloadElement); this.writer.WriteEnd(); }
public void TaupoTopLevelFeedTest() { EntitySetInstance entitySet = new EntitySetInstance(PayloadGenerator.GenerateAtomPayloads().First()) .WithDefaultAtomFeedAnnotations(); this.CombinatorialEngineProvider.RunCombinations( new[] { entitySet }, this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent, (testCase, testConfiguration) => { testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); this.WriteAndVerifyODataPayloadElement(testCase, testConfiguration); }); // The ID annotation is added for JSON as even though JSON has no way to represent the ID ODataLib requires it. entitySet = new EntitySetInstance(PayloadGenerator.GenerateJsonPayloads().ToArray()).WithDefaultAtomIDAnnotation(); // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight //this.CombinatorialEngineProvider.RunCombinations( // new[] { entitySet }, // this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent, // (testCase, testConfiguration) => // { // this.WriteAndVerifyODataPayloadElement(testCase, testConfiguration); // }); }
/// <summary> /// Visits a feed item. /// </summary> /// <param name="feed">The feed to visit.</param> protected override ODataPayloadElement VisitFeed(ODataResourceSet resourceCollection) { ExceptionUtilities.CheckArgumentNotNull(resourceCollection, "feed"); EntitySetInstance entitySet = new EntitySetInstance() { InlineCount = resourceCollection.Count, NextLink = resourceCollection.NextPageLink == null ? null : resourceCollection.NextPageLink.OriginalString }; if (resourceCollection.Id != null) { entitySet.AtomId(UriUtils.UriToString(resourceCollection.Id)); } // now check for the entries annotation on the feed IEnumerable <ODataResource> entries = resourceCollection.Entries(); if (entries != null) { foreach (ODataResource entry in entries) { entitySet.Add(this.Visit(entry)); } } return(entitySet); }
private void Recurse(EntitySetInstance payloadElement) { if (payloadElement.Count == 0) { return; } var currentValue = this.queryValueStack.Peek() as QueryCollectionValue; ExceptionUtilities.CheckObjectNotNull(currentValue, "Current value was not a collection"); ExceptionUtilities.Assert(payloadElement.Count == currentValue.Elements.Count, "Number of elements did not match"); for (int i = 0; i < payloadElement.Count; i++) { try { this.queryValueStack.Push(currentValue.Elements[i]); this.Recurse(payloadElement[i]); } finally { this.queryValueStack.Pop(); } } }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { base.Visit(payloadElement); // Inject an empty $select projection for top-level feeds (if no projection exists) this.InjectEmptyContextUriProjection(payloadElement); }
/// <summary> /// Annotates the feed with atom:logo values. /// </summary> /// <param name="feed">The feed to annotate.</param> /// <param name="uri">The value of the atom:logo element.</param> /// <returns>The feed with the annotation applied.</returns> public static EntitySetInstance AtomLogo(this EntitySetInstance feed, string uri) { ExceptionUtilities.CheckArgumentNotNull(feed, "feed"); feed.AddAnnotation(XmlTreeAnnotation.Atom(TestAtomConstants.AtomLogoElementName, uri)); return(feed); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { base.Visit(payloadElement); // Inject an empty $select projection for top-level feeds (if no projection exists) this.InjectEmptyContextUriProjection(payloadElement); }
public void FeedReadingNullUriTest() { EdmModel model = (EdmModel)Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel(); model.Fixup(); EntitySetInstance feed = PayloadBuilder.EntitySet(); feed.NextLink = null; // Run only in version >= 2 since next links are only supported since v2 and not allowed in requests this.CombinatorialEngineProvider.RunCombinations( baseUriValues, this.ReaderTestConfigurationProvider.AtomFormatConfigurations.Where(tc => !tc.IsRequest), (baseUriValue, testConfiguration) => { // The next link should always be null independently of whether a base URI is specified or not NullUriValueTestCase <EntitySetInstance> testCase = new NullUriValueTestCase <EntitySetInstance> { SetNullUriAction = (instance, uri, testConfig) => instance.NextLink = null, SetExpectedUriAction = null // will use SetNullUriAction instead }; this.RunNullUriReadingTest(feed, testCase, model, baseUriValue, testConfiguration); }); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); ExceptionUtilities.CheckObjectNotNull(this.currentXElement, "Current XElement is not defined"); XElement feed = CreateAtomElement(this.currentXElement, "feed"); if (payloadElement.InlineCount.HasValue) { XElement countElement = CreateMetadataElement(feed, "count"); countElement.Value = payloadElement.InlineCount.Value.ToString(CultureInfo.InvariantCulture); } foreach (EntityInstance entity in payloadElement) { this.VisitPayloadElement(entity, feed); } if (payloadElement.NextLink != null) { CreateAtomLinkElement(feed, "next", payloadElement.NextLink); } PostProcessXElement(payloadElement, feed); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); XmlRewriteElementAnnotation annotation = new XmlRewriteElementAnnotation() { RewriteFunction = (node) => { XNode foundNode = null; var currentNode = node.FirstNode; if (node.Nodes().Count() > 1) { while (currentNode != null && foundNode == null) { var element = (XElement)currentNode; if (element.Name.LocalName.Equals("id")) { foundNode = currentNode; currentNode.Remove(); } currentNode = currentNode.NextNode; } if (foundNode != null) { node.FirstNode.AddBeforeSelf(foundNode); } } return node; } }; payloadElement.Add(annotation); base.Visit(payloadElement); }
/// <summary> /// Visits an entity set instance: creates a new ODataFeed instance, calls ODataWriter.WriteStart() /// before visiting the entries and then calls ODataWriter.WriteEnd() /// </summary> /// <param name="payloadElement">The entity set instance to write.</param> public override void Visit(EntitySetInstance payloadElement) { // create an ODataFeed and write it ODataFeed feed = new ODataFeed() { // NOTE: the required Id is set when processing the annotations in AddFeedMetadata() Count = payloadElement.InlineCount, SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceEntityTypeName = "Null", NavigationSourceName = "MySet", ExpectedTypeName = "Null" } }; if (payloadElement.NextLink != null) { feed.NextPageLink = new Uri(payloadElement.NextLink); } AddFeedMetadata(payloadElement, feed); this.writer.WriteStart(feed); base.Visit(payloadElement); this.writer.WriteEnd(); }
public void TaupoTopLevelFeedTest() { EntitySetInstance entitySet = new EntitySetInstance(PayloadGenerator.GenerateAtomPayloads().First()) .WithDefaultAtomFeedAnnotations(); this.CombinatorialEngineProvider.RunCombinations( new[] { entitySet }, this.WriterTestConfigurationProvider.AtomFormatConfigurationsWithIndent, (testCase, testConfiguration) => { testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); this.WriteAndVerifyODataPayloadElement(testCase, testConfiguration); }); // The ID annotation is added for JSON as even though JSON has no way to represent the ID ODataLib requires it. entitySet = new EntitySetInstance(PayloadGenerator.GenerateJsonPayloads().ToArray()).WithDefaultAtomIDAnnotation(); // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight //this.CombinatorialEngineProvider.RunCombinations( // new[] { entitySet }, // this.WriterTestConfigurationProvider.JsonLightFormatConfigurationsWithIndent, // (testCase, testConfiguration) => // { // this.WriteAndVerifyODataPayloadElement(testCase, testConfiguration); // }); }
/// <summary> /// Visits an entity set instance: creates a new ODataFeed instance, calls ODataWriter.WriteStart() /// before visiting the entries and then calls ODataWriter.WriteEnd() /// </summary> /// <param name="payloadElement">The entity set instance to write.</param> public override void Visit(EntitySetInstance payloadElement) { // create an ODataFeed and write it ODataFeed feed = new ODataFeed() { // NOTE: the required Id is set when processing the annotations in AddFeedMetadata() Count = payloadElement.InlineCount, SerializationInfo = new ODataFeedAndEntrySerializationInfo() { NavigationSourceEntityTypeName = "Null", NavigationSourceName = "MySet", ExpectedTypeName = "Null" } }; var idAnnotation = payloadElement.Annotations.Where(a => { var annotation = a as XmlTreeAnnotation; if (annotation != null) return annotation.LocalName.Equals("id"); return false; }).SingleOrDefault(); if (idAnnotation != null) { feed.Id = new Uri((idAnnotation as XmlTreeAnnotation).PropertyValue, UriKind.Absolute); } if (payloadElement.NextLink != null) { feed.NextPageLink = new Uri(payloadElement.NextLink); } AddFeedMetadata(payloadElement, feed); if (this.items.Count > 0 && this.items.Peek() is ODataNavigationLink) { var currentLink = this.items.Peek() as ODataNavigationLink; ExceptionUtilities.CheckObjectNotNull(currentLink, "Feed can only exist at top level or inside a navigation link"); currentLink.SetAnnotation(new ODataNavigationLinkExpandedItemObjectModelAnnotation() { ExpandedItem = feed }); } try { items.Push(feed); base.Visit(payloadElement); } finally { feed = (ODataFeed)items.Pop(); } // If we are at the top level push this to items to make it the result. if (this.items.Count == 0) { this.items.Push(feed); } }
/// <summary> /// Sets the expected base entity type for the top-level entity set. /// </summary> /// <param name="entitySetInstance">The entity set instance to set the expected set for.</param> /// <param name="entitySet">The entity set the entities belong to.</param> /// <param name="baseEntityType">The base entity type to set as the expected base entity type.</param> /// <returns>The <paramref name="entitySetInstance"/> after its expected type was set.</returns> public static EntitySetInstance ExpectedEntityType(this EntitySetInstance entitySetInstance, EntitySet entitySet, EntityDataType baseEntityType) { ExceptionUtilities.CheckArgumentNotNull(entitySetInstance, "entitySetInstance"); ExpectedTypeODataPayloadElementAnnotation annotation = AddExpectedTypeAnnotation(entitySetInstance); EntityDataType entityType = baseEntityType ?? (entitySet == null ? null : DataTypes.EntityType.WithDefinition(entitySet.EntityType)); annotation.ExpectedType = entityType; annotation.EntitySet = entitySet; return(entitySetInstance); }
/// <summary> /// Sets the expected base entity type for the top-level entity set. /// </summary> /// <param name="entitySetInstance">The entity set instance to set the expected set for.</param> /// <param name="entitySet">The entity set the entities belong to.</param> /// <param name="baseEntityType">The base entity type to set as the expected base entity type.</param> /// <returns>The <paramref name="entitySetInstance"/> after its expected type was set.</returns> public static EntitySetInstance ExpectedEntityType(this EntitySetInstance entitySetInstance, IEdmTypeReference baseEntityType, IEdmEntitySet entitySet = null) { ExceptionUtilities.CheckArgumentNotNull(entitySetInstance, "entitySetInstance"); ExpectedTypeODataPayloadElementAnnotation annotation = ODataPayloadElementExtensions.AddExpectedTypeAnnotation(entitySetInstance); var entityType = baseEntityType ?? (entitySet == null ? null : entitySet.EntityType().ToTypeReference()); annotation.EdmExpectedType = entityType; annotation.EdmEntitySet = entitySet; return(entitySetInstance); }
private void AddFeedEPMAnnotations(XElement feedXElement, EntitySetInstance entitySetInstance) { // get all the properties mapped to atom-specific locations // note that this is driven off what is found, not what is expected based on metadata // Id foreach (var id in feedXElement.Elements(AtomId)) { this.AddEpmTree(entitySetInstance, id); } // Title foreach (var title in feedXElement.Elements(AtomTitle)) { this.AddEpmTree(entitySetInstance, title); } // Summary foreach (var summary in feedXElement.Elements(AtomSummary)) { this.AddEpmTree(entitySetInstance, summary); } // Rights foreach (var rights in feedXElement.Elements(AtomRights)) { this.AddEpmTree(entitySetInstance, rights); } // Published foreach (var published in feedXElement.Elements(AtomPublished)) { this.AddEpmTree(entitySetInstance, published); } // Updated foreach (var updated in feedXElement.Elements(AtomUpdated)) { this.AddEpmTree(entitySetInstance, updated); } // Author foreach (var author in feedXElement.Elements(AtomAuthor)) { // will recurse automatically this.AddEpmTree(entitySetInstance, author); } // Contributor foreach (var contributor in feedXElement.Elements(AtomContributor)) { // will recurse automatically this.AddEpmTree(entitySetInstance, contributor); } }
/// <summary> /// Annotates the feed with atom:generator values. /// </summary> /// <param name="feed">The feed to annotate.</param> /// <param name="name">The value of the atom:generator element.</param> /// <param name="uri">The value of the atom:generator's URI property.</param> /// <param name="version">The value of the atom:generator's version property.</param> /// <returns>The feed with the annotation applied.</returns> public static EntitySetInstance AtomGenerator(this EntitySetInstance feed, string name, string uri, string version) { ExceptionUtilities.CheckArgumentNotNull(feed, "feed"); var generatorAttributes = CreateAtomAttributes( new KeyValuePair <string, string>(TestAtomConstants.AtomGeneratorUriAttributeName, uri), new KeyValuePair <string, string>(TestAtomConstants.AtomGeneratorVersionAttributeName, version)); feed.AddAnnotation(XmlTreeAnnotation.Atom(TestAtomConstants.AtomGeneratorElementName, name, generatorAttributes)); return(feed); }
/// <summary> /// Visits a payload element whose root is an EntitySetInstance. /// </summary> /// <param name="payloadElement">The root node of the payload element being visited.</param> public override ODataPayloadElement Visit(EntitySetInstance payloadElement) { EntitySetInstance entitySetInstance = (EntitySetInstance)base.Visit(payloadElement); foreach (EntityInstance instance in entitySetInstance) { instance.Accept(this); } return(entitySetInstance); }
/// <summary> /// Visits the entity set and removes the title and entity set annotations /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var annotation = payloadElement.Annotations.Where(a => a is TitleAnnotation).SingleOrDefault(); payloadElement.Annotations.Remove(annotation); annotation = payloadElement.Annotations.Where(a => a is EntitySetAnnotation).SingleOrDefault(); payloadElement.Annotations.Remove(annotation); base.Visit(payloadElement); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var hasID = payloadElement.Annotations.Where(a => a is XmlTreeAnnotation && (a as XmlTreeAnnotation).LocalName == TestAtomConstants.AtomIdElementName).SingleOrDefault(); if (hasID == null) { payloadElement.AtomId("urn:FeedID"); } base.Visit(payloadElement); }
/// <summary> /// Visits a payload element whose root is an EntitySetInstance. /// </summary> /// <param name="payloadElement">The root node of the payload element being visited.</param> public override void Visit(EntitySetInstance payloadElement) { base.Visit(payloadElement); // Entity set instances (Feeds) use different format in JSON for V2 (and higher) payloads in responses // so we need to add an annotation marking it with the right version so that the serializer will use the // V2 format. if (!this.requestPayload) { this.AddVersionAnnotation(payloadElement); } }
/// <summary> /// Visits the entity set and removes the title and entity set annotations /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var annotation = payloadElement.Annotations.Where(a => a is TitleAnnotation).SingleOrDefault(); payloadElement.Annotations.Remove(annotation); annotation = payloadElement.Annotations.Where(a => a is EntitySetAnnotation).SingleOrDefault(); payloadElement.Annotations.Remove(annotation); base.Visit(payloadElement); }
/// <summary> /// Visits a payload element whose root is a EntitySetInstance. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); this.isRootElement = false; this.writer.StartArrayScope(); for (int i = 0; i < payloadElement.Count(); i++) { payloadElement[i].Accept(this); } this.writer.EndScope(); }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var hasID = payloadElement.Annotations.Where(a => a is XmlTreeAnnotation && (a as XmlTreeAnnotation).LocalName == TestAtomConstants.AtomIdElementName).SingleOrDefault(); if (hasID == null) { payloadElement.AtomId("urn:FeedID"); } base.Visit(payloadElement); }
/// <summary> /// Visits payloadElement to add default annotations and remove certain ones. /// Then Visits its properties to replace properties with null values with NullProperty Instances. /// This is required in comparison because the Test Deserialiser converts properties that are null to NullProperty Instnaces. /// Also removes the annotations added by the Replacing Visitor and removes MultiValue properties if found /// </summary> /// <param name="payloadElement">the payload to potentially replace</param> /// <returns>The original or a copy if it has changed</returns> public override ODataPayloadElement Visit(EntitySetInstance payloadElement) { FixEpmAnnotationsUris(payloadElement.Annotations); EntitySetInstance entitySetInstance = (EntitySetInstance)base.Visit(payloadElement); // This has to happen last ReplaceAnnotationRemover replaceAnnotationRemover = new ReplaceAnnotationRemover(); replaceAnnotationRemover.Visit(entitySetInstance); return(entitySetInstance); }
private static void AddFeedMetadata(EntitySetInstance payloadElement, ODataFeed feed) { AtomFeedMetadata metadata = CreateFeedMetadata(payloadElement.Annotations.OfType <XmlTreeAnnotation>(), feed); // Fix up metadata for baselining metadata = metadata.Fixup(); if (metadata != null) { feed.SetAnnotation <AtomFeedMetadata>(metadata); } }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var idAnnotation = payloadElement.Annotations .Where(a => a is XmlTreeAnnotation && ((XmlTreeAnnotation)a).LocalName == TestAtomConstants.AtomIdElementName).SingleOrDefault(); if (idAnnotation != null) { payloadElement.Annotations.Remove(idAnnotation); } base.Visit(payloadElement); }
/// <summary> /// Visits a payload element whose root is an EntitySetInstance. /// </summary> /// <param name="expected">The root node of payload element being visited.</param> public void Visit(EntitySetInstance expected) { ExceptionUtilities.CheckArgumentNotNull(expected, "expected"); var observed = this.GetNextObservedElement <EntitySetInstance>(); using (this.Assert.WithMessage("Entity set instance did not match expectation")) { this.Assert.AreEqual(expected.NextLink, observed.NextLink, "Next link did not match expectation"); this.Assert.AreEqual(expected.InlineCount, observed.InlineCount, "Inline count did not match expectation"); this.CompareCollection(expected, observed); } }
/// <summary> /// Builds an instance of QueryCollectionValue from an entity set instance. /// </summary> /// <param name="entitySetInstance">The entity set instance.</param> /// <param name="elementType">The QueryEntityType of its element.</param> /// <param name="xmlBaseAnnotations">The xml base annotations from parent elements, if any</param> /// <returns>The converted QueryCollectionValue of entity set instance.</returns> private QueryCollectionValue BuildFromEntitySetInstance(EntitySetInstance entitySetInstance, QueryEntityType elementType, IEnumerable <XmlBaseAnnotation> xmlBaseAnnotations) { ExceptionUtilities.CheckArgumentNotNull(elementType, "elementType"); var entities = new List <QueryStructuralValue>(); foreach (var entityInstance in entitySetInstance) { var value = this.BuildFromEntityInstance(entityInstance, elementType, xmlBaseAnnotations.Concat(entityInstance.Annotations.OfType <XmlBaseAnnotation>())); entities.Add(value); } return(QueryCollectionValue.Create(elementType, entities.ToArray())); }
/// <summary> /// Converts the ComplexMultiValue into an EntitySetInstance based on if the base returns a set of EntityInstances /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var replaced = (ComplexMultiValue)base.Visit(payloadElement); ExceptionUtilities.CheckObjectNotNull(replaced, "ComplexMultiValue Expected"); if (replaced.All(e => e.ElementType == ODataPayloadElementType.EntityInstance) && replaced.Count > 0) { var entitySet = new EntitySetInstance(replaced.Cast<EntityInstance>().ToArray()); return replaced.ReplaceWith(entitySet); } return replaced; }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var idAnnotation = payloadElement.Annotations .Where(a => a is XmlTreeAnnotation && ((XmlTreeAnnotation)a).LocalName == TestAtomConstants.AtomIdElementName).SingleOrDefault(); if (idAnnotation != null) { payloadElement.Annotations.Remove(idAnnotation); } base.Visit(payloadElement); }
/// <summary> /// Converts the ComplexMultiValue into an EntitySetInstance based on if the base returns a set of EntityInstances /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(ComplexMultiValue payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var replaced = (ComplexMultiValue)base.Visit(payloadElement); ExceptionUtilities.CheckObjectNotNull(replaced, "ComplexMultiValue Expected"); if (replaced.All(e => e.ElementType == ODataPayloadElementType.EntityInstance) && replaced.Count > 0) { var entitySet = new EntitySetInstance(replaced.Cast <EntityInstance>().ToArray()); return(replaced.ReplaceWith(entitySet)); } return(replaced); }
/// <summary> /// Deserializes the given element, which is assumed to be an atom feed, into an entity set /// </summary> /// <param name="feed">An atom feed xml element</param> /// <returns>The deserialized entity set</returns> private EntitySetInstance DeserializeEntitySet(XElement feed) { ExceptionUtilities.CheckArgumentNotNull(feed, "feed"); EntitySetInstance entitySet = new EntitySetInstance(); AddXmlBaseAnnotation(entitySet, feed); // set title XElement title = feed.Element(AtomTitle); if (title != null) { entitySet.Annotations.Add(new TitleAnnotation(title.Value)); } // read the count, if present XElement count = feed.Element(MetadataCount); if (count != null) { entitySet.InlineCount = long.Parse(count.Value, CultureInfo.InvariantCulture); } // read the next link, if present XElement nextLink = feed.Elements(AtomLink) .Select(l => l.Attribute(Rel)) .Where(rel => rel != null) .Where(rel => rel.Value == RelNext) .Select(rel => rel.Parent) .SingleOrDefault(); if (nextLink != null) { XAttribute href = nextLink.Attribute(Href); if (href != null) { entitySet.NextLink = href.Value; } } // deserialize and add each entry foreach (XElement entry in feed.Elements(AtomEntry)) { entitySet.Add(this.DeserializeEntity(entry)); } this.AddFeedEPMAnnotations(feed, entitySet); return(entitySet); }
/// <summary> /// Annotates the entry with atom:source values. /// </summary> /// <param name="entry">The entry to annotate.</param> /// <param name="sourceFeed">The feed containing metadata to copy.</param> /// <returns>The entry with the annotation applied.</returns> public static EntityInstance AtomSource(this EntityInstance entry, EntitySetInstance sourceFeed) { ExceptionUtilities.CheckArgumentNotNull(entry, "entry"); ExceptionUtilities.CheckArgumentNotNull(sourceFeed, "sourceFeed"); var sourceAnnotations = sourceFeed.Annotations.OfType <XmlTreeAnnotation>(); entry.AddAnnotation( XmlTreeAnnotation.Atom( TestAtomConstants.AtomSourceElementName, null, sourceAnnotations.Select(a => (XmlTreeAnnotation)a.Clone()).ToArray())); return(entry); }
/// <summary> /// Visits a feed item. /// </summary> /// <param name="feed">The feed item to visit.</param> /// <returns>An ODataPayloadElement representing the feed.</returns> protected override ODataPayloadElement VisitFeed(ODataFeed feed) { ExceptionUtilities.CheckArgumentNotNull(feed, "feed"); EntitySetInstance entitySet = (EntitySetInstance)base.VisitFeed(feed); var atomMetadata = feed.GetAnnotation <AtomFeedMetadata>(); if (atomMetadata != null) { ConvertAtomFeedMetadata(atomMetadata, entitySet); } return(entitySet); }
/// <summary> /// Build QueryValue from action response payload /// </summary> /// <param name="payload">response payload element</param> /// <param name="queryType">query type to build</param> /// <returns>query value that represents the payload</returns> private QueryValue BuildQueryValueForActionResponse(ODataPayloadElement payload, QueryType queryType) { EntitySetInstance entitySetInstance = payload as EntitySetInstance; PrimitiveProperty primitiveProperty = payload as PrimitiveProperty; ComplexProperty complexProperty = payload as ComplexProperty; PrimitiveMultiValueProperty primitiveMultiValueProperty = payload as PrimitiveMultiValueProperty; ComplexMultiValueProperty complexMultiValueProperty = payload as ComplexMultiValueProperty; PrimitiveCollection primitiveCollection = payload as PrimitiveCollection; ComplexInstanceCollection complexInstanceCollection = payload as ComplexInstanceCollection; if (entitySetInstance != null) { var xmlBaseAnnotations = payload.Annotations.OfType <XmlBaseAnnotation>(); var collectionType = this.currentExpression.ExpressionType as QueryCollectionType; ExceptionUtilities.CheckObjectNotNull(collectionType, "Cannot cast expression type to QueryCollectionType."); var elementType = collectionType.ElementType as QueryEntityType; return(this.BuildFromEntitySetInstance(entitySetInstance, elementType, xmlBaseAnnotations)); } else if (primitiveProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(primitiveProperty.Value, queryType)); } else if (complexProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(complexProperty.Value, queryType)); } else if (primitiveMultiValueProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(primitiveMultiValueProperty.Value, queryType)); } else if (complexMultiValueProperty != null) { return(this.PayloadElementToQueryValueConverter.Convert(complexMultiValueProperty.Value, queryType)); } else if (primitiveCollection != null) { return(this.PayloadElementToQueryValueConverter.Convert(primitiveCollection, queryType)); } else if (complexInstanceCollection != null) { return(this.PayloadElementToQueryValueConverter.Convert(complexInstanceCollection, queryType)); } else { ExceptionUtilities.CheckArgumentNotNull(payload as EntityInstance, "Unexpected response payload type: " + payload.ElementType + "."); return(this.PayloadElementToQueryValueConverter.Convert(payload, queryType)); } }
/// <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(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var replaced = this.VisitCollection(payloadElement); if (!this.ShouldReplace(replaced, payloadElement)) { return(payloadElement); } var replacedCollection = payloadElement.ReplaceWith(new EntitySetInstance(replaced.ToArray())); replacedCollection.InlineCount = payloadElement.InlineCount; replacedCollection.NextLink = payloadElement.NextLink; return(replacedCollection); }
/// <summary> /// Visits the payload element and annotates it with metadata /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var entitySet = this.MetadataStack.Peek() as EntitySet; ExceptionUtilities.CheckObjectNotNull(entitySet, "Expected entity set, got '{0}'", this.MetadataStack.Peek()); payloadElement.AddAnnotationIfNotExist(new EntitySetAnnotation() { EntitySet = entitySet }); foreach (var element in payloadElement) { this.Recurse(element); } }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); XmlTreeAnnotation updated = XmlTreeAnnotation.Atom(TestAtomConstants.AtomUpdatedElementName, "2013-08-13T01:03:16.7800000"); updated.SetValueEqualityFunc((obj1, obj2) => { return true; }); payloadElement.Annotations.Add(updated); payloadElement.Add(XmlTreeAnnotation.Atom("title", null)); //If a feed is empty it must have an author bool feedEmpty = payloadElement.Count == 0; if (feedEmpty) { XmlTreeAnnotation author = XmlTreeAnnotation.Atom(TestAtomConstants.AtomAuthorElementName, null, XmlTreeAnnotation.Atom(TestAtomConstants.AtomAuthorNameElementName, null)); payloadElement.Annotations.Add(author); } base.Visit(payloadElement); }
/// <summary> /// Replaces the empty collection property with a more specific type /// </summary> /// <param name="payloadElement">The payload element to potentially replace</param> /// <returns>The original element or a copy to replace it with</returns> public override ODataPayloadElement Visit(EmptyUntypedCollection payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var expectedTypeAnnotatation = payloadElement.Annotations.OfType<ExpectedPayloadElementTypeAnnotation>().SingleOrDefault(); if (expectedTypeAnnotatation != null && expectedTypeAnnotatation.ExpectedType == ODataPayloadElementType.LinkCollection) { var linkCollection = new LinkCollection(); linkCollection.InlineCount = payloadElement.InlineCount; linkCollection.NextLink = payloadElement.NextLink; return payloadElement.ReplaceWith(linkCollection); } var entitySetAnnotation = payloadElement.Annotations.OfType<EntitySetAnnotation>().SingleOrDefault(); if (entitySetAnnotation != null) { var entitySet = new EntitySetInstance(); entitySet.InlineCount = payloadElement.InlineCount; entitySet.NextLink = payloadElement.NextLink; return payloadElement.ReplaceWith(entitySet); } var functionAnnotation = payloadElement.Annotations.OfType<FunctionAnnotation>().SingleOrDefault(); if (functionAnnotation != null && expectedTypeAnnotatation != null) { if (expectedTypeAnnotatation.ExpectedType == ODataPayloadElementType.ComplexInstanceCollection) { return payloadElement.ReplaceWith(new ComplexInstanceCollection()); } if (expectedTypeAnnotatation.ExpectedType == ODataPayloadElementType.PrimitiveCollection) { return payloadElement.ReplaceWith(new PrimitiveCollection()); } } return base.Visit(payloadElement); }
/// <summary> /// Converts the Object Model representation of Atom metadata for entries into appropriate PayloadElement annotations /// </summary> /// <param name="entryMetadata">the Atom entry metadata, in Object Model representation, to convert</param> /// <param name="entry">the EntityInstance to annotate</param> private static void ConvertAtomEntryMetadata(AtomEntryMetadata entryMetadata, EntityInstance entry) { ExceptionUtilities.CheckArgumentNotNull(entryMetadata, "entryMetadata"); ExceptionUtilities.CheckArgumentNotNull(entry, "entry"); foreach (var author in entryMetadata.Authors) { entry.AtomAuthor(author.Name, author.Uri == null ? null : author.Uri.OriginalString, author.Email); } foreach (var category in entryMetadata.Categories) { entry.AtomCategory(category.Term, category.Scheme, category.Label); } foreach (var contributor in entryMetadata.Contributors) { entry.AtomContributor(contributor.Name, contributor.Uri == null? null : contributor.Uri.OriginalString, contributor.Email); } if (entryMetadata.EditLink != null) { AtomLinkMetadata editLink = entryMetadata.EditLink; entry.AtomEditLink(editLink.Href == null ? null : editLink.Href.OriginalString, editLink.MediaType, editLink.HrefLang, editLink.Title, ToString(editLink.Length)); } foreach (var link in entryMetadata.Links) { entry.AtomLink(link.Href == null ? null : link.Href.OriginalString, link.Relation, link.MediaType, link.HrefLang, link.Title, ToString(link.Length)); } if (entryMetadata.Published.HasValue) { entry.AtomPublished(ToString(entryMetadata.Published)); } if (entryMetadata.Rights != null) { entry.AtomRights(entryMetadata.Rights.Text, ToString(entryMetadata.Rights.Kind)); } if (entryMetadata.SelfLink != null) { AtomLinkMetadata selfLink = entryMetadata.SelfLink; entry.AtomSelfLink(selfLink.Href == null ? null : selfLink.Href.OriginalString, selfLink.MediaType, selfLink.HrefLang, selfLink.Title, ToString(selfLink.Length)); } if (entryMetadata.CategoryWithTypeName != null) { AtomCategoryMetadata categoryWithTypeName = entryMetadata.CategoryWithTypeName; entry.AtomCategoryWithTypeName(categoryWithTypeName.Term, categoryWithTypeName.Label); } if (entryMetadata.Source != null) { EntitySetInstance tempSourceFeed = new EntitySetInstance(); ConvertAtomFeedMetadata(entryMetadata.Source, tempSourceFeed); entry.AtomSource(tempSourceFeed); } if (entryMetadata.Summary != null) { entry.AtomSummary(entryMetadata.Summary.Text, ToString(entryMetadata.Summary.Kind)); } if (entryMetadata.Title != null) { entry.AtomTitle(entryMetadata.Title.Text, ToString(entryMetadata.Title.Kind)); } if (entryMetadata.Updated.HasValue) { entry.AtomUpdated(ToString(entryMetadata.Updated)); } }
private void GenerateAndCompareNextLink(EntitySetInstance payloadElement, int expectedPageSize) { var currentPageValues = this.queryValueStack.Peek() as QueryCollectionValue; ExceptionUtilities.CheckObjectNotNull(currentPageValues, "Current value was not a collection"); var lastEntityValue = currentPageValues.Elements.Cast<QueryStructuralValue>().Last(); // build the expected next link and the message to used based on whether we are in an expanded feed or top-level feed string expectedNextLink = null; if (this.navigationStack.Count == 0) { expectedNextLink = this.parent.ExpectedNextLinkGenerator.GenerateNextLink(this.requestUri, expectedPageSize, lastEntityValue); } else { expectedNextLink = this.parent.ExpectedNextLinkGenerator.GenerateExpandedNextLink(this.entityStack.Peek(), this.navigationStack.Peek(), lastEntityValue); } var xmlBaseSegments = this.xmlBaseStack.Reverse().Select(x => x.Value); var expected = UriHelpers.CreateAbsoluteLink(expectedNextLink, xmlBaseSegments); this.parent.AssertHandler.AreEqual(expected.OriginalString, payloadElement.NextLink, "Next link did not match expectation"); }
private void Recurse(EntitySetInstance payloadElement) { if (payloadElement.Count == 0) { return; } var currentValue = this.queryValueStack.Peek() as QueryCollectionValue; ExceptionUtilities.CheckObjectNotNull(currentValue, "Current value was not a collection"); ExceptionUtilities.Assert(payloadElement.Count == currentValue.Elements.Count, "Number of elements did not match"); for (int i = 0; i < payloadElement.Count; i++) { try { this.queryValueStack.Push(currentValue.Elements[i]); this.Recurse(payloadElement[i]); } finally { this.queryValueStack.Pop(); } } }
/// <summary> /// Visits the payload element and annotates it with metadata /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var entitySet = this.MetadataStack.Peek() as EntitySet; ExceptionUtilities.CheckObjectNotNull(entitySet, "Expected entity set, got '{0}'", this.MetadataStack.Peek()); payloadElement.AddAnnotationIfNotExist(new EntitySetAnnotation() { EntitySet = entitySet }); foreach (var element in payloadElement) { this.Recurse(element); } }
/// <summary> /// Visits a payload element whose root is an EntitySetInstance. /// </summary> /// <param name="payloadElement">The root node of the payload element being visited.</param> public override void Visit(EntitySetInstance payloadElement) { base.Visit(payloadElement); // Entity set instances (Feeds) use different format in JSON for V2 (and higher) payloads in responses // so we need to add an annotation marking it with the right version so that the serializer will use the // V2 format. if (!this.requestPayload) { this.AddVersionAnnotation(payloadElement); } }
/// <summary> /// Deserializes the given element, which is assumed to be an atom feed, into an entity set /// </summary> /// <param name="feed">An atom feed xml element</param> /// <returns>The deserialized entity set</returns> private EntitySetInstance DeserializeEntitySet(XElement feed) { ExceptionUtilities.CheckArgumentNotNull(feed, "feed"); EntitySetInstance entitySet = new EntitySetInstance(); AddXmlBaseAnnotation(entitySet, feed); // set title XElement title = feed.Element(AtomTitle); if (title != null) { entitySet.Annotations.Add(new TitleAnnotation(title.Value)); } // read the count, if present XElement count = feed.Element(MetadataCount); if (count != null) { entitySet.InlineCount = long.Parse(count.Value, CultureInfo.InvariantCulture); } // read the next link, if present XElement nextLink = feed.Elements(AtomLink) .Select(l => l.Attribute(Rel)) .Where(rel => rel != null) .Where(rel => rel.Value == RelNext) .Select(rel => rel.Parent) .SingleOrDefault(); if (nextLink != null) { XAttribute href = nextLink.Attribute(Href); if (href != null) { entitySet.NextLink = href.Value; } } // deserialize and add each entry foreach (XElement entry in feed.Elements(AtomEntry)) { entitySet.Add(this.DeserializeEntity(entry)); } this.AddFeedEPMAnnotations(feed, entitySet); return entitySet; }
/// <summary> /// verification method to verify entity collection without verifying order. /// </summary> /// <param name="payloadElement">entity set instance</param> /// <param name="value">expected collection value</param> private void CompareUnsortedCollection(EntitySetInstance payloadElement, QueryCollectionValue value) { for (int i = 0; i < payloadElement.Count; i++) { var actual = payloadElement[i]; ExceptionUtilities.CheckObjectNotNull(actual, "Element at position {0} was unexpectedly null", i); bool match = false; foreach (var expected in value.Elements) { var ex = this.RecurseAndCatch(actual, expected); if (ex == null) { match = true; break; } } this.parent.Assert.IsTrue(match, "Element at position {0} did not match any expected value", i + 1); } }
private void AddFeedEPMAnnotations(XElement feedXElement, EntitySetInstance entitySetInstance) { // get all the properties mapped to atom-specific locations // note that this is driven off what is found, not what is expected based on metadata // Id foreach (var id in feedXElement.Elements(AtomId)) { this.AddEpmTree(entitySetInstance, id); } // Title foreach (var title in feedXElement.Elements(AtomTitle)) { this.AddEpmTree(entitySetInstance, title); } // Summary foreach (var summary in feedXElement.Elements(AtomSummary)) { this.AddEpmTree(entitySetInstance, summary); } // Rights foreach (var rights in feedXElement.Elements(AtomRights)) { this.AddEpmTree(entitySetInstance, rights); } // Published foreach (var published in feedXElement.Elements(AtomPublished)) { this.AddEpmTree(entitySetInstance, published); } // Updated foreach (var updated in feedXElement.Elements(AtomUpdated)) { this.AddEpmTree(entitySetInstance, updated); } // Author foreach (var author in feedXElement.Elements(AtomAuthor)) { // will recurse automatically this.AddEpmTree(entitySetInstance, author); } // Contributor foreach (var contributor in feedXElement.Elements(AtomContributor)) { // will recurse automatically this.AddEpmTree(entitySetInstance, contributor); } }
/// <summary> /// Visits a payload element whose root is a EntitySetInstance. /// </summary> /// <param name="payloadElement">The root node of the payload element being visited.</param> public override void Visit(EntitySetInstance payloadElement) { base.Visit(payloadElement); if (payloadElement.GetAnnotation<JsonLightContextUriAnnotation>() == null) { var typeAnnotation = payloadElement.Annotations.OfType<ExpectedTypeODataPayloadElementAnnotation>().SingleOrDefault(); if (typeAnnotation == null && this.payloadElementStack.Count == 1) { var annotation = payloadElement.GetAnnotation<EntityModelTypeAnnotation>(); if (annotation != null) { if (this.testDescriptor.PayloadEdmModel != null && annotation.EdmModelType != null) { var edmEntityType = annotation.EdmModelType; var edmEntitySet = FindEntitySet(this.testDescriptor.PayloadEdmModel, edmEntityType.Definition as IEdmSchemaType); payloadElement.ExpectedEntityType(edmEntityType, edmEntitySet); } } } } }
/// <summary> /// verification method to verify entity collection with predictable order. /// </summary> /// <param name="payloadElement">entity set instance</param> /// <param name="value">expected collection value</param> private void CompareSortedCollection(EntitySetInstance payloadElement, QueryCollectionValue value) { for (int i = 0; i < value.Elements.Count; i++) { this.RecurseWithMessage(payloadElement[i], value.Elements[i], "Element at position {0} did not match expectation", i + 1); } }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); this.IncreaseVersionIfNonNull(payloadElement.NextLink, DataServiceProtocolVersion.V4); base.Visit(payloadElement); }
/// <summary> /// Visits a payload element whose root is a EntitySetInstance. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); this.isRootElement = false; this.writer.StartArrayScope(); for (int i = 0; i < payloadElement.Count(); i++) { payloadElement[i].Accept(this); } this.writer.EndScope(); }
/// <summary> /// Visits a payload element whose root is an EntitySetInstance. /// </summary> /// <param name="payloadElement">The root node of payload element being visited.</param> public void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var current = this.expectedValueStack.Peek(); var value = current as QueryCollectionValue; ExceptionUtilities.CheckObjectNotNull(value, "Value was not a collection. Value was: '{0}'", current.ToString()); var entityType = value.Type.ElementType as QueryEntityType; ExceptionUtilities.CheckObjectNotNull(entityType, "Value was not a collection of entities. Value was: '{0}'", current.ToString()); this.parent.Assert.AreEqual(value.Elements.Count, payloadElement.Count, "Entity set count did not match expectation"); // apply different verification methods based on whether order is predictable. if (value.IsSorted) { this.CompareSortedCollection(payloadElement, value); } else { this.CompareUnsortedCollection(payloadElement, value); } // next-link verification now performed by seperate component. See NextLinkResponseVerifier. }
/// <summary> /// Visits the payload element /// </summary> /// <param name="payloadElement">The payload element to visit</param> public override void Visit(EntitySetInstance payloadElement) { ExceptionUtilities.CheckArgumentNotNull(payloadElement, "payloadElement"); var entitySetAnnotation = payloadElement.Annotations.OfType<EntitySetAnnotation>().SingleOrDefault(); ExceptionUtilities.CheckObjectNotNull(entitySetAnnotation, "Could not find entity-set annotation on payload element"); bool expectNextLink = false; var expectedPageSize = entitySetAnnotation.EntitySet.GetEffectivePageSize(); if (expectedPageSize.HasValue) { // note that the check that the number of elements is less-than-or-equal-to page size happens below expectNextLink = payloadElement.Count == expectedPageSize.Value; } string message; if (this.navigationStack.Count == 0) { message = "In root feed"; // if the service can tell from the uri that no paging is needed, there will be no next link if (expectNextLink && this.requestUri.Top.HasValue) { expectNextLink &= this.requestUri.Top.Value > expectedPageSize.Value; } } else { message = "In expanded feed"; } using (this.parent.AssertHandler.WithMessage(message)) { if (expectedPageSize.HasValue) { // verify number of elements. This is also validated based on query expectations in another verifier, // but its cheap and easy to cover here as well to cover our bases. this.parent.AssertHandler.IsTrue( payloadElement.Count <= expectedPageSize.Value, "Number of elements ({0}) exceeds page size ({1}).", payloadElement.Count, expectedPageSize.Value); } if (!expectNextLink) { this.parent.AssertHandler.IsNull(payloadElement.NextLink, "Next link unexpectedly non-null"); } else { this.parent.AssertHandler.IsNotNull(payloadElement.NextLink, "Next link unexpectedly null"); // only validate the next link if the protocol is implemented based on the expected conventions if (this.payloadOptions.HasFlag(ODataPayloadOptions.UseConventionBasedLinks)) { this.GenerateAndCompareNextLink(payloadElement, expectedPageSize.Value); } } this.Recurse(payloadElement); } }
private static void AddFeedMetadata(EntitySetInstance payloadElement, ODataFeed feed) { AtomFeedMetadata metadata = CreateFeedMetadata(payloadElement.Annotations.OfType<XmlTreeAnnotation>(), feed); // Fix up metadata for baselining metadata = metadata.Fixup(); if (metadata != null) { feed.SetAnnotation<AtomFeedMetadata>(metadata); } }
/// <summary> /// Converts the Object Model representation of Atom metadata for feeds into appropriate PayloadElement annotations /// </summary> /// <param name="feedMetadata">the Atom feed metadata, in Object Model representation, to convert</param> /// <param name="feed">the EntitySetInstance to annotate</param> private static void ConvertAtomFeedMetadata(AtomFeedMetadata feedMetadata, EntitySetInstance feed) { ExceptionUtilities.CheckArgumentNotNull(feedMetadata, "feedMetadata"); ExceptionUtilities.CheckArgumentNotNull(feed, "feed"); foreach (var author in feedMetadata.Authors) { feed.AtomAuthor(author.Name, author.Uri == null ? null : author.Uri.OriginalString, author.Email); } foreach (var category in feedMetadata.Categories) { feed.AtomCategory(category.Term, category.Scheme, category.Label); } foreach (var contributor in feedMetadata.Contributors) { feed.AtomContributor(contributor.Name, contributor.Uri == null ? null : contributor.Uri.OriginalString, contributor.Email); } if (feedMetadata.Generator != null) { feed.AtomGenerator(feedMetadata.Generator.Name, feedMetadata.Generator.Uri == null ? null : feedMetadata.Generator.Uri.OriginalString, feedMetadata.Generator.Version); } if (feedMetadata.Icon != null) { feed.AtomIcon(feedMetadata.Icon.OriginalString); } foreach (var link in feedMetadata.Links) { string linkLength = link.Length.HasValue ? link.Length.Value.ToString() : null; feed.AtomLink(link.Href == null ? null : link.Href.OriginalString, link.Relation, link.MediaType, link.HrefLang, link.Title, linkLength); } if (feedMetadata.Logo != null) { feed.AtomLogo(feedMetadata.Logo.OriginalString); } if (feedMetadata.Rights != null) { feed.AtomRights(feedMetadata.Rights.Text, ToString(feedMetadata.Rights.Kind)); } if (feedMetadata.SelfLink != null) { AtomLinkMetadata selfLink = feedMetadata.SelfLink; ExceptionUtilities.Assert(selfLink.Relation == TestAtomConstants.AtomSelfRelationAttributeValue, "The self link ATOM metadata must have the rel set to 'self'."); string selfLinkLength = selfLink.Length.HasValue ? selfLink.Length.Value.ToString() : null; feed.AtomSelfLink(selfLink.Href == null ? null : selfLink.Href.OriginalString, selfLink.MediaType, selfLink.HrefLang, selfLink.Title, selfLinkLength); } if (feedMetadata.NextPageLink != null) { AtomLinkMetadata nextPageLink = feedMetadata.NextPageLink; ExceptionUtilities.Assert(nextPageLink.Relation == TestAtomConstants.AtomNextRelationAttributeValue, "The next page link ATOM metadata must have the rel set to 'next'."); string nextPageLinkLength = nextPageLink.Length.HasValue ? nextPageLink.Length.Value.ToString() : null; feed.AtomNextPageLink(nextPageLink.Href == null ? null : nextPageLink.Href.OriginalString, nextPageLink.MediaType, nextPageLink.HrefLang, nextPageLink.Title, nextPageLinkLength); } if (feedMetadata.SourceId != null) { // This should only occur when the metadata comes from the source element of an entry // and we are annotating a temporary feed instance feed.AtomId(UriUtils.UriToString(feedMetadata.SourceId)); } if (feedMetadata.Subtitle != null) { feed.AtomSubtitle(feedMetadata.Subtitle.Text, ToString(feedMetadata.Subtitle.Kind)); } if (feedMetadata.Title != null) { feed.AtomTitle(feedMetadata.Title.Text, ToString(feedMetadata.Title.Kind)); } if (feedMetadata.Updated.HasValue) { feed.AtomUpdated(ToString(feedMetadata.Updated)); } }
/// <summary> /// Visit the EntitySetInstance to remove annotations. /// </summary> /// <param name="payloadElement">payloadElement to visit</param> public override void Visit(EntitySetInstance payloadElement) { payloadElement.Annotations.Clear(); base.Visit(payloadElement); }
public void ODataFeedWriterErrorTests() { var feed = new EntitySetInstance( new EntityInstance("TestModel.Type1", false) { Properties = new List<PropertyInstance>() { new PrimitiveProperty("StringProp", "Edm.String", "hello"), new PrimitiveProperty("IntProp", "Edm.Int32", 5) } }, new EntityInstance("TestModel.Type2", false) { Properties = new List<PropertyInstance>() { new PrimitiveProperty("GuidProp", "Edm.Guid", Guid.NewGuid()), new PrimitiveProperty("BooleanProp", "Edm.Boolean", true) } } ).WithDefaultAtomIDAnnotation(); List<PayloadWriterTestDescriptor<ODataPayloadElement>> testDescriptors = new List<PayloadWriterTestDescriptor<ODataPayloadElement>>() { // Skipping json because there is a fixup in the PayloadWriterTestDescriptor that will add the ID. // Write feed without ID. new PayloadWriterTestDescriptor<ODataPayloadElement>(this.Settings, (ODataPayloadElement)null) { PayloadElement = new EntitySetInstance(), SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, ExpectedResultCallback = (tc) => new PayloadWriterTestExpectedResults(this.ExpectedResultSettings) { ExpectedException2 = ODataExpectedExceptions.ODataException("ODataAtomWriter_FeedsMustHaveNonEmptyId") } }, // Write feed with inline count on a request. new PayloadWriterTestDescriptor<ODataPayloadElement>(this.Settings, (ODataPayloadElement)null) { PayloadElement = new EntitySetInstance(){ InlineCount = 0 }.WithDefaultAtomIDAnnotation(), SkipTestConfiguration = (tc) => !tc.IsRequest, ExpectedResultCallback = (tc) => new PayloadWriterTestExpectedResults(this.ExpectedResultSettings) { ExpectedException2 = ODataExpectedExceptions.ODataException("ODataWriterCore_QueryCountInRequest") } }, // Write feed with next link on a request. new PayloadWriterTestDescriptor<ODataPayloadElement>(this.Settings, (ODataPayloadElement)null) { PayloadElement = new EntitySetInstance(){ NextLink = "http://www.odata.org"}.WithDefaultAtomIDAnnotation(), SkipTestConfiguration = (tc) => !tc.IsRequest, ExpectedResultCallback = (tc) => new PayloadWriterTestExpectedResults(this.ExpectedResultSettings) { ExpectedException2 = ODataExpectedExceptions.ODataException("WriterValidationUtils_NextPageLinkInRequest") } }, // TODO: Add appropriate exception and enable the test when this is bug is fixed. // new PayloadWriterTestDescriptor<ODataPayloadElement>(this.Settings, feed) // { // ExpectedResultCallback = (tc) => new PayloadWriterTestExpectedResults(this.ExpectedResultSettings) // { // ExpectedException2 = // } // }, }; this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.WriterTestConfigurationProvider.AtomFormatConfigurations, (testDescriptor, testConfig) => { testConfig = testConfig.Clone(); testConfig.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); testDescriptor.RunTest(testConfig, this.Logger); }); }