public void WriteObjectInline_WritesCorrectIdLink()
        {
            // Arrange
            bool customIdLinkbuilderCalled = false;
            EntitySetLinkBuilderAnnotation linkAnnotation = new MockEntitySetLinkBuilderAnnotation
            {
                IdLinkBuilder = new SelfLinkBuilder<string>((EntityInstanceContext context) =>
                {
                    Assert.Equal(context.EdmModel, _model);
                    Assert.Equal(context.EntityInstance, _customer);
                    Assert.Equal(context.EntitySet, _customerSet);
                    Assert.Equal(context.EntityType, _customerSet.ElementType);
                    customIdLinkbuilderCalled = true;
                    return "http://sample_id_link";
                },
                followsConventions: false)
            };
            _model.SetEntitySetLinkBuilderAnnotation(_customerSet, linkAnnotation);

            Mock<ODataWriter> writer = new Mock<ODataWriter>();
            writer
                .Setup(w => w.WriteStart(It.IsAny<ODataEntry>()))
                .Callback((ODataEntry entry) =>
                {
                    Assert.Equal(entry.Id, "http://sample_id_link");
                });

            // Act
            _serializer.WriteObjectInline(_customer, writer.Object, _writeContext);

            // Assert
            Assert.True(customIdLinkbuilderCalled);
        }
        public static IEdmModel SimpleCustomerOrderModel()
        {
            var model = new EdmModel();
            var customerType = new EdmEntityType("Default", "Customer");
            customerType.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32);
            customerType.AddStructuralProperty("FirstName", EdmPrimitiveTypeKind.String);
            customerType.AddStructuralProperty("LastName", EdmPrimitiveTypeKind.String);
            IEdmTypeReference primitiveTypeReference = EdmCoreModel.Instance
                .GetPrimitive(EdmPrimitiveTypeKind.String, isNullable: true);
            customerType.AddStructuralProperty("City", primitiveTypeReference, defaultValue: null,
                concurrencyMode: EdmConcurrencyMode.Fixed);
            model.AddElement(customerType);

            var orderType = new EdmEntityType("Default", "Order");
            orderType.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32);
            orderType.AddStructuralProperty("Name", EdmPrimitiveTypeKind.String);
            orderType.AddStructuralProperty("Shipment", EdmPrimitiveTypeKind.String);
            model.AddElement(orderType);

            var addressType = new EdmComplexType("Default", "Address");
            addressType.AddStructuralProperty("Street", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("City", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("State", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("Country", EdmPrimitiveTypeKind.String);
            addressType.AddStructuralProperty("ZipCode", EdmPrimitiveTypeKind.String);
            model.AddElement(addressType);

            // Add navigations
            customerType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name = "Orders",
                Target = orderType,
                TargetMultiplicity = EdmMultiplicity.Many
            });
            orderType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo()
            {
                Name = "Customer",
                Target = customerType,
                TargetMultiplicity = EdmMultiplicity.One
            });

            var container = new EdmEntityContainer("Default", "Container");
            var customerSet = container.AddEntitySet("Customers", customerType);
            var orderSet = container.AddEntitySet("Orders", orderType);
            customerSet.AddNavigationTarget(customerType.NavigationProperties().Single(np => np.Name == "Orders"), orderSet);
            orderSet.AddNavigationTarget(orderType.NavigationProperties().Single(np => np.Name == "Customer"), customerSet);

            EntitySetLinkBuilderAnnotation linkAnnotation = new MockEntitySetLinkBuilderAnnotation();
            model.SetEntitySetLinkBuilder(customerSet, linkAnnotation);
            model.SetEntitySetLinkBuilder(orderSet, linkAnnotation);

            model.AddElement(container);
            return model;
        }
        public void CreateODataFeed_Sets_FeedSelfLink()
        {
            // Arrange
            var feedInstance = new object[0];
            ODataSerializerContext writeContext = new ODataSerializerContext { EntitySet = _customerSet, Model = _model, Request = new HttpRequestMessage() };
            writeContext.Url = new UrlHelper(writeContext.Request);
            ODataFeedSerializer serializer = new ODataFeedSerializer(new DefaultODataSerializerProvider());
            Uri feedSelfLink = new Uri("http://feed_self_link/");
            EntitySetLinkBuilderAnnotation linkBuilder = new MockEntitySetLinkBuilderAnnotation
            {
                FeedSelfLinkBuilder = (context) =>
                    {
                        Assert.Equal(_customerSet, context.EntitySet);
                        Assert.Equal(feedInstance, context.FeedInstance);
                        Assert.Equal(writeContext.Request, context.Request);
                        Assert.Equal(writeContext.Url, context.Url);
                        return feedSelfLink;
                    }
            };
            _model.SetEntitySetLinkBuilder(_customerSet, linkBuilder);

            // Act
            ODataFeed feed = serializer.CreateODataFeed(feedInstance, _customersType, writeContext);

            // Assert
            AtomFeedMetadata feedMetadata = feed.GetAnnotation<AtomFeedMetadata>();
            Assert.Equal(feedSelfLink, feedMetadata.SelfLink.Href);
            Assert.Equal("self", feedMetadata.SelfLink.Relation);
        }
        public void WriteObjectInline_WritesCorrectReadLink()
        {
            // Arrange
            EntityInstanceContext instanceContext = new EntityInstanceContext { SerializerContext = _writeContext };
            bool customReadLinkbuilderCalled = false;
            EntitySetLinkBuilderAnnotation linkAnnotation = new MockEntitySetLinkBuilderAnnotation
            {
                ReadLinkBuilder = new SelfLinkBuilder<Uri>((EntityInstanceContext context) =>
                {
                    Assert.Same(instanceContext, context);
                    customReadLinkbuilderCalled = true;
                    return new Uri("http://sample_read_link");
                },
                followsConventions: false)
            };

            _model.SetEntitySetLinkBuilder(_customerSet, linkAnnotation);

            Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(_serializer.EdmType, _serializerProvider);
            serializer.CallBase = true;
            SelectExpandNode selectExpandNode = new SelectExpandNode();

            // Act
            ODataEntry entry = serializer.Object.CreateEntry(selectExpandNode, instanceContext);

            // Assert
            Assert.True(customReadLinkbuilderCalled);
        }
        public void CreateNavigationLink_CreatesCorrectNavigationLink()
        {
            // Arrange
            Uri navigationLinkUri = new Uri("http://navigation_link");
            IEdmNavigationProperty property1 = CreateFakeNavigationProperty("Property1", _serializer.EntityType);
            EntitySetLinkBuilderAnnotation linkAnnotation = new MockEntitySetLinkBuilderAnnotation
            {
                NavigationLinkBuilder = (ctxt, property, metadataLevel) => navigationLinkUri
            };
            _model.SetEntitySetLinkBuilder(_customerSet, linkAnnotation);

            Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(_serializer.EdmType, _serializerProvider);
            serializer.CallBase = true;

            // Act
            ODataNavigationLink navigationLink = serializer.Object.CreateNavigationLink(property1, _entityInstanceContext);

            // Assert
            Assert.Equal("Property1", navigationLink.Name);
            Assert.Equal(navigationLinkUri, navigationLink.Url);
        }
        public void WriteObjectInline_WritesCorrectReadLink()
        {
            // Arrange
            EntityInstanceContext instanceContext = new EntityInstanceContext();
            bool customReadLinkbuilderCalled = false;
            EntitySetLinkBuilderAnnotation linkAnnotation = new MockEntitySetLinkBuilderAnnotation
            {
                ReadLinkBuilder = new SelfLinkBuilder<Uri>((EntityInstanceContext context) =>
                {
                    Assert.Same(instanceContext, context);
                    customReadLinkbuilderCalled = true;
                    return new Uri("http://sample_read_link");
                },
                followsConventions: false)
            };

            _model.SetEntitySetLinkBuilderAnnotation(_customerSet, linkAnnotation);

            Mock<ODataEntityTypeSerializer> serializer = new Mock<ODataEntityTypeSerializer>(_serializer.EdmType, new DefaultODataSerializerProvider());
            serializer.Setup(s => s.CreateStructuralPropertyBag(instanceContext, _writeContext)).Returns(Enumerable.Empty<ODataProperty>());
            serializer.Setup(s => s.CreateODataActions(instanceContext, _writeContext)).Returns(Enumerable.Empty<ODataAction>());
            serializer.CallBase = true;

            // Act
            ODataEntry entry = serializer.Object.CreateEntry(instanceContext, _writeContext);

            // Assert
            Assert.True(customReadLinkbuilderCalled);
        }
        public void CreateNavigationLinks_Returns_NavigationLinkForEachNaviagationProperty()
        {
            // Arrange
            IEdmNavigationProperty property1 = CreateFakeNavigationProperty("Property1", _serializer.EntityType);
            IEdmNavigationProperty property2 = CreateFakeNavigationProperty("Property2", _serializer.EntityType);
            Mock<IEdmEntityType> entityType = new Mock<IEdmEntityType>();
            entityType.Setup(e => e.DeclaredProperties).Returns(new[] { property1, property2 });

            var serializer = new ODataEntityTypeSerializer(new EdmEntityTypeReference(entityType.Object, isNullable: false), new DefaultODataSerializerProvider());

            MockEntitySetLinkBuilderAnnotation linkBuilder = new MockEntitySetLinkBuilderAnnotation
            {
                NavigationLinkBuilder = (ctxt, property, metadataLevel) => new Uri(property.Name, UriKind.Relative)
            };
            _model.SetEntitySetLinkBuilderAnnotation(_customerSet, linkBuilder);

            // Act
            IEnumerable<ODataNavigationLink> links = serializer.CreateNavigationLinks(new EntityInstanceContext(), _writeContext);

            // Assert
            Assert.Equal(new[] { "Property1", "Property2" }, links.Select(l => l.Name));
            Assert.Equal(new[] { "Property1", "Property2" }, links.Select(l => l.Url.ToString()));
            Assert.Equal(new bool?[] { false, false }, links.Select(l => l.IsCollection));
        }