public void TryTranslateNavigationSegmentTemplate_ReturnsODataNavigationSegment()
        {
            // Arrange
            EdmEntityType          employee   = new EdmEntityType("NS", "Employee");
            IEdmNavigationProperty navigation = employee.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "DirectReports",
                Target             = employee,
                TargetMultiplicity = EdmMultiplicity.Many
            });

            NavigationLinkSegmentTemplate linkSegment = new NavigationLinkSegmentTemplate(navigation, null);
            ODataTemplateTranslateContext context     = new ODataTemplateTranslateContext();

            // Act
            bool ok = linkSegment.TryTranslate(context);

            // Assert
            Assert.True(ok);
            ODataPathSegment actual = Assert.Single(context.Segments);
            NavigationPropertyLinkSegment navLinkSegment = Assert.IsType <NavigationPropertyLinkSegment>(actual);

            Assert.Same(navigation, navLinkSegment.NavigationProperty);
            Assert.Null(navLinkSegment.NavigationSource);
        }
Exemplo n.º 2
0
        public void TryTranslateNavigationLinkSegmentTemplate_ThrowsArgumentNull_Context()
        {
            // Arrange
            NavigationLinkSegmentTemplate linkSegment = new NavigationLinkSegmentTemplate(_navigation, null);

            // Act & Assert
            ExceptionAssert.ThrowsArgumentNull(() => linkSegment.TryTranslate(null), "context");
        }
Exemplo n.º 3
0
        public void CtorNavigationLinkSegmentTemplate_SetsProperties()
        {
            // Arrange & Act
            NavigationLinkSegmentTemplate linkSegment = new NavigationLinkSegmentTemplate(_navigation, null);

            // Assert
            Assert.Null(linkSegment.Key);
            Assert.Same(_navigation, linkSegment.NavigationProperty);
            Assert.Null(linkSegment.NavigationSource);
            Assert.NotNull(linkSegment.Segment);
        }
Exemplo n.º 4
0
        public void TryTranslateNavigationLinkSegmentTemplate_ReturnsODataNavigationSegment()
        {
            // Arrange
            EdmModel model = new EdmModel();

            model.AddElement(_employee);

            NavigationLinkSegmentTemplate linkSegment          = new NavigationLinkSegmentTemplate(_navigation, null);
            RouteValueDictionary          routeValueDictionary = new RouteValueDictionary(new { id = "42" });
            ODataTemplateTranslateContext context = new ODataTemplateTranslateContext
            {
                RouteValues = routeValueDictionary,
                Model       = model
            };

            // Without key segment
            // Act & Assert
            bool ok = linkSegment.TryTranslate(context);

            Assert.True(ok);
            ODataPathSegment actual = Assert.Single(context.Segments);
            NavigationPropertyLinkSegment navLinkSegment = Assert.IsType <NavigationPropertyLinkSegment>(actual);

            Assert.Same(_navigation, navLinkSegment.NavigationProperty);
            Assert.Null(navLinkSegment.NavigationSource);

            // With Key segment
            // Act & Assert
            context = new ODataTemplateTranslateContext
            {
                RouteValues = routeValueDictionary,
                Model       = model
            };

            linkSegment.Key = KeySegmentTemplate.CreateKeySegment(_employee, null, "id");
            ok = linkSegment.TryTranslate(context);

            Assert.True(ok);
            Assert.Collection(context.Segments,
                              e =>
            {
                NavigationPropertyLinkSegment navLinkSegment = Assert.IsType <NavigationPropertyLinkSegment>(e);
                Assert.Same(_navigation, navLinkSegment.NavigationProperty);
                Assert.Null(navLinkSegment.NavigationSource);
            },
                              e =>
            {
                KeySegment keySegment             = Assert.IsType <KeySegment>(e);
                KeyValuePair <string, object> key = Assert.Single(keySegment.Keys);
                Assert.Equal("Id", key.Key);
                Assert.Equal(42, key.Value);
            });
        }
