public void ApplyNavigationProperty_Calls_ReadInlineOnEntry() { // Arrange Mock <ODataEdmTypeDeserializer> supplierDeserializer = new Mock <ODataEdmTypeDeserializer>(ODataPayloadKind.Feed); Mock <ODataDeserializerProvider> deserializerProvider = new Mock <ODataDeserializerProvider>(); var deserializer = new ODataEntityDeserializer(deserializerProvider.Object); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Supplier" }); navigationLink.NestedItems.Add(new ODataEntryWithNavigationLinks(new ODataEntry())); Product product = new Product(); Supplier supplier = new Supplier { ID = 42 }; deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny <IEdmTypeReference>())).Returns(supplierDeserializer.Object); supplierDeserializer .Setup(d => d.ReadInline(navigationLink.NestedItems[0], _productEdmType.FindNavigationProperty("Supplier").Type, _readContext)) .Returns(supplier).Verifiable(); // Act deserializer.ApplyNavigationProperty(product, navigationLink, _productEdmType, _readContext); // Assert supplierDeserializer.Verify(); Assert.Equal(supplier, product.Supplier); }
public void ApplyNavigationProperty_UsesThePropertyAlias_ForEntry() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer))); model.Model.SetAnnotationValue(model.Order, new ClrTypeAnnotation(typeof(Order))); model.Model.SetAnnotationValue( model.Order.FindProperty("Customer"), new ClrPropertyInfoAnnotation(typeof(Order).GetProperty("AliasedCustomer"))); ODataEntry entry = new ODataEntry { Properties = new[] { new ODataProperty { Name = "ID", Value = 42 } } }; Order order = new Order(); ODataNavigationLinkWithItems navLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Customer" }); navLink.NestedItems.Add(new ODataEntryWithNavigationLinks(entry)); ODataDeserializerContext context = new ODataDeserializerContext { Model = model.Model }; // Act new ODataEntityDeserializer(_deserializerProvider) .ApplyNavigationProperty(order, navLink, model.Order.AsReference(), context); // Assert Assert.Equal(order.AliasedCustomer.ID, 42); }
public void ApplyNavigationProperty_Calls_ReadInlineOnFeed() { // Arrange IEdmCollectionTypeReference productsType = new EdmCollectionTypeReference(new EdmCollectionType(_productEdmType)); Mock <ODataEdmTypeDeserializer> productsDeserializer = new Mock <ODataEdmTypeDeserializer>(ODataPayloadKind.Feed); Mock <ODataDeserializerProvider> deserializerProvider = new Mock <ODataDeserializerProvider>(); var deserializer = new ODataEntityDeserializer(deserializerProvider.Object); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Products" }); navigationLink.NestedItems.Add(new ODataFeedWithEntries(new ODataFeed())); Supplier supplier = new Supplier(); IEnumerable products = new[] { new Product { ID = 42 } }; deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny <IEdmTypeReference>())).Returns(productsDeserializer.Object); productsDeserializer .Setup(d => d.ReadInline(navigationLink.NestedItems[0], _supplierEdmType.FindNavigationProperty("Products").Type, _readContext)) .Returns(products).Verifiable(); // Act deserializer.ApplyNavigationProperty(supplier, navigationLink, _supplierEdmType, _readContext); // Assert productsDeserializer.Verify(); Assert.Equal(1, supplier.Products.Count()); Assert.Equal(42, supplier.Products.First().ID); }
public void ApplyNavigationProperty_ThrowsArgumentNull_EntityResource() { var deserializer = new ODataEntityDeserializer(_deserializerProvider); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink()); Assert.ThrowsArgumentNull( () => deserializer.ApplyNavigationProperty(entityResource: null, navigationLinkWrapper: navigationLink, entityType: _productEdmType, readContext: _readContext), "entityResource"); }
public void ApplyNavigationProperty_ThrowsODataException_NavigationPropertyNotfound() { var deserializer = new ODataEntityDeserializer(_deserializerProvider); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "SomeProperty" }); Assert.Throws <ODataException>( () => deserializer.ApplyNavigationProperty(42, navigationLink, _productEdmType, _readContext), "Cannot find navigation property 'SomeProperty' on the entity type 'ODataDemo.Product'."); }
public void ApplyNavigationProperty_ThrowsODataException_WhenPatchingCollectionNavigationProperty() { var deserializer = new ODataEntityDeserializer(_deserializerProvider); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Products" }); navigationLink.NestedItems.Add(new ODataFeedWithEntries(new ODataFeed())); _readContext.ResourceType = typeof(Delta <Supplier>); Assert.Throws <ODataException>( () => deserializer.ApplyNavigationProperty(42, navigationLink, _supplierEdmType, _readContext), "Cannot apply PATCH to navigation property 'Products' on entity type 'ODataDemo.Supplier'."); }
/// <summary> /// Deserializes the navigation property from <paramref name="navigationLinkWrapper"/> into <paramref name="entityResource"/>. /// </summary> /// <param name="entityResource">The object into which the navigation property should be read.</param> /// <param name="navigationLinkWrapper">The navigation link.</param> /// <param name="entityType">The entity type of the entity resource.</param> /// <param name="readContext">The deserializer context.</param> public virtual void ApplyNavigationProperty(object entityResource, ODataNavigationLinkWithItems navigationLinkWrapper, IEdmEntityTypeReference entityType, ODataDeserializerContext readContext) { if (navigationLinkWrapper == null) { throw Error.ArgumentNull("navigationLinkWrapper"); } if (entityResource == null) { throw Error.ArgumentNull("entityResource"); } IEdmNavigationProperty navigationProperty = entityType.FindProperty(navigationLinkWrapper.NavigationLink.Name) as IEdmNavigationProperty; if (navigationProperty == null) { throw new ODataException( Error.Format(SRResources.NavigationPropertyNotfound, navigationLinkWrapper.NavigationLink.Name, entityType.FullName())); } foreach (ODataItemBase childItem in navigationLinkWrapper.NestedItems) { ODataEntityReferenceLinkBase entityReferenceLink = childItem as ODataEntityReferenceLinkBase; if (entityReferenceLink != null) { // ignore links. continue; } ODataFeedWithEntries feed = childItem as ODataFeedWithEntries; if (feed != null) { ApplyFeedInNavigationProperty(navigationProperty, entityResource, feed, readContext); continue; } // It must be entry by now. ODataEntryWithNavigationLinks entry = (ODataEntryWithNavigationLinks)childItem; if (entry != null) { ApplyEntryInNavigationProperty(navigationProperty, entityResource, entry, readContext); } } }
public void ApplyNavigationProperty_UsesThePropertyAlias_ForFeed() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer))); model.Model.SetAnnotationValue(model.Order, new ClrTypeAnnotation(typeof(Order))); model.Model.SetAnnotationValue( model.Customer.FindProperty("Orders"), new ClrPropertyInfoAnnotation(typeof(Customer).GetProperty("AliasedOrders"))); ODataFeedWithEntries feedWrapper = new ODataFeedWithEntries(new ODataFeed()); feedWrapper.Entries.Add(new ODataEntryWithNavigationLinks( new ODataEntry { Properties = new[] { new ODataProperty { Name = "ID", Value = 42 } } })); Customer customer = new Customer(); ODataNavigationLinkWithItems navLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Orders" }); navLink.NestedItems.Add(feedWrapper); ODataDeserializerContext context = new ODataDeserializerContext { Model = model.Model }; // Act new ODataEntityDeserializer(_deserializerProvider) .ApplyNavigationProperty(customer, navLink, model.Customer.AsReference(), context); // Assert Assert.Equal(1, customer.AliasedOrders.Count()); Assert.Equal(42, customer.AliasedOrders[0].ID); }
/// <summary> /// Reads an ODataFeed or an ODataItem from the reader. /// </summary> /// <param name="reader">The OData reader to read from.</param> /// <returns>The read feed or entry.</returns> public static ODataItemBase ReadEntryOrFeed(ODataReader reader) { if (reader == null) { throw Error.ArgumentNull("odataReader"); } ODataItemBase topLevelItem = null; Stack<ODataItemBase> itemsStack = new Stack<ODataItemBase>(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryStart: ODataEntry entry = (ODataEntry)reader.Item; ODataEntryWithNavigationLinks entryWrapper = null; if (entry != null) { entryWrapper = new ODataEntryWithNavigationLinks(entry); } if (itemsStack.Count == 0) { Contract.Assert(entry != null, "The top-level entry can never be null."); topLevelItem = entryWrapper; } else { ODataItemBase parentItem = itemsStack.Peek(); ODataFeedWithEntries parentFeed = parentItem as ODataFeedWithEntries; if (parentFeed != null) { parentFeed.Entries.Add(entryWrapper); } else { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)parentItem; Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == false, "Only singleton navigation properties can contain entry as their child."); Contract.Assert(parentNavigationLink.NestedItems.Count == 0, "Each navigation property can contain only one entry as its direct child."); parentNavigationLink.NestedItems.Add(entryWrapper); } } itemsStack.Push(entryWrapper); break; case ODataReaderState.EntryEnd: Contract.Assert(itemsStack.Count > 0 && (reader.Item == null || itemsStack.Peek().Item == reader.Item), "The entry which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.NavigationLinkStart: ODataNavigationLink navigationLink = (ODataNavigationLink)reader.Item; Contract.Assert(navigationLink != null, "Navigation link should never be null."); ODataNavigationLinkWithItems navigationLinkWrapper = new ODataNavigationLinkWithItems(navigationLink); Contract.Assert(itemsStack.Count > 0, "Navigation link can't appear as top-level item."); { ODataEntryWithNavigationLinks parentEntry = (ODataEntryWithNavigationLinks)itemsStack.Peek(); parentEntry.NavigationLinks.Add(navigationLinkWrapper); } itemsStack.Push(navigationLinkWrapper); break; case ODataReaderState.NavigationLinkEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The navigation link which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.FeedStart: ODataFeed feed = (ODataFeed)reader.Item; Contract.Assert(feed != null, "Feed should never be null."); ODataFeedWithEntries feedWrapper = new ODataFeedWithEntries(feed); if (itemsStack.Count > 0) { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek(); Contract.Assert(parentNavigationLink != null, "this has to be an inner feed. inner feeds always have a navigation link."); Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == true, "Only collection navigation properties can contain feed as their child."); parentNavigationLink.NestedItems.Add(feedWrapper); } else { topLevelItem = feedWrapper; } itemsStack.Push(feedWrapper); break; case ODataReaderState.FeedEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The feed which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.EntityReferenceLink: ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)reader.Item; Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null."); ODataEntityReferenceLinkBase entityReferenceLinkWrapper = new ODataEntityReferenceLinkBase(entityReferenceLink); Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item."); { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek(); parentNavigationLink.NestedItems.Add(entityReferenceLinkWrapper); } break; default: Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state."); break; } } Contract.Assert(reader.State == ODataReaderState.Completed, "We should have consumed all of the input by now."); Contract.Assert(topLevelItem != null, "A top level entry or feed should have been read by now."); return topLevelItem; }
public void ApplyNavigationProperty_ThrowsODataException_NavigationPropertyNotfound() { var deserializer = new ODataEntityDeserializer(_deserializerProvider); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "SomeProperty" }); Assert.Throws<ODataException>( () => deserializer.ApplyNavigationProperty(42, navigationLink, _productEdmType, _readContext), "Cannot find navigation property 'SomeProperty' on the entity type 'ODataDemo.Product'."); }
/// <summary> /// Reads an ODataFeed or an ODataItem from the reader. /// </summary> /// <param name="reader">The OData reader to read from.</param> /// <returns>The read feed or entry.</returns> public static ODataItemBase ReadEntryOrFeed(ODataReader reader) { if (reader == null) { throw Error.ArgumentNull("odataReader"); } ODataItemBase topLevelItem = null; Stack <ODataItemBase> itemsStack = new Stack <ODataItemBase>(); while (reader.Read()) { switch (reader.State) { case ODataReaderState.EntryStart: ODataEntry entry = (ODataEntry)reader.Item; ODataEntryWithNavigationLinks entryWrapper = null; if (entry != null) { entryWrapper = new ODataEntryWithNavigationLinks(entry); } if (itemsStack.Count == 0) { Contract.Assert(entry != null, "The top-level entry can never be null."); topLevelItem = entryWrapper; } else { ODataItemBase parentItem = itemsStack.Peek(); ODataFeedWithEntries parentFeed = parentItem as ODataFeedWithEntries; if (parentFeed != null) { parentFeed.Entries.Add(entryWrapper); } else { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)parentItem; Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == false, "Only singleton navigation properties can contain entry as their child."); Contract.Assert(parentNavigationLink.NestedItems.Count == 0, "Each navigation property can contain only one entry as its direct child."); parentNavigationLink.NestedItems.Add(entryWrapper); } } itemsStack.Push(entryWrapper); break; case ODataReaderState.EntryEnd: Contract.Assert(itemsStack.Count > 0 && (reader.Item == null || itemsStack.Peek().Item == reader.Item), "The entry which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.NavigationLinkStart: ODataNavigationLink navigationLink = (ODataNavigationLink)reader.Item; Contract.Assert(navigationLink != null, "Navigation link should never be null."); ODataNavigationLinkWithItems navigationLinkWrapper = new ODataNavigationLinkWithItems(navigationLink); Contract.Assert(itemsStack.Count > 0, "Navigation link can't appear as top-level item."); { ODataEntryWithNavigationLinks parentEntry = (ODataEntryWithNavigationLinks)itemsStack.Peek(); parentEntry.NavigationLinks.Add(navigationLinkWrapper); } itemsStack.Push(navigationLinkWrapper); break; case ODataReaderState.NavigationLinkEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The navigation link which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.FeedStart: ODataFeed feed = (ODataFeed)reader.Item; Contract.Assert(feed != null, "Feed should never be null."); ODataFeedWithEntries feedWrapper = new ODataFeedWithEntries(feed); if (itemsStack.Count > 0) { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek(); Contract.Assert(parentNavigationLink != null, "this has to be an inner feed. inner feeds always have a navigation link."); Contract.Assert(parentNavigationLink.NavigationLink.IsCollection == true, "Only collection navigation properties can contain feed as their child."); parentNavigationLink.NestedItems.Add(feedWrapper); } else { topLevelItem = feedWrapper; } itemsStack.Push(feedWrapper); break; case ODataReaderState.FeedEnd: Contract.Assert(itemsStack.Count > 0 && itemsStack.Peek().Item == reader.Item, "The feed which is ending should be on the top of the items stack."); itemsStack.Pop(); break; case ODataReaderState.EntityReferenceLink: ODataEntityReferenceLink entityReferenceLink = (ODataEntityReferenceLink)reader.Item; Contract.Assert(entityReferenceLink != null, "Entity reference link should never be null."); ODataEntityReferenceLinkBase entityReferenceLinkWrapper = new ODataEntityReferenceLinkBase(entityReferenceLink); Contract.Assert(itemsStack.Count > 0, "Entity reference link should never be reported as top-level item."); { ODataNavigationLinkWithItems parentNavigationLink = (ODataNavigationLinkWithItems)itemsStack.Peek(); parentNavigationLink.NestedItems.Add(entityReferenceLinkWrapper); } break; default: Contract.Assert(false, "We should never get here, it means the ODataReader reported a wrong state."); break; } } Contract.Assert(reader.State == ODataReaderState.Completed, "We should have consumed all of the input by now."); Contract.Assert(topLevelItem != null, "A top level entry or feed should have been read by now."); return(topLevelItem); }
public void ApplyNavigationProperty_Calls_ReadInlineOnEntry() { // Arrange Mock<ODataEdmTypeDeserializer> supplierDeserializer = new Mock<ODataEdmTypeDeserializer>(ODataPayloadKind.Feed); Mock<ODataDeserializerProvider> deserializerProvider = new Mock<ODataDeserializerProvider>(); var deserializer = new ODataEntityDeserializer(deserializerProvider.Object); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Supplier" }); navigationLink.NestedItems.Add(new ODataEntryWithNavigationLinks(new ODataEntry())); Product product = new Product(); Supplier supplier = new Supplier { ID = 42 }; deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny<IEdmTypeReference>())).Returns(supplierDeserializer.Object); supplierDeserializer .Setup(d => d.ReadInline(navigationLink.NestedItems[0], _productEdmType.FindNavigationProperty("Supplier").Type, _readContext)) .Returns(supplier).Verifiable(); // Act deserializer.ApplyNavigationProperty(product, navigationLink, _productEdmType, _readContext); // Assert supplierDeserializer.Verify(); Assert.Equal(supplier, product.Supplier); }
public void ApplyNavigationProperty_Calls_ReadInlineOnFeed() { // Arrange IEdmCollectionTypeReference productsType = new EdmCollectionTypeReference(new EdmCollectionType(_productEdmType)); Mock<ODataEdmTypeDeserializer> productsDeserializer = new Mock<ODataEdmTypeDeserializer>(ODataPayloadKind.Feed); Mock<ODataDeserializerProvider> deserializerProvider = new Mock<ODataDeserializerProvider>(); var deserializer = new ODataEntityDeserializer(deserializerProvider.Object); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Products" }); navigationLink.NestedItems.Add(new ODataFeedWithEntries(new ODataFeed())); Supplier supplier = new Supplier(); IEnumerable products = new[] { new Product { ID = 42 } }; deserializerProvider.Setup(d => d.GetEdmTypeDeserializer(It.IsAny<IEdmTypeReference>())).Returns(productsDeserializer.Object); productsDeserializer .Setup(d => d.ReadInline(navigationLink.NestedItems[0], _supplierEdmType.FindNavigationProperty("Products").Type, _readContext)) .Returns(products).Verifiable(); // Act deserializer.ApplyNavigationProperty(supplier, navigationLink, _supplierEdmType, _readContext); // Assert productsDeserializer.Verify(); Assert.Equal(1, supplier.Products.Count()); Assert.Equal(42, supplier.Products.First().ID); }
public void ApplyNavigationProperty_ThrowsODataException_WhenPatchingCollectionNavigationProperty() { var deserializer = new ODataEntityDeserializer(_deserializerProvider); ODataNavigationLinkWithItems navigationLink = new ODataNavigationLinkWithItems(new ODataNavigationLink { Name = "Products" }); navigationLink.NestedItems.Add(new ODataFeedWithEntries(new ODataFeed())); _readContext.ResourceType = typeof(Delta<Supplier>); Assert.Throws<ODataException>( () => deserializer.ApplyNavigationProperty(42, navigationLink, _supplierEdmType, _readContext), "Cannot apply PATCH to navigation property 'Products' on entity type 'ODataDemo.Supplier'."); }