[InlineData("GET", "http://localhost/Customers(12)/NS.SpecialCustomer/NS.GetSalary()", "GetSalaryFromSpecialCustomer_12")] // call function on derived entity type
        public async Task AttriubteRouting_SelectsExpectedControllerAndAction(string method, string requestUri,
            string expectedResult)
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();

            var controllers = new[] { typeof(CustomersController), typeof(MetadataAndServiceController), typeof(OrdersController) };
            TestAssemblyResolver resolver = new TestAssemblyResolver(new MockAssembly(controllers));

            HttpConfiguration config = new HttpConfiguration();
            config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
            config.Services.Replace(typeof(IAssembliesResolver), resolver);

            config.MapODataServiceRoute("odata", "", model.Model);

            HttpServer server = new HttpServer(config);
            config.EnsureInitialized();

            HttpClient client = new HttpClient(server);
            HttpRequestMessage request = new HttpRequestMessage(new HttpMethod(method), requestUri);

            // Act
            var response = await client.SendAsync(request);

            // Assert
            if (!response.IsSuccessStatusCode)
            {
                Assert.False(true, await response.Content.ReadAsStringAsync());
            }
            var result = await response.Content.ReadAsAsync<AttributeRoutingTestODataResponse>();
            Assert.Equal(expectedResult, result.Value);
        }
        public void SelectAction_OnEntitySetPath_Returns_ExpectedMethodOnBaseType(string method, string[] methodsInController,
            string expectedSelectedAction)
        {
            // Arrange
            const string key = "42";
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            var ordersProperty = model.Customer.FindProperty("Orders") as IEdmNavigationProperty;
            ODataPath odataPath = new ODataPath(new EntitySetPathSegment(model.Customers), new KeyValuePathSegment(key),
                new NavigationPathSegment(ordersProperty));
            HttpControllerContext controllerContext = CreateControllerContext(method);
            var actionMap = GetMockActionMap(methodsInController);

            // Act
            string selectedAction = new NavigationRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.Equal(expectedSelectedAction, selectedAction);
            if (expectedSelectedAction == null)
            {
                Assert.Empty(controllerContext.RouteData.Values);
            }
            else
            {
                Assert.Equal(1, controllerContext.RouteData.Values.Count);
                Assert.Equal(key, controllerContext.RouteData.Values["key"]);
            }
        }
        public void Ctor_ThatBuildsNestedContext_CopiesProperties()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataSerializerContext context = new ODataSerializerContext
            {
                NavigationSource = model.Customers,
                MetadataLevel = ODataMetadataLevel.FullMetadata,
                Model = model.Model,
                Path = new ODataPath(),
                Request = new HttpRequestMessage(),
                RootElementName = "somename",
                SelectExpandClause = new SelectExpandClause(new SelectItem[0], allSelected: true),
                SkipExpensiveAvailabilityChecks = true,
                Url = new UrlHelper()
            };
            EntityInstanceContext entity = new EntityInstanceContext { SerializerContext = context };
            SelectExpandClause selectExpand = new SelectExpandClause(new SelectItem[0], allSelected: true);
            IEdmNavigationProperty navProp = model.Customer.NavigationProperties().First();

            // Act
            ODataSerializerContext nestedContext = new ODataSerializerContext(entity, selectExpand, navProp);

            // Assert
            Assert.Equal(context.MetadataLevel, nestedContext.MetadataLevel);
            Assert.Same(context.Model, nestedContext.Model);
            Assert.Same(context.Path, nestedContext.Path);
            Assert.Same(context.Request, nestedContext.Request);
            Assert.Equal(context.RootElementName, nestedContext.RootElementName);
            Assert.Equal(context.SkipExpensiveAvailabilityChecks, nestedContext.SkipExpensiveAvailabilityChecks);
            Assert.Same(context.Url, nestedContext.Url);
        }
        public async Task AttributeRouting_QueryProperty_AfterCallBoundFunction()
        {
            // Arrange
            const string RequestUri = @"http://localhost/Customers(12)/NS.GetOrder(orderId=4)/Amount";
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();

            HttpConfiguration config = new[] { typeof(CustomersController) }.GetHttpConfiguration();
            config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;
            config.MapODataServiceRoute("odata", "", model.Model);

            HttpServer server = new HttpServer(config);
            config.EnsureInitialized();

            HttpClient client = new HttpClient(server);
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, RequestUri);

            // Act
            HttpResponseMessage response = await client.SendAsync(request);
            string responseString = await response.Content.ReadAsStringAsync();

            // Assert
            Assert.True(response.IsSuccessStatusCode);
            Assert.Equal("{\r\n  \"@odata.context\":\"http://localhost/$metadata#Edm.Int32\",\"value\":56\r\n}",
                responseString);
        }
