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, ""));
        }
Ejemplo n.º 2
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();
 }
Ejemplo n.º 4
0
        [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();
        }
Ejemplo n.º 10
0
        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"]);
        }
Ejemplo n.º 11
0
        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"]);
        }
Ejemplo n.º 12
0
        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);
            }
        }