Exemplo n.º 5
0
        public void ParseODataUriTemplate_ForNavigationPropertyLink(string template, int count)
        {
            // Arrange
            IODataPathTemplateParser parser = new DefaultODataPathTemplateParser();

            // Act
            ODataPathTemplate path = parser.Parse(_edmModel, template, null);

            // Assert
            Assert.NotNull(path);
            Assert.Equal(count, path.Count);
            NavigationLinkSegmentTemplate navigationSegment = Assert.IsType <NavigationLinkSegmentTemplate>(path[count - 1]);

            Assert.Equal("Orders", navigationSegment.NavigationProperty.Name);
        }
Exemplo n.º 6
0
        public void GetTemplatesNavigationLinkSegmentTemplate_ReturnsTemplates()
        {
            // Arrange
            NavigationLinkSegmentTemplate linkSegment = new NavigationLinkSegmentTemplate(_navigation, null);

            // Act & Assert
            IEnumerable <string> templates = linkSegment.GetTemplates();
            string template = Assert.Single(templates);

            Assert.Equal("/DirectReports/$ref", template);

            // Act & Assert
            linkSegment.Key = KeySegmentTemplate.CreateKeySegment(_employee, null);
            templates       = linkSegment.GetTemplates();
            Assert.Collection(templates,
                              e => Assert.Equal("/DirectReports({key})/$ref", e),
                              e => Assert.Equal("/DirectReports/{key}/$ref", e));
        }
        public void CommonNavigationTemplateProperties_ReturnsAsExpected()
        {
            // Assert
            EdmEntityType          employee   = new EdmEntityType("NS", "Employee");
            IEdmNavigationProperty navigation = employee.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "DirectReports",
                Target             = employee,
                TargetMultiplicity = EdmMultiplicity.Many
            });

            NavigationLinkSegmentTemplate linkSegment = new NavigationLinkSegmentTemplate(navigation, null);

            // Act & Assert
            Assert.Equal("DirectReports", linkSegment.Literal);
            Assert.Equal(ODataSegmentKind.NavigationLink, linkSegment.Kind);
            Assert.False(linkSegment.IsSingle);
            Assert.Equal("Collection(NS.Employee)", linkSegment.EdmType.FullTypeName());
            Assert.Null(linkSegment.NavigationSource);
        }
Exemplo n.º 8
0
        public void ODataPathSegmentToTemplateHandler_Handles_Key_AfterNavigationProperty()
        {
            // Arrange
            ODataPathSegmentToTemplateHandler handler = new ODataPathSegmentToTemplateHandler(null);

            EdmEntityType customer = new EdmEntityType("NS", "Customer");

            customer.AddKeys(customer.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));

            EdmEntityType order = new EdmEntityType("NS", "order");

            order.AddKeys(order.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32));

            IEdmNavigationProperty ordersNavProperty = customer.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo
            {
                Name               = "Orders",
                Target             = order,
                TargetMultiplicity = EdmMultiplicity.Many
            });
            NavigationPropertyLinkSegment segment1 = new NavigationPropertyLinkSegment(ordersNavProperty, null);

            EdmEntityContainer           entityContainer = new EdmEntityContainer("NS", "Default");
            EdmEntitySet                 orders          = entityContainer.AddEntitySet("Orders", order);
            IDictionary <string, object> keys            = new Dictionary <string, object>
            {
                { "Id", "{relatedKey}" }
            };

            KeySegment segment2 = new KeySegment(keys, order, orders);

            // Act
            handler.Handle(segment1);
            handler.Handle(segment2);

            // Assert
            ODataSegmentTemplate          segmentTemplate = Assert.Single(handler.Templates);
            NavigationLinkSegmentTemplate nlTemplate      = Assert.IsType <NavigationLinkSegmentTemplate>(segmentTemplate);

            Assert.NotNull(nlTemplate.Key);
        }
Exemplo n.º 9
0
        /// <summary>
        /// Translate a KeySegment.
        /// </summary>
        /// <param name="segment">the segment to Translate</param>
        public override void Handle(KeySegment segment)
        {
            Func <KeySegmentTemplate> BuildKeyTemplate = () =>
            {
                try
                {
                    return(new KeySegmentTemplate(segment));
                }
                catch
                {
                    if (_model != null)
                    {
                        var alternateKeys = _model.ResolveAlternateKeyProperties(segment);
                        if (alternateKeys != null)
                        {
                            return(new KeySegmentTemplate(segment, alternateKeys));
                        }
                    }

                    throw;
                }
            };

            KeySegmentTemplate keyTemplate = BuildKeyTemplate();

            ODataSegmentTemplate          previous = _segmentTemplates.LastOrDefault();
            NavigationLinkSegmentTemplate preRef   = previous as NavigationLinkSegmentTemplate;

            if (preRef != null)
            {
                preRef.Key = keyTemplate;
            }
            else
            {
                _segmentTemplates.Add(keyTemplate);
            }
        }