Exemplo n.º 5
0
        public ODataSwaggerUtilitiesTest()
        {
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            _customer = model.Customer;
            _customers = model.Customers;

            IEdmAction action = new EdmAction("NS", "GetCustomers", null, false, null);
            _getCustomers = new EdmActionImport(model.Container, "GetCustomers", action);

            _isAnyUpgraded = model.Model.SchemaElements.OfType<IEdmFunction>().FirstOrDefault(e => e.Name == "IsAnyUpgraded");
            _isCustomerUpgradedWithParam = model.Model.SchemaElements.OfType<IEdmFunction>().FirstOrDefault(e => e.Name == "IsUpgradedWithParam");
        }
Exemplo n.º 6
0
        public void ApplyTo_OnSingleEntity_WithUnTypedContext_Throws_InvalidOperation()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer);
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption(select: "ID", expand: null, context: context);
            object entity = new object();

            // Act & Assert
            Assert.Throws<NotSupportedException>(() => selectExpand.ApplyTo(entity, new ODataQuerySettings()),
                "The query option is not bound to any CLR type. 'ApplyTo' is only supported with a query option bound to a CLR type.");
        }
        public void SelectController_RetrunsSingletonName_ForSingletonRequest()
        {
            // Arrange
            Mock<HttpRequestMessage> request = new Mock<HttpRequestMessage>();
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataPath odataPath = new DefaultODataPathHandler().Parse(model.Model, "http://any/", "VipCustomer");

            // Act
            string controller = new MockNavigationSourceRoutingConvention().SelectController(odataPath, request.Object);

            // Assert
            Assert.Equal("VipCustomer", controller);
        }
        public void ValidateThrowException_IfNotNavigable()
        {
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer)));
            ODataQueryContext queryContext = new ODataQueryContext(model.Model, typeof(Customer));
            model.Model.SetAnnotationValue(model.Customer.FindProperty("Orders"), new QueryableRestrictionsAnnotation(new QueryableRestrictions{NotNavigable=true}));

            string select = "Orders";
            SelectExpandQueryValidator validator = new SelectExpandQueryValidator();
            SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(select, null, queryContext);
            Assert.Throws<ODataException>(
                () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()),
                "The property 'Orders' cannot be used for navigation.");
        }
        public void ValidateThrowException_IfBaseOrDerivedClassPropertyNotNavigable(string className, string propertyName)
        {
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            model.Model.SetAnnotationValue(model.SpecialCustomer, new ClrTypeAnnotation(typeof(Customer)));
            ODataQueryContext queryContext = new ODataQueryContext(model.Model, typeof(Customer));
            EdmEntityType classType = (className == "Customer") ? model.Customer : model.SpecialCustomer;
            model.Model.SetAnnotationValue(classType.FindProperty(propertyName), new QueryableRestrictionsAnnotation(new QueryableRestrictions { NotNavigable = true }));

            string select = "NS.SpecialCustomer/" + propertyName;
            SelectExpandQueryValidator validator = new SelectExpandQueryValidator();
            SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(select, null, queryContext);
            Assert.Throws<ODataException>(
                () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()),
                String.Format(CultureInfo.InvariantCulture, "The property '{0}' cannot be used for navigation.", propertyName));
        }
