public void QueryOptionWithEmptyValueShouldWork() { var uriParser = new ODataQueryOptionParser(HardCodedTestModel.TestModel, HardCodedTestModel.GetPersonType(), HardCodedTestModel.GetPeopleSet(), new Dictionary<string, string>() { {"$filter" , ""}, {"$expand" , ""}, {"$select" , ""}, {"$orderby" , ""}, {"$top" , ""}, {"$skip" , ""}, {"$count" , ""}, {"$search" , ""}, {"$unknow" , ""}, }); uriParser.ParseFilter().Should().BeNull(); var results = uriParser.ParseSelectAndExpand(); results.AllSelected.Should().BeTrue(); results.SelectedItems.Should().HaveCount(0); uriParser.ParseOrderBy().Should().BeNull(); Action action = () => uriParser.ParseTop(); action.ShouldThrow<ODataException>().WithMessage(Strings.SyntacticTree_InvalidTopQueryOptionValue("")); action = () => uriParser.ParseSkip(); action.ShouldThrow<ODataException>().WithMessage(Strings.SyntacticTree_InvalidSkipQueryOptionValue("")); action = () => uriParser.ParseCount(); action.ShouldThrow<ODataException>().WithMessage(Strings.ODataUriParser_InvalidCount("")); action = () => uriParser.ParseSearch(); action.ShouldThrow<ODataException>().WithMessage(Strings.UriQueryExpressionParser_ExpressionExpected(0, "")); }
/// <summary> /// Creates a new instance of the <see cref="SelectExpandNode"/> class describing the set of structural properties, /// navigation properties, and actions to select and expand for the given <paramref name="writeContext"/>. /// </summary> /// <param name="entityType">The entity type of the entry that would be written.</param> /// <param name="writeContext">The serializer context to be used while creating the collection.</param> /// <remarks>The default constructor is for unit testing only.</remarks> public SelectExpandNode(IEdmEntityType entityType, ODataSerializerContext writeContext) : this(writeContext.SelectExpandClause, entityType, writeContext.Model) { var queryOptionParser = new ODataQueryOptionParser( writeContext.Model, entityType, writeContext.NavigationSource, _extraQueryParameters); var selectExpandClause = queryOptionParser.ParseSelectAndExpand(); if (selectExpandClause != null) { foreach (SelectItem selectItem in selectExpandClause.SelectedItems) { ExpandedNavigationSelectItem expandItem = selectItem as ExpandedNavigationSelectItem; if (expandItem != null) { ValidatePathIsSupported(expandItem.PathToNavigationProperty); NavigationPropertySegment navigationSegment = (NavigationPropertySegment)expandItem.PathToNavigationProperty.LastSegment; IEdmNavigationProperty navigationProperty = navigationSegment.NavigationProperty; if (!ExpandedNavigationProperties.ContainsKey(navigationProperty)) { ExpandedNavigationProperties.Add(navigationProperty, expandItem.SelectAndExpand); } } } } SelectedNavigationProperties.ExceptWith(ExpandedNavigationProperties.Keys); }
public void EmptyQueryOptionDictionaryShouldWork() { var uriParser = new ODataQueryOptionParser(HardCodedTestModel.TestModel, HardCodedTestModel.GetPersonType(), HardCodedTestModel.GetPeopleSet(), new Dictionary<string, string>()); uriParser.ParseFilter().Should().BeNull(); uriParser.ParseSelectAndExpand().Should().BeNull(); uriParser.ParseOrderBy().Should().BeNull(); uriParser.ParseTop().Should().Be(null); uriParser.ParseSkip().Should().Be(null); uriParser.ParseCount().Should().Be(null); uriParser.ParseSearch().Should().BeNull(); }
[InlineData("ID", "Orders($select=ID),Orders($expand=Customer($select=ID))", true, "ID")] // deep expand and selects public void GetPropertiesToBeSelected_Selects_ExpectedProperties_OnCustomer( string select, string expand, bool specialCustomer, string structuralPropertiesToSelect) { // Arrange ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers, new Dictionary<string, string> { { "$select", select }, { "$expand", expand } }); SelectExpandClause selectExpandClause = parser.ParseSelectAndExpand(); IEdmEntityType entityType = specialCustomer ? _model.SpecialCustomer : _model.Customer; // Act SelectExpandNode selectExpandNode = new SelectExpandNode(selectExpandClause, entityType, _model.Model); var result = selectExpandNode.SelectedStructuralProperties; // Assert Assert.Equal(structuralPropertiesToSelect, String.Join(",", result.Select(p => p.Name).OrderBy(n => n))); }
public void WriteObjectInline_CanWriteExpandedNavigationProperty_DerivedExpandedSingleValuedNavigationPropertyIsNull() { // Arrange IEdmEntityType specialOrderType = (IEdmEntityType)_specialOrderType.Definition; IEdmNavigationProperty customerProperty = specialOrderType.NavigationProperties().Single(p => p.Name == "SpecialCustomer"); Mock<IEdmEntityObject> order = new Mock<IEdmEntityObject>(); object customerValue = null; order.Setup(c => c.TryGetPropertyValue("SpecialCustomer", out customerValue)).Returns(true); order.Setup(c => c.GetEdmType()).Returns(_specialOrderType); IEdmEntityType orderType = (IEdmEntityType)_orderType.Definition; ODataQueryOptionParser parser = new ODataQueryOptionParser( _model, orderType, _orderSet, new Dictionary<string, string> { { "$select", "Default.SpecialOrder/SpecialCustomer" }, { "$expand", "Default.SpecialOrder/SpecialCustomer" } }); SelectExpandClause selectExpandClause = parser.ParseSelectAndExpand(); SelectExpandNode selectExpandNode = new SelectExpandNode(); selectExpandNode.ExpandedNavigationProperties[customerProperty] = selectExpandClause.SelectedItems.OfType<ExpandedNavigationSelectItem>().Single().SelectAndExpand; Mock<ODataWriter> writer = new Mock<ODataWriter>(); writer.Setup(w => w.WriteStart(null as ODataEntry)).Verifiable(); Mock<ODataEdmTypeSerializer> ordersSerializer = new Mock<ODataEdmTypeSerializer>(ODataPayloadKind.Entry); Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(); serializerProvider.Setup(p => p.GetEdmTypeSerializer(customerProperty.Type)) .Returns(ordersSerializer.Object); Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(serializerProvider.Object); serializer.Setup(s => s.CreateSelectExpandNode(It.IsAny<EntityInstanceContext>())).Returns(selectExpandNode); serializer.CallBase = true; // Act serializer.Object.WriteObjectInline(order.Object, _orderType, writer.Object, _writeContext); // Assert writer.Verify(); }
public void WriteObjectInline_CanWriteExpandedNavigationProperty_DerivedExpandedCollectionValuedNavigationPropertyIsNull() { // Arrange IEdmEntityType specialCustomerType = (IEdmEntityType)_specialCustomerType.Definition; IEdmNavigationProperty specialOrdersProperty = specialCustomerType.NavigationProperties().Single(p => p.Name == "SpecialOrders"); Mock<IEdmEntityObject> customer = new Mock<IEdmEntityObject>(); object specialOrdersValue = null; customer.Setup(c => c.TryGetPropertyValue("SpecialOrders", out specialOrdersValue)).Returns(true); customer.Setup(c => c.GetEdmType()).Returns(_specialCustomerType); IEdmEntityType customerType = _customerSet.EntityType(); ODataQueryOptionParser parser = new ODataQueryOptionParser( _model, customerType, _customerSet, new Dictionary<string, string> { { "$select", "Default.SpecialCustomer/SpecialOrders" }, { "$expand", "Default.SpecialCustomer/SpecialOrders" } }); SelectExpandClause selectExpandClause = parser.ParseSelectAndExpand(); SelectExpandNode selectExpandNode = new SelectExpandNode(); selectExpandNode.ExpandedNavigationProperties[specialOrdersProperty] = selectExpandClause.SelectedItems.OfType<ExpandedNavigationSelectItem>().Single().SelectAndExpand; Mock<ODataWriter> writer = new Mock<ODataWriter>(); writer.Setup(w => w.WriteStart(It.IsAny<ODataFeed>())).Callback( (ODataFeed feed) => { Assert.Null(feed.Count); Assert.Null(feed.DeltaLink); Assert.Null(feed.Id); Assert.Empty(feed.InstanceAnnotations); Assert.Null(feed.NextPageLink); }).Verifiable(); Mock<ODataEdmTypeSerializer> ordersSerializer = new Mock<ODataEdmTypeSerializer>(ODataPayloadKind.Entry); Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(); serializerProvider.Setup(p => p.GetEdmTypeSerializer(specialOrdersProperty.Type)) .Returns(ordersSerializer.Object); Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(serializerProvider.Object); serializer.Setup(s => s.CreateSelectExpandNode(It.IsAny<EntityInstanceContext>())).Returns(selectExpandNode); serializer.CallBase = true; // Act serializer.Object.WriteObjectInline(customer.Object, _customerType, writer.Object, _writeContext); // Assert writer.Verify(); }
public void WriteObjectInline_CanExpandNavigationProperty_ContainingEdmObject() { // Arrange IEdmEntityType customerType = _customerSet.EntityType(); IEdmNavigationProperty ordersProperty = customerType.NavigationProperties().Single(p => p.Name == "Orders"); Mock<IEdmObject> orders = new Mock<IEdmObject>(); orders.Setup(o => o.GetEdmType()).Returns(ordersProperty.Type); object ordersValue = orders.Object; Mock<IEdmEntityObject> customer = new Mock<IEdmEntityObject>(); customer.Setup(c => c.TryGetPropertyValue("Orders", out ordersValue)).Returns(true); customer.Setup(c => c.GetEdmType()).Returns(customerType.AsReference()); ODataQueryOptionParser parser = new ODataQueryOptionParser(_model, customerType, _customerSet, new Dictionary<string, string> { { "$select", "Orders" }, { "$expand", "Orders" } }); SelectExpandClause selectExpandClause = parser.ParseSelectAndExpand(); SelectExpandNode selectExpandNode = new SelectExpandNode(); selectExpandNode.ExpandedNavigationProperties[ordersProperty] = selectExpandClause.SelectedItems.OfType<ExpandedNavigationSelectItem>().Single().SelectAndExpand; Mock<ODataWriter> writer = new Mock<ODataWriter>(); Mock<ODataEdmTypeSerializer> ordersSerializer = new Mock<ODataEdmTypeSerializer>(ODataPayloadKind.Entry); ordersSerializer.Setup(s => s.WriteObjectInline(ordersValue, ordersProperty.Type, writer.Object, It.IsAny<ODataSerializerContext>())).Verifiable(); Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(); serializerProvider.Setup(p => p.GetEdmTypeSerializer(ordersProperty.Type)).Returns(ordersSerializer.Object); Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(serializerProvider.Object); serializer.Setup(s => s.CreateSelectExpandNode(It.IsAny<EntityInstanceContext>())).Returns(selectExpandNode); serializer.CallBase = true; // Act serializer.Object.WriteObjectInline(customer.Object, _customerType, writer.Object, _writeContext); //Assert ordersSerializer.Verify(); }
public void WriteObjectInline_ExpandsUsingInnerSerializerUsingRightContext_ExpandedNavigationProperties() { // Arrange IEdmEntityType customerType = _customerSet.EntityType(); IEdmNavigationProperty ordersProperty = customerType.NavigationProperties().Single(p => p.Name == "Orders"); ODataQueryOptionParser parser = new ODataQueryOptionParser(_model, customerType, _customerSet, new Dictionary<string, string> { { "$select", "Orders" }, { "$expand", "Orders" } }); SelectExpandClause selectExpandClause = parser.ParseSelectAndExpand(); SelectExpandNode selectExpandNode = new SelectExpandNode { ExpandedNavigationProperties = { { ordersProperty, selectExpandClause.SelectedItems.OfType<ExpandedNavigationSelectItem>().Single().SelectAndExpand } } }; Mock<ODataWriter> writer = new Mock<ODataWriter>(); Mock<ODataEdmTypeSerializer> innerSerializer = new Mock<ODataEdmTypeSerializer>(ODataPayloadKind.Entry); innerSerializer .Setup(s => s.WriteObjectInline(_customer.Orders, ordersProperty.Type, writer.Object, It.IsAny<ODataSerializerContext>())) .Callback((object o, IEdmTypeReference t, ODataWriter w, ODataSerializerContext context) => { Assert.Same(context.NavigationSource.Name, "Orders"); Assert.Same(context.SelectExpandClause, selectExpandNode.ExpandedNavigationProperties.Single().Value); }) .Verifiable(); Mock<ODataSerializerProvider> serializerProvider = new Mock<ODataSerializerProvider>(); serializerProvider.Setup(p => p.GetEdmTypeSerializer(ordersProperty.Type)) .Returns(innerSerializer.Object); Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(serializerProvider.Object); serializer.Setup(s => s.CreateSelectExpandNode(It.IsAny<EntityInstanceContext>())).Returns(selectExpandNode); serializer.CallBase = true; _writeContext.SelectExpandClause = selectExpandClause; // Act serializer.Object.WriteObjectInline(_customer, _customerType, writer.Object, _writeContext); // Assert innerSerializer.Verify(); // check that the context is rolled back Assert.Same(_writeContext.NavigationSource.Name, "Customers"); Assert.Same(_writeContext.SelectExpandClause, selectExpandClause); }
public void QueryOptionWithNullValueShouldWork() { var uriParser = new ODataQueryOptionParser(HardCodedTestModel.TestModel, HardCodedTestModel.GetPersonType(), HardCodedTestModel.GetPeopleSet(), new Dictionary<string, string>() { {"$filter" , null}, {"$expand" , null}, {"$select" , null}, {"$orderby" , null}, {"$top" , null}, {"$skip" , null}, {"$count" , null}, {"$search" , null}, {"$unknow" , null}, }); uriParser.ParseFilter().Should().BeNull(); uriParser.ParseSelectAndExpand().Should().BeNull(); uriParser.ParseOrderBy().Should().BeNull(); uriParser.ParseTop().Should().Be(null); uriParser.ParseSkip().Should().Be(null); uriParser.ParseCount().Should().Be(null); uriParser.ParseSearch().Should().BeNull(); }
public void ProjectAsWrapper_ProjectedValueContainsConcurrencyProperties_EvenIfNotPresentInSelectClause(string select) { // Arrange Customer customer = new Customer { ID = 42, City = "any" }; ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers, new Dictionary<string, string> { { "$select", select } }); SelectExpandClause selectExpand = parser.ParseSelectAndExpand(); Expression source = Expression.Constant(customer); // Act Expression projection = _binder.ProjectAsWrapper(source, selectExpand, _model.Customer); // Assert SelectExpandWrapper<Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Customer>; Assert.Equal(customer.City, customerWrapper.Container.ToDictionary(new IdentityPropertyMapper())["City"]); }
public void ProjectAsWrapper_Element_ProjectedValueContains_SelectedStructuralProperties() { // Arrange Customer customer = new Customer { Name = "OData" }; ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers, new Dictionary<string, string> { { "$select", "Name,Orders" }, { "$expand", "Orders" } }); SelectExpandClause selectExpand = parser.ParseSelectAndExpand(); Expression source = Expression.Constant(customer); // Act Expression projection = _binder.ProjectAsWrapper(source, selectExpand, _model.Customer); // Assert SelectExpandWrapper<Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Customer>; Assert.Equal(customer.Name, customerWrapper.Container.ToDictionary(new IdentityPropertyMapper())["Name"]); }
public void ProjectAsWrapper_Element_ProjectedValueDoesNotContainInstance_IfSelectionIsPartial() { // Arrange Customer customer = new Customer(); ODataQueryOptionParser parser = new ODataQueryOptionParser(_model.Model, _model.Customer, _model.Customers, new Dictionary<string, string> { { "$select", "ID,Orders" }, { "$expand", "Orders" } }); SelectExpandClause selectExpand = parser.ParseSelectAndExpand(); Expression source = Expression.Constant(customer); // Act Expression projection = _binder.ProjectAsWrapper(source, selectExpand, _model.Customer); // Assert Assert.Equal(ExpressionType.MemberInit, projection.NodeType); Assert.Empty((projection as MemberInitExpression).Bindings.Where(p => p.Member.Name == "Instance")); SelectExpandWrapper<Customer> customerWrapper = Expression.Lambda(projection).Compile().DynamicInvoke() as SelectExpandWrapper<Customer>; Assert.Null(customerWrapper.Instance); }
private void ParseUriAndVerify( Uri uri, Action<ODataPath, FilterClause, OrderByClause, SelectExpandClause, IDictionary<string, SingleValueNode>> verifyAction) { // run 2 test passes: // 1. low level api - ODataUriParser instance methods { List<CustomQueryOptionToken> queries = UriUtils.ParseQueryOptions(uri); ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://gobbledygook/"), uri); ODataPath path = parser.ParsePath(); IEdmNavigationSource entitySource = ResolveEntitySource(path); IEdmEntitySet entitySet = entitySource as IEdmEntitySet; var dic = queries.ToDictionary(customQueryOptionToken => customQueryOptionToken.Name, customQueryOptionToken => queries.GetQueryOptionValue(customQueryOptionToken.Name)); ODataQueryOptionParser queryOptionParser = new ODataQueryOptionParser(HardCodedTestModel.TestModel, entitySet.EntityType(), entitySet, dic) { Configuration = { ParameterAliasValueAccessor = parser.ParameterAliasValueAccessor } }; FilterClause filterClause = queryOptionParser.ParseFilter(); SelectExpandClause selectExpandClause = queryOptionParser.ParseSelectAndExpand(); OrderByClause orderByClause = queryOptionParser.ParseOrderBy(); // Two parser should share same ParameterAliasNodes verifyAction(path, filterClause, orderByClause, selectExpandClause, parser.ParameterAliasNodes); verifyAction(path, filterClause, orderByClause, selectExpandClause, queryOptionParser.ParameterAliasNodes); } //2. high level api - ParseUri { ODataUriParser parser = new ODataUriParser(HardCodedTestModel.TestModel, new Uri("http://gobbledygook/"), uri); verifyAction(parser.ParsePath(), parser.ParseFilter(), parser.ParseOrderBy(), parser.ParseSelectAndExpand(), parser.ParameterAliasNodes); } }