Exemplo n.º 10
0
        /// <inheritdoc />
        public bool AppliesToAction(ODataControllerActionContext context)
        {
            if (context == null)
            {
                throw Error.ArgumentNull(nameof(context));
            }

            Debug.Assert(context.Action != null);

            ActionModel action           = context.Action;
            string      actionMethodName = action.ActionName;

            // Need to refactor the following
            // for example:  CreateRef( with the navigation property parameter) should for all navigation properties
            // CreateRefToOrdersFromCustomer, CreateRefToOrders, CreateRef.
            string method = SplitRefActionName(actionMethodName, out string httpMethod, out string property, out string declaring);

            if (method == null)
            {
                return(false);
            }

            IEdmNavigationSource navigationSource = context.NavigationSource;
            IEdmEntityType       entityType       = context.EntityType;

            // For entity set, we should have the key parameter
            // For Singleton, we should not have the key parameter
            bool hasODataKeyParameter = action.HasODataKeyParameter(entityType);

            if ((context.EntitySet != null && !hasODataKeyParameter) ||
                (context.Singleton != null && hasODataKeyParameter))
            {
                return(false);
            }

            // Find the navigation property declaring type
            IEdmStructuredType declaringType = entityType;

            if (declaring != null)
            {
                declaringType = entityType.FindTypeInInheritance(context.Model, declaring);
                if (declaringType == null)
                {
                    return(false);
                }
            }

            // Process the generic scenario
            if (property == null)
            {
                return(ProcessNonNavigationProperty(httpMethod, context, action, navigationSource, entityType, declaringType));
            }

            // Find the navigation property if have
            IEdmNavigationProperty navigationProperty = null;

            if (property != null)
            {
                navigationProperty = declaringType.DeclaredNavigationProperties().FirstOrDefault(p => p.Name == property);
            }

            if (navigationProperty == null)
            {
                return(false);
            }

            IList <ODataSegmentTemplate> segments = new List <ODataSegmentTemplate>();

            if (context.EntitySet != null)
            {
                segments.Add(new EntitySetSegmentTemplate(context.EntitySet));
                segments.Add(KeySegmentTemplate.CreateKeySegment(entityType, context.EntitySet));
            }
            else
            {
                segments.Add(new SingletonSegmentTemplate(context.Singleton));
            }

            if (entityType != declaringType)
            {
                segments.Add(new CastSegmentTemplate(declaringType, entityType, navigationSource));
            }

            IEdmNavigationSource          targetNavigationSource = navigationSource.FindNavigationTarget(navigationProperty, segments, out _);
            NavigationLinkSegmentTemplate linkTemplate           = new NavigationLinkSegmentTemplate(navigationProperty, targetNavigationSource);

            IEdmEntityType navigationPropertyType            = navigationProperty.Type.GetElementTypeOrSelf().AsEntity().EntityDefinition();
            bool           hasNavigationPropertyKeyParameter = action.HasODataKeyParameter(navigationPropertyType, "relatedKey");

            if (hasNavigationPropertyKeyParameter)
            {
                linkTemplate.Key = KeySegmentTemplate.CreateKeySegment(navigationPropertyType, targetNavigationSource, "relatedKey");
            }
            else
            {
                hasNavigationPropertyKeyParameter = action.HasODataKeyParameter(navigationPropertyType, "relatedId");
                if (hasNavigationPropertyKeyParameter)
                {
                    linkTemplate.Key = KeySegmentTemplate.CreateKeySegment(navigationPropertyType, targetNavigationSource, "relatedId");
                }
            }

            segments.Add(linkTemplate);

            ODataPathTemplate template = new ODataPathTemplate(segments);

            action.AddSelector(httpMethod, context.Prefix, context.Model, template, context.Options?.RouteOptions);

            // processed
            return(true);
        }