Exemplo n.º 10
0
        public SelectExpandBinderTest()
        {
            _settings = new ODataQuerySettings { HandleNullPropagation = HandleNullPropagationOption.False };
            _model = new CustomersModelWithInheritance();
            _model.Model.SetAnnotationValue<ClrTypeAnnotation>(_model.Customer, new ClrTypeAnnotation(typeof(Customer)));
            _model.Model.SetAnnotationValue<ClrTypeAnnotation>(_model.SpecialCustomer, new ClrTypeAnnotation(typeof(SpecialCustomer)));
            _context = new ODataQueryContext(_model.Model, typeof(Customer));
            _binder = new SelectExpandBinder(_settings, new DefaultAssembliesResolver(), new SelectExpandQueryOption("*", "", _context));

            Customer customer = new Customer();
            Order order = new Order { Customer = customer };
            customer.Orders.Add(order);

            _queryable = new[] { customer }.AsQueryable();
        }
Exemplo n.º 11
0
        public void Ctor_TakingOrderByClause_InitializesProperty_Property()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            IEdmProperty property = model.Customer.FindProperty("ID");
            EntityRangeVariable variable = new EntityRangeVariable("it", model.Customer.AsReference(), model.Customers);
            SingleValuePropertyAccessNode node = new SingleValuePropertyAccessNode(new EntityRangeVariableReferenceNode("it", variable), property);
            OrderByClause orderBy = new OrderByClause(thenBy: null, expression: node, direction: OrderByDirection.Ascending, rangeVariable: variable);

            // Act
            OrderByPropertyNode orderByNode = new OrderByPropertyNode(orderBy);

            // Assert
            Assert.Equal(property, orderByNode.Property);
        }
        public void SelectAction_ReturnsNull_ForInvalidHttpMethods(string httpMethod)
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataPath odataPath = new DefaultODataPathHandler().Parse(model.Model, "VipCustomer");
            ILookup<string, HttpActionDescriptor> actionMap = new HttpActionDescriptor[0].ToLookup(desc => (string)null);
            HttpControllerContext controllerContext = new HttpControllerContext();
            controllerContext.Request = new HttpRequestMessage(new HttpMethod(httpMethod), "http://localhost/");
            controllerContext.Request.SetRouteData(new HttpRouteData(new HttpRoute()));

            // Act
            string actionName = new SingletonRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Act & Assert
            Assert.Null(actionName);
        }
Exemplo n.º 13
0
        public void GenerateODataLink_ThrowsIdLinkNullForEntityIdHeader_IfEntitySetLinkBuilderReturnsNull()
        {
            // Arrange
            var linkBuilder = new Mock<NavigationSourceLinkBuilderAnnotation>();
            var model = new CustomersModelWithInheritance();
            model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(TestEntity)));
            model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object);
            var path = new ODataPath(new EntitySetPathSegment(model.Customers));
            var request = new HttpRequestMessage();
            request.ODataProperties().Model = model.Model;
            request.ODataProperties().Path = path;

            // Act & Assert
            Assert.Throws<InvalidOperationException>(
                () => ResultHelpers.GenerateODataLink(request, _entity, isEntityId: true),
                "The Id link builder for the entity set 'Customers' returned null. An Id link is required for the OData-EntityId header.");
        }
        public void SelectAction_OnSingletonPath_Returns_ExpectedMethodOnBaseType(string method, string[] methodsInController,
            string expectedSelectedAction)
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            var ordersProperty = model.Customer.FindProperty("Orders") as IEdmNavigationProperty;
            ODataPath odataPath = new ODataPath(new SingletonPathSegment(model.VipCustomer),
                new NavigationPathSegment(ordersProperty));
            HttpControllerContext controllerContext = CreateControllerContext(method);
            var actionMap = GetMockActionMap(methodsInController);

            // Act
            string selectedAction = new NavigationRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.Equal(expectedSelectedAction, selectedAction);
            Assert.Empty(controllerContext.RouteData.Values);
        }
        public void Ctor_ThatBuildsNestedContext_InitializesRightValues()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            SelectExpandClause selectExpand = new SelectExpandClause(new SelectItem[0], allSelected: true);
            IEdmNavigationProperty navProp = model.Customer.NavigationProperties().First();
            ODataSerializerContext context = new ODataSerializerContext { NavigationSource = model.Customers, Model = model.Model };
            EntityInstanceContext entity = new EntityInstanceContext { SerializerContext = context };

            // Act
            ODataSerializerContext nestedContext = new ODataSerializerContext(entity, selectExpand, navProp);

            // Assert
            Assert.Same(entity, nestedContext.ExpandedEntity);
            Assert.Same(navProp, nestedContext.NavigationProperty);
            Assert.Same(selectExpand, nestedContext.SelectExpandClause);
            Assert.Same(model.Orders, nestedContext.NavigationSource);
        }
        public void SelectAction_ReturnsExpectedActionName_DollarCount(string method, string expected)
        {
            // Arrange
            var model = new CustomersModelWithInheritance();
            var odataPath = new ODataPath(new EntitySetPathSegment(model.Customers), new CountPathSegment());

            HttpControllerContext controllerContext = new HttpControllerContext()
            {
                Request = new HttpRequestMessage(new HttpMethod(method), "http://localhost/"),
                RouteData = new HttpRouteData(new HttpRoute())
            };

            ILookup<string, HttpActionDescriptor> actionMap = new HttpActionDescriptor[1].ToLookup(desc => expected);

            // Act
            string actionName = new EntitySetRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.Equal(expected, actionName);
        }
        public void SelectAction_ReturnsTheActionName_ForValidHttpMethods(string httpMethod, string httpMethodNamePrefix)
        {
            // Arrange
            const string SingletonName = "VipCustomer";
            string actionName = httpMethodNamePrefix + SingletonName;
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataPath odataPath = new DefaultODataPathHandler().Parse(model.Model, _serviceRoot, SingletonName);
            ILookup<string, HttpActionDescriptor> actionMap = new HttpActionDescriptor[1].ToLookup(desc => actionName);
            HttpControllerContext controllerContext = new HttpControllerContext();
            controllerContext.Request = new HttpRequestMessage(new HttpMethod(httpMethod), "http://localhost/");
            controllerContext.Request.SetRouteData(new HttpRouteData(new HttpRoute()));

            // Act
            string selectedAction = new SingletonRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.NotNull(selectedAction);
            Assert.Equal(actionName, selectedAction);
            Assert.Empty(controllerContext.Request.GetRouteData().Values);
        }
        public void SelectAction_ReturnsNull_IfActionIsMissing()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataPath odataPath = new DefaultODataPathHandler().Parse(model.Model, "http://localhost/", "Customers(10)/Account/Tax");
            ILookup<string, HttpActionDescriptor> emptyActionMap = new HttpActionDescriptor[0].ToLookup(desc => (string)null);
            HttpRequestContext requestContext = new HttpRequestContext();
            HttpControllerContext controllerContext = new HttpControllerContext
            {
                Request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/"),
                RequestContext = requestContext,
                RouteData = new HttpRouteData(new HttpRoute())
            };
            controllerContext.Request.SetRequestContext(requestContext);

            // Act
            string selectedAction = _routingConvention.SelectAction(odataPath, controllerContext, emptyActionMap);

            // Assert
            Assert.Null(selectedAction);
            Assert.Empty(controllerContext.Request.GetRouteData().Values);
        }
        public void SelectAction_OnSingletonPath_ReturnsTheActionName()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataPath odataPath = new DefaultODataPathHandler().Parse(model.Model, "VipCustomer/Address");
            ILookup<string, HttpActionDescriptor> actionMap = new HttpActionDescriptor[1].ToLookup(desc => "GetAddress");
            HttpRequestContext requestContext = new HttpRequestContext();
            HttpControllerContext controllerContext = new HttpControllerContext
            {
                Request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/"),
                RequestContext = requestContext,
                RouteData = new HttpRouteData(new HttpRoute())
            };
            controllerContext.Request.SetRequestContext(requestContext);

            // Act
            string selectedAction = new PropertyRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.NotNull(selectedAction);
            Assert.Equal("GetAddress", selectedAction);
            Assert.Empty(controllerContext.Request.GetRouteData().Values);
        }
        public void SelectAction_OnEntitySetPath_ReturnsTheActionName(string httpMethod, string prefix)
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataPath odataPath = new DefaultODataPathHandler().Parse(model.Model, _serviceRoot, "Customers(7)/Name");
            ILookup<string, HttpActionDescriptor> actionMap = new HttpActionDescriptor[1].ToLookup(desc => prefix + "NameFromCustomer");
            HttpRequestContext requestContext = new HttpRequestContext();
            HttpControllerContext controllerContext = new HttpControllerContext
            {
                Request = new HttpRequestMessage(new HttpMethod(httpMethod), "http://localhost/"),
                RequestContext = requestContext,
                RouteData = new HttpRouteData(new HttpRoute())
            };
            controllerContext.Request.SetRequestContext(requestContext);

            // Act
            string selectedAction = new PropertyRoutingConvention().SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.NotNull(selectedAction);
            Assert.Equal(prefix + "NameFromCustomer", selectedAction);
            Assert.Equal(1, controllerContext.Request.GetRouteData().Values.Count);
            Assert.Equal("7", controllerContext.Request.GetRouteData().Values["key"]);
        }
        public void SelectAction_ReturnsFunctionName_ForFunctionOnEntity()
        {
            // Arrange
            FunctionRoutingConvention functionConvention = new FunctionRoutingConvention();
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataPath odataPath = new DefaultODataPathHandler().Parse(model.Model, "Customers(1)/NS.IsUpgraded");
            HttpRequestContext requestContext = new HttpRequestContext();
            HttpControllerContext controllerContext = new HttpControllerContext
                {
                    Request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/"),
                    RequestContext = requestContext,
                    RouteData = new HttpRouteData(new HttpRoute())
                };
            controllerContext.Request.SetRequestContext(requestContext);
            ILookup<string, HttpActionDescriptor> actionMap = new HttpActionDescriptor[1].ToLookup(desc => "IsUpgraded");

            // Act
            string function = functionConvention.SelectAction(odataPath, controllerContext, actionMap);

            // Assert
            Assert.Equal("IsUpgraded", function);
            Assert.Equal(1, controllerContext.Request.GetRouteData().Values.Count);
            Assert.Equal("1", controllerContext.Request.GetRouteData().Values["key"]);
        }
        public void CreateODataFeed_SetsNextPageLink_WhenWritingTruncatedCollection_ForExpandedProperties()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            IEdmCollectionTypeReference customersType = new EdmCollectionTypeReference(new EdmCollectionType(model.Customer.AsReference()));
            ODataFeedSerializer serializer = new ODataFeedSerializer(new DefaultODataSerializerProvider());
            SelectExpandClause selectExpandClause = new SelectExpandClause(new SelectItem[0], allSelected: true);
            IEdmNavigationProperty ordersProperty = model.Customer.NavigationProperties().First();
            EntityInstanceContext entity = new EntityInstanceContext
            {
                SerializerContext = new ODataSerializerContext { NavigationSource = model.Customers, Model = model.Model }
            };
            ODataSerializerContext nestedContext = new ODataSerializerContext(entity, selectExpandClause, ordersProperty);
            TruncatedCollection<Order> orders = new TruncatedCollection<Order>(new[] { new Order(), new Order() }, pageSize: 1);

            Mock<NavigationSourceLinkBuilderAnnotation> linkBuilder = new Mock<NavigationSourceLinkBuilderAnnotation>();
            linkBuilder.Setup(l => l.BuildNavigationLink(entity, ordersProperty, ODataMetadataLevel.Default)).Returns(new Uri("http://navigation-link/"));
            model.Model.SetNavigationSourceLinkBuilder(model.Customers, linkBuilder.Object);
            model.Model.SetNavigationSourceLinkBuilder(model.Orders, new NavigationSourceLinkBuilderAnnotation());

            // Act
            ODataFeed feed = serializer.CreateODataFeed(orders, _customersType, nestedContext);

            // Assert
            Assert.Equal("http://navigation-link/?$skip=1", feed.NextPageLink.AbsoluteUri);
        }
        private static EdmFunction AddFunction(CustomersModelWithInheritance model, string name,
            IEdmTypeReference returnType = null, IEdmEntitySet entitySet = null, IEdmTypeReference bindingParameterType = null)
        {
            returnType = returnType ?? EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            IEdmExpression expression = entitySet == null ? null : new EdmEntitySetReferenceExpression(entitySet);

            var function = new EdmFunction(
                model.Container.Namespace,
                name,
                returnType,
                isBound: bindingParameterType != null,
                entitySetPathExpression: null,
                isComposable: true);
            if (bindingParameterType != null)
            {
                function.AddParameter("bindingParameter", bindingParameterType);
                model.Model.AddElement(function);
            }
            else
            {
                model.Container.AddFunctionImport(name, function, expression);
            }

            return function;
        }
        [Fact] // Issue 984: Redundant type name serialization in OData JSON light minimal metadata mode
        public void AddTypeNameAnnotationAsNeeded_AddsAnnotationWithNullValue_IfTypeOfPathMatchesEntryType()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataEntry entry = new ODataEntry
            {
                TypeName = model.SpecialCustomer.FullName()
            };

            // Act
            ODataEntityTypeSerializer.AddTypeNameAnnotationAsNeeded(entry, model.SpecialCustomer, ODataMetadataLevel.MinimalMetadata);

            // Assert
            SerializationTypeNameAnnotation annotation = entry.GetAnnotation<SerializationTypeNameAnnotation>();
            Assert.NotNull(annotation); // Guard
            Assert.Null(annotation.TypeName);
        }
        private static IEdmModel GetModelWithFunctions()
        {
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            var container = model.Container;
            IEdmTypeReference boolType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            IEdmTypeReference customerType = model.Customer.AsReference();
            IEdmTypeReference addressType = new EdmComplexTypeReference(model.Address, isNullable: false);
            IEdmTypeReference customersType = new EdmCollectionTypeReference(new EdmCollectionType(customerType));

            AddFunction(model, "unBoundWithoutParams");

            var unBoundWithOneParam = AddFunction(model, "unBoundWithOneParam");
            unBoundWithOneParam.AddParameter("Param", boolType);

            var unBoundWithMultipleParams = AddFunction(model, "unBoundWithMultipleParams");
            unBoundWithMultipleParams.AddParameter("Param1", boolType);
            unBoundWithMultipleParams.AddParameter("Param2", boolType);
            unBoundWithMultipleParams.AddParameter("Param3", boolType);

            AddFunction(model, "BoundToEntityNoParams", bindingParameterType: customerType);

            var boundToEntity = AddFunction(model, "BoundToEntity", bindingParameterType: customerType);
            boundToEntity.AddParameter("Param", boolType);

            AddFunction(model, "BoundToEntityReturnsEntityNoParams",
                returnType: customerType, entitySet: model.Customers, bindingParameterType: customerType);

            AddFunction(model, "BoundToEntityReturnsEntityCollectionNoParams",
                returnType: customersType, entitySet: model.Customers, bindingParameterType: customerType);

            AddFunction(model, "BoundToEntityCollection", bindingParameterType: customersType);

            AddFunction(model, "BoundToEntityCollectionReturnsComplex", bindingParameterType: customersType, returnType: addressType);

            return model.Model;
        }
        public void CanParse_FunctionParameters_CanResolveAliasedParameterValue()
        {
            // Arrange
            var model = new CustomersModelWithInheritance();
            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            var function = new EdmFunction(
                model.Container.Namespace,
                "FunctionAtRoot",
                returnType,
                isBound: false,
                entitySetPathExpression: null,
                isComposable: true);
            function.AddParameter("IntParameter", EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Int32, isNullable: false));
            model.Container.AddFunctionImport("FunctionAtRoot", function, entitySet: null);

            // Act
            ODataPath path = _parser.Parse(model.Model, "FunctionAtRoot(IntParameter=@p1)");
            UnboundFunctionPathSegment functionSegment = (UnboundFunctionPathSegment)path.Segments.Last();

            // Assert
            UnresolvedParameterValue unresolvedParamValue = functionSegment.GetParameterValue("IntParameter") as UnresolvedParameterValue;
            int intParameter = (int)unresolvedParamValue.Resolve(new Uri("http://services.odata.org/FunctionAtRoot(IntParameter=@p1)?@p1=1"));
            Assert.Equal(1, intParameter);
        }
        public void CanParse_BoundFunction_AtEntityCollection()
        {
            // Arrange
            var model = new CustomersModelWithInheritance();
            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            IEdmExpression entitySet = new EdmEntitySetReferenceExpression(model.Customers);
            var function = new EdmFunction(
                model.Container.Namespace,
                "Count",
                returnType,
                isBound: true,
                entitySetPathExpression: null,
                isComposable: true);
            IEdmTypeReference bindingParameterType = new EdmCollectionTypeReference(
                new EdmCollectionType(new EdmEntityTypeReference(model.Customer, isNullable: false)));
            function.AddParameter("customers", bindingParameterType);
            model.Model.AddElement(function);

            // Act
            ODataPath path = _parser.Parse(model.Model, "Customers/NS.Count");

            // Assert
            Assert.NotNull(path);
            Assert.Equal(2, path.Segments.Count);
            var functionSegment = Assert.IsType<BoundFunctionPathSegment>(path.Segments.Last());
            Assert.Same(function, functionSegment.Function);
            Assert.Empty(functionSegment.Values);
        }
        public void CanParse_UnboundFunction_AtRoot()
        {
            // Arrange
            var model = new CustomersModelWithInheritance();
            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);
            var function = model.Container.AddFunctionImport(
                new EdmFunction(
                    model.Container.Namespace,
                    "FunctionAtRoot",
                    returnType,
                    isBound: false,
                    entitySetPathExpression: null,
                    isComposable: true));

            // Act
            ODataPath path = _parser.Parse(model.Model, "FunctionAtRoot");

            // Assert
            Assert.NotNull(path);
            Assert.Equal(1, path.Segments.Count);
            var functionSegment = Assert.IsType<UnboundFunctionPathSegment>(path.Segments.First());
            Assert.Same(function, functionSegment.Function);
            Assert.Empty(functionSegment.Values);
        }
        public void Property_SelectExpandClause_WorksWithUnTypedContext()
        {
            // Arrange
            CustomersModelWithInheritance model = new CustomersModelWithInheritance();
            ODataQueryContext context = new ODataQueryContext(model.Model, model.Customer);
            SelectExpandQueryOption selectExpand = new SelectExpandQueryOption(select: "ID", expand: null, context: context);

            // Act & Assert
            Assert.NotNull(selectExpand.SelectExpandClause);
        }
        public void CannotParseQualifiedUnboundOperation(string odataPath)
        {
            // Arrange
            var model = new CustomersModelWithInheritance();
            IEdmTypeReference returnType = EdmCoreModel.Instance.GetPrimitive(EdmPrimitiveTypeKind.Boolean, isNullable: false);

            model.Container.AddFunctionImport(new EdmFunction(model.Container.Namespace, "FunctionAtRoot",
                    returnType, isBound: false, entitySetPathExpression: null, isComposable: true));

            model.Container.AddActionImport(new EdmAction(model.Container.Namespace, "ActionAtRoot", returnType));

            // Act
            ODataPath path = _parser.Parse(model.Model, odataPath);

            // Assert
            Assert.Null(path);
        }