Beispiel #1
0
        public void DollarMetadata_Works_WithDerivedEntityTypeWithOwnKeys()
        {
            // Arrange
            const string expectMetadata =
                "    <Schema Namespace=\"System.Web.OData.Formatter\" xmlns=\"http://docs.oasis-open.org/odata/ns/edm\">\r\n" +
                "      <EntityType Name=\"AbstractEntityType\" Abstract=\"true\">\r\n" +
                "        <Property Name=\"IntProperty\" Type=\"Edm.Int32\" Nullable=\"false\" />\r\n" +
                "      </EntityType>\r\n" +
                "      <EntityType Name=\"SubEntityType\" BaseType=\"System.Web.OData.Formatter.AbstractEntityType\">\r\n" +
                "        <Key>\r\n" +
                "          <PropertyRef Name=\"SubKey\" />\r\n" +
                "        </Key>\r\n" +
                "        <Property Name=\"SubKey\" Type=\"Edm.Int32\" Nullable=\"false\" />\r\n" +
                "      </EntityType>\r\n" +
                "      <EntityType Name=\"AnotherSubEntityType\" BaseType=\"System.Web.OData.Formatter.AbstractEntityType\">\r\n" +
                "        <Key>\r\n" +
                "          <PropertyRef Name=\"AnotherKey\" />\r\n" +
                "        </Key>\r\n" +
                "        <Property Name=\"AnotherKey\" Type=\"Edm.Double\" Nullable=\"false\" />\r\n" +
                "      </EntityType>\r\n" +
                "    </Schema>";

            ODataModelBuilder builder = new ODataModelBuilder();

            builder.EntityType <AbstractEntityType>().Abstract().Property(a => a.IntProperty);
            builder.EntityType <SubEntityType>().HasKey(b => b.SubKey).DerivesFrom <AbstractEntityType>();
            builder.EntityType <AnotherSubEntityType>().HasKey(d => d.AnotherKey).DerivesFrom <AbstractEntityType>();
            IEdmModel model = builder.GetEdmModel();

            var config = new[] { typeof(MetadataController) }.GetHttpConfiguration();

            config.MapODataServiceRoute(model);
            HttpServer server = new HttpServer(config);
            HttpClient client = new HttpClient(server);

            // Act
            var response = client.GetAsync("http://localhost/$metadata").Result;

            // Assert
            Assert.True(response.IsSuccessStatusCode);
            Assert.Equal("application/xml", response.Content.Headers.ContentType.MediaType);

            string payload = response.Content.ReadAsStringAsync().Result;

            Assert.Contains(expectMetadata, payload);
        }
Beispiel #2
0
        public void CreateEnumTypeWithoutFlags()
        {
            // Arrange
            var builder = new ODataModelBuilder();
            var simple  = builder.EnumType <SimpleEnum>();

            simple.Member(SimpleEnum.First);
            simple.Member(SimpleEnum.Second);
            simple.Member(SimpleEnum.Third);

            // Act
            var model     = builder.GetEdmModel();
            var colorType = model.SchemaElements.OfType <IEdmEnumType>().Single();

            // Assert
            Assert.False(colorType.IsFlags);
        }
        public void GetEdmModel_ThrowsException_WhenBoundActionOverloaded()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>();

            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);
            customer.Action("ActionOnCustomer");
            customer.Action("ActionOnCustomer").Returns <string>();

            // Act & Assert
            Assert.Throws <InvalidOperationException>(() => builder.GetEdmModel(),
                                                      "Found more than one action with name 'ActionOnCustomer' " +
                                                      "bound to the same type 'System.Web.OData.Builder.TestModels.Customer'. " +
                                                      "Each bound action must have a different binding type or name.");
        }
Beispiel #4
0
        public void CanConfigureSingleProperty_MultipleBindingPath_For_NavigationProperties_WithComplex()
        {
            // Arrange
            ODataModelBuilder builder = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();

            builder
            .EntitySet <BindingCustomer>("Customers")
            .Binding
            .HasSinglePath(c => c.Location)
            .HasRequiredBinding(a => a.City, "Cities");

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            var customers = model.EntityContainer.FindEntitySet("Customers");

            Assert.NotNull(customers);

            // "BindingCustomer" entity type
            var customer = model.AssertHasEntityType(typeof(BindingCustomer));

            Assert.Empty(customer.NavigationProperties());
            IEdmProperty locationProperty = Assert.Single(customer.Properties());

            Assert.Equal("Location", locationProperty.Name);
            Assert.Equal(EdmPropertyKind.Structural, locationProperty.PropertyKind);

            // "BindingAddress" complex type
            var address      = model.AssertHasComplexType(typeof(BindingAddress));
            var cityProperty = address.AssertHasNavigationProperty(model, "City", typeof(BindingCity), isNullable: false, multiplicity: EdmMultiplicity.One);
            var bindings     = customers.FindNavigationPropertyBindings(cityProperty);
            IEdmNavigationPropertyBinding binding = Assert.Single(bindings);

            Assert.Equal("City", binding.NavigationProperty.Name);
            Assert.Equal("Cities", binding.Target.Name);
            Assert.Equal("Location/City", binding.Path.Path);

            IEdmNavigationSource navSource = customers.FindNavigationTarget(cityProperty, binding.Path);

            Assert.Same(navSource, binding.Target);

            // "BindingCity" entity type
            model.AssertHasEntityType(typeof(BindingCity));
        }
        public void GetEdmModel_DoesntCreateOperationImport_For_BoundedOperations()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntitySetConfiguration <Customer> customers = builder.EntitySet <Customer>("Customers");

            customers.EntityType.HasKey(c => c.Id);
            customers.EntityType.Action("Action").Returns <bool>();
            customers.EntityType.Collection.Action("CollectionAction").Returns <bool>();
            customers.EntityType.Function("Function").Returns <bool>();
            customers.EntityType.Collection.Function("Function").Returns <bool>();

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            Assert.Equal(0, model.EntityContainer.OperationImports().Count());
        }
Beispiel #6
0
        public void CanCreateEdmModel_WithTransientBindableAction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>();

            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);

            // Act
            ActionConfiguration sendEmail = customer.TransientAction("ActionName");
            IEdmModel           model     = builder.GetEdmModel();

            // Assert
            IEdmAction action = Assert.Single(model.SchemaElements.OfType <IEdmAction>());

            Assert.True(action.IsBound);
        }
        public void GetEdmModel_SetsNullableIfParameterTypeIsReferenceType()
        {
            // Arrange
            ODataModelBuilder builder             = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();
            EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType;
            var actionBuilder = movie.Action("Watch");

            actionBuilder.Parameter <string>("string").OptionalParameter = false;
            actionBuilder.Parameter <string>("nullaleString");

            actionBuilder.Parameter <Address>("address").OptionalParameter = false;
            actionBuilder.Parameter <Address>("nullableAddress");

            actionBuilder.EntityParameter <Customer>("customer").OptionalParameter = false;
            actionBuilder.EntityParameter <Customer>("nullableCustomer");

            actionBuilder.CollectionParameter <Address>("addresses").OptionalParameter = false;
            actionBuilder.CollectionParameter <Address>("nullableAddresses");

            actionBuilder.CollectionEntityParameter <Customer>("customers").OptionalParameter = false;
            actionBuilder.CollectionEntityParameter <Customer>("nullableCustomers");

            // Act
            IEdmModel model = builder.GetEdmModel();

            //Assert
            IEdmOperation action = Assert.Single(model.SchemaElements.OfType <IEdmAction>());

            Assert.False(action.FindParameter("string").Type.IsNullable);
            Assert.True(action.FindParameter("nullaleString").Type.IsNullable);

            Assert.False(action.FindParameter("address").Type.IsNullable);
            Assert.True(action.FindParameter("nullableAddress").Type.IsNullable);

            Assert.False(action.FindParameter("customer").Type.IsNullable);
            Assert.True(action.FindParameter("nullableCustomer").Type.IsNullable);

            Assert.False(action.FindParameter("addresses").Type.IsNullable);
            Assert.True(action.FindParameter("nullableAddresses").Type.IsNullable);

            // Follow up: https://github.com/OData/odata.net/issues/98
            // Assert.False(action.FindParameter("customers").Type.IsNullable);
            Assert.True(action.FindParameter("nullableCustomers").Type.IsNullable);
        }
Beispiel #8
0
        public void CanConfigureSingleProperty_MultipleBindingPath_For_NavigationProperties_WithComplex_Multiple()
        {
            // Arrange
            ODataModelBuilder builder = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();

            builder
            .EntitySet <BindingCustomer>("Customers")
            .Binding
            .HasSinglePath(c => c.Location)
            .HasRequiredBinding(a => a.City, "Cities_A");

            builder
            .EntitySet <BindingCustomer>("Customers")
            .Binding
            .HasSinglePath(c => c.Address)
            .HasRequiredBinding(a => a.City, "Cities_B");

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            var customers = model.EntityContainer.FindEntitySet("Customers");

            Assert.NotNull(customers);

            // "BindingCustomer" entity type
            var customer = model.AssertHasEntityType(typeof(BindingCustomer));

            Assert.Empty(customer.NavigationProperties());

            // "BindingAddress" complex type
            var address      = model.AssertHasComplexType(typeof(BindingAddress));
            var cityProperty = address.AssertHasNavigationProperty(model, "City", typeof(BindingCity), isNullable: false, multiplicity: EdmMultiplicity.One);
            var bindings     = customers.FindNavigationPropertyBindings(cityProperty).ToList();

            Assert.Equal(2, bindings.Count());

            Assert.Equal("City, City", String.Join(", ", bindings.Select(e => e.NavigationProperty.Name)));
            Assert.Equal("Cities_A, Cities_B", String.Join(", ", bindings.Select(e => e.Target.Name)));
            Assert.Equal("Location/City, Address/City", String.Join(", ", bindings.Select(e => e.Path.Path)));

            // "BindingCity" entity type
            model.AssertHasEntityType(typeof(BindingCity));
        }
Beispiel #9
0
        public void FailingToConfigureNavigationLinks_Results_In_ArgumentException_When_BuildingNavigationLink()
        {
            // Arrange
            ODataModelBuilder builder = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();

            builder.EntitySet <EntitySetLinkConfigurationTest_Product>("Products").HasManyBinding(p => p.Orders, "Orders");
            var model = builder.GetEdmModel();

            IEdmEntitySet          products       = model.EntityContainer.EntitySets().Single(s => s.Name == "Products");
            IEdmNavigationProperty ordersProperty = products.EntityType().DeclaredNavigationProperties().Single();
            var linkBuilder = model.GetNavigationSourceLinkBuilder(products);

            // Act & Assert
            Assert.ThrowsArgument(
                () => linkBuilder.BuildNavigationLink(new EntityInstanceContext(), ordersProperty, ODataMetadataLevel.Default),
                "navigationProperty",
                "No NavigationLink factory was found for the navigation property 'Orders' from entity type 'System.Web.OData.Builder.EntitySetLinkConfigurationTest_Product' on entity set or singleton 'Products'. " +
                "Try calling HasNavigationPropertyLink on the NavigationSourceConfiguration.");
        }
Beispiel #10
0
        public void Cant_SetFunctionTitle_OnNonBindableFunctions()
        {
            // Arrange
            ODataModelBuilder     builder  = new ODataModelBuilder();
            FunctionConfiguration function = builder.Function("MyFunction");

            function.Returns <int>();
            function.Title = "My Function";

            // Act
            IEdmModel           model          = builder.GetEdmModel();
            IEdmOperationImport functionImport = model.EntityContainer.OperationImports().OfType <IEdmFunctionImport>().Single();

            Assert.NotNull(functionImport);
            OperationTitleAnnotation functionTitleAnnotation = model.GetOperationTitleAnnotation(functionImport.Operation);

            // Assert
            Assert.Null(functionTitleAnnotation);
        }
Beispiel #11
0
        public void CanCreateAbstractEntityTypeWithoutKey()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            builder.EntityType <BaseAbstractShape>().Abstract();

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityType baseShapeType =
                model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(e => e.Name == "BaseAbstractShape");

            Assert.NotNull(baseShapeType);
            Assert.True(baseShapeType.IsAbstract);
            Assert.Null(baseShapeType.DeclaredKey);
            Assert.Empty(baseShapeType.Properties());
        }
        public void CanConfig_PrecisionAndScaleOfDecimalType()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            var entity = builder.EntityType <PrecisionEnitity>().HasKey(p => p.Id);

            entity.Property(p => p.DecimalProperty).Precision = 5;
            entity.Property(p => p.DecimalProperty).Scale     = 3;

            // Act
            IEdmModel                model         = builder.GetEdmModel();
            IEdmEntityType           edmEntityType = model.SchemaElements.OfType <IEdmEntityType>().First(p => p.Name == "PrecisionEnitity");
            IEdmDecimalTypeReference decimalType   =
                (IEdmDecimalTypeReference)edmEntityType.DeclaredProperties.First(p => p.Name.Equals("DecimalProperty")).Type;

            // Assert
            Assert.Equal(decimalType.Precision.Value, 5);
            Assert.Equal(decimalType.Scale.Value, 3);
        }
Beispiel #13
0
        public void CanCreateFunctionWithCollectionReturnTypeViaEntitySetPath()
        {
            // Arrange
            ODataModelBuilder builder = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();
            EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>();
            EntityTypeConfiguration <Order>    order    = builder.EntityType <Order>();

            customer.HasMany <Order>(c => c.Orders);
            FunctionConfiguration getOrders = customer.Function("GetOrders").ReturnsCollectionViaEntitySetPath <Order>("bindingParameter/Orders");

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmFunction function = Assert.Single(model.SchemaElements.OfType <IEdmFunction>());

            Assert.Equal(EdmExpressionKind.Path, function.EntitySetPath.ExpressionKind);
            Assert.Equal("bindingParameter/Orders", string.Join("/", ((IEdmPathExpression)(function.EntitySetPath)).Path));
        }
        public void Singleton_CanConfigureLinksIndependently()
        {
            // Arrange
            ODataModelBuilder builder          = GetSingletonModel();
            const string      ExpectedEditLink = "http://server1/service/Exchange";
            const string      ExpectedReadLink = "http://server2/service/Exchange";
            const string      ExpectedIdLink   = "http://server3/service/Exchange";

            var product = builder.Singleton <SingletonProduct>("Exchange");

            product.HasEditLink(c => new Uri("http://server1/service/Exchange"),
                                followsConventions: false);
            product.HasReadLink(c => new Uri("http://server2/service/Exchange"),
                                followsConventions: false);
            product.HasIdLink(c => new Uri("http://server3/service/Exchange"),
                              followsConventions: false);

            var exchange          = builder.Singletons.Single();
            var model             = builder.GetEdmModel();
            var productType       = model.SchemaElements.OfType <IEdmEntityType>().Single();
            var singleton         = model.SchemaElements.OfType <IEdmEntityContainer>().Single().FindSingleton("Exchange");
            var singletonInstance = new SingletonProduct {
                ID = 15
            };
            var serializerContext = new ODataSerializerContext {
                Model = model, NavigationSource = singleton
            };
            var entityContext = new ResourceContext(serializerContext, productType.AsReference(), singletonInstance);

            // Act
            var editLink = exchange.GetEditLink().Factory(entityContext);
            var readLink = exchange.GetReadLink().Factory(entityContext);
            var idLink   = exchange.GetIdLink().Factory(entityContext);

            // Assert
            Assert.NotNull(editLink);
            Assert.Equal(ExpectedEditLink, editLink.ToString());
            Assert.NotNull(readLink);
            Assert.Equal(ExpectedReadLink, readLink.ToString());
            Assert.NotNull(idLink);
            Assert.Equal(ExpectedIdLink, idLink.ToString());
        }
        public void GetEdmModel_SetReturnTypeAsNullable()
        {
            // Arrange
            ODataModelBuilder builder             = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();
            EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType;

            movie.Action("Watch1").Returns <Address>();
            movie.Action("Watch2").Returns <Address>().OptionalReturn = false;

            // Act
            IEdmModel model = builder.GetEdmModel();

            //Assert
            IEdmOperation action = model.SchemaElements.OfType <IEdmAction>().First(e => e.Name == "Watch1");

            Assert.True(action.ReturnType.IsNullable);

            action = model.SchemaElements.OfType <IEdmAction>().First(e => e.Name == "Watch2");
            Assert.False(action.ReturnType.IsNullable);
        }
Beispiel #16
0
        public void GetEdmModel_PropertyWithETag_IsConcurrencyToken()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>();

            customer.HasKey(c => c.Id);
            customer.Property(c => c.Id);
            customer.Property(c => c.Name).IsConcurrencyToken();

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmEntityType         type     = model.AssertHasEntityType(typeof(Customer));
            IEdmStructuralProperty property =
                type.AssertHasPrimitiveProperty(model, "Name", EdmPrimitiveTypeKind.String, isNullable: true);

            Assert.Equal(EdmConcurrencyMode.Fixed, property.ConcurrencyMode);
        }
Beispiel #17
0
        public void CreateCollectionOfEnumTypeProperty()
        {
            // Arrange
            var builder = new ODataModelBuilder().Add_Color_EnumType();
            var complexTypeConfiguration = builder.ComplexType <ComplexTypeWithEnumTypePropertyTestModel>();

            complexTypeConfiguration.CollectionProperty(c => c.Colors);

            // Act
            var model       = builder.GetEdmModel();
            var complexType = model.SchemaElements.OfType <IEdmStructuredType>().Single();

            // Assert
            Assert.Equal(1, complexType.Properties().Count());
            var colors = complexType.Properties().SingleOrDefault(p => p.Name == "Colors");

            Assert.NotNull(colors);
            Assert.True(colors.Type.IsCollection());
            Assert.True(((IEdmCollectionTypeReference)colors.Type).ElementType().IsEnum());
        }
        public void BuilderIncludesMapFromEntityTypeToBindableOperations()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntitySet <Customer>("Customers").EntityType;

            customer.HasKey(c => c.Id);
            customer.Property(c => c.Name);
            customer.Action("Reward");
            IEdmModel      model        = builder.GetEdmModel();
            IEdmEntityType customerType = model.SchemaElements.OfType <IEdmEntityType>().SingleOrDefault();

            // Act
            BindableOperationFinder finder = model.GetAnnotationValue <BindableOperationFinder>(model);

            // Assert
            Assert.NotNull(finder);
            Assert.NotNull(finder.FindOperations(customerType).SingleOrDefault());
            Assert.Equal("Reward", finder.FindOperations(customerType).SingleOrDefault().Name);
        }
Beispiel #19
0
        public void CreateNullableEnumType()
        {
            // Arrange
            var builder = new ODataModelBuilder().Add_Color_EnumType();
            var complexTypeConfiguration = builder.ComplexType <ComplexTypeWithEnumTypePropertyTestModel>();

            complexTypeConfiguration.EnumProperty(c => c.NullableColor);

            // Act
            var model       = builder.GetEdmModel();
            var complexType = model.SchemaElements.OfType <IEdmStructuredType>().Single();

            // Assert
            Assert.Equal(1, complexType.Properties().Count());
            var nullableColor = complexType.Properties().SingleOrDefault(p => p.Name == "NullableColor");

            Assert.NotNull(nullableColor);
            Assert.True(nullableColor.Type.IsEnum());
            Assert.True(nullableColor.Type.IsNullable);
        }
Beispiel #20
0
        public void GetEdmModel_SetsDateTimeAsParameterType_WorksForDefaultConverter()
        {
            // Arrange
            ODataModelBuilder builder             = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();
            EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType;
            var functionBuilder = movie.Function("DateTimeFunction");

            functionBuilder.Parameter <DateTime>("dateTime");
            functionBuilder.Parameter <DateTime?>("nullableDateTime");
            functionBuilder.CollectionParameter <DateTime>("collectionDateTime");
            functionBuilder.CollectionParameter <DateTime?>("nullableCollectionDateTime");
            functionBuilder.Returns <DateTime>();

            // Act
            IEdmModel model = builder.GetEdmModel();

            //Assert
            IEdmOperation function = Assert.Single(model.SchemaElements.OfType <IEdmFunction>());

            Assert.Equal("DateTimeFunction", function.Name);

            Assert.Equal("Edm.DateTimeOffset", function.ReturnType.FullName());
            Assert.False(function.ReturnType.IsNullable);

            IEdmOperationParameter parameter = function.FindParameter("dateTime");

            Assert.Equal("Edm.DateTimeOffset", parameter.Type.FullName());
            Assert.False(parameter.Type.IsNullable);

            parameter = function.FindParameter("nullableDateTime");
            Assert.Equal("Edm.DateTimeOffset", parameter.Type.FullName());
            Assert.True(parameter.Type.IsNullable);

            parameter = function.FindParameter("collectionDateTime");
            Assert.Equal("Collection(Edm.DateTimeOffset)", parameter.Type.FullName());
            Assert.False(parameter.Type.IsNullable);

            parameter = function.FindParameter("nullableCollectionDateTime");
            Assert.Equal("Collection(Edm.DateTimeOffset)", parameter.Type.FullName());
            Assert.True(parameter.Type.IsNullable);
        }
        public void CanConfig_MaxLengthOfStringAndBinaryType()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            var entity = builder.EntityType <PrecisionEnitity>().HasKey(p => p.Id);

            entity.Property(p => p.StringProperty).MaxLength = 5;
            entity.Property(p => p.BinaryProperty).MaxLength = 3;

            // Act
            IEdmModel               model         = builder.GetEdmModel();
            IEdmEntityType          edmEntityType = model.SchemaElements.OfType <IEdmEntityType>().First(p => p.Name == "PrecisionEnitity");
            IEdmStringTypeReference stringType    =
                (IEdmStringTypeReference)edmEntityType.DeclaredProperties.First(p => p.Name.Equals("StringProperty")).Type;
            IEdmBinaryTypeReference binaryType =
                (IEdmBinaryTypeReference)edmEntityType.DeclaredProperties.First(p => p.Name.Equals("BinaryProperty")).Type;

            // Assert
            Assert.Equal(stringType.MaxLength.Value, 5);
            Assert.Equal(binaryType.MaxLength.Value, 3);
        }
Beispiel #22
0
        public void GetEdmModel_WorksOnModelBuilder_ForOpenComplexType()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            ComplexTypeConfiguration <SimpleOpenComplexType> complex = builder.ComplexType <SimpleOpenComplexType>();

            complex.Property(c => c.IntProperty);
            complex.HasDynamicProperties(c => c.DynamicProperties);

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            Assert.NotNull(model);
            IEdmComplexType complexType = Assert.Single(model.SchemaElements.OfType <IEdmComplexType>());

            Assert.True(complexType.IsOpen);
            IEdmProperty edmProperty = Assert.Single(complexType.Properties());

            Assert.Equal("IntProperty", edmProperty.Name);
        }
Beispiel #23
0
        public void GetEdmModel_SetsNullableIffParameterTypeIsNullable()
        {
            // Arrange
            ODataModelBuilder builder             = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>();
            EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType;
            var actionBuilder = movie.Action("Watch");

            actionBuilder.Parameter <int>("int");
            actionBuilder.Parameter <Nullable <int> >("nullableOfInt");
            actionBuilder.Parameter <string>("string");

            // Act
            IEdmModel model = builder.GetEdmModel();

            //Assert
            IEdmOperation action = Assert.Single(model.SchemaElements.OfType <IEdmAction>());

            Assert.False(action.FindParameter("int").Type.IsNullable);
            Assert.True(action.FindParameter("nullableOfInt").Type.IsNullable);
            Assert.True(action.FindParameter("string").Type.IsNullable);
        }
        public void CanCreateEdmModel_WithTransientBindableFunction()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            EntityTypeConfiguration <Customer> customer = builder.EntityType <Customer>();

            customer.HasKey(c => c.CustomerId);
            customer.Property(c => c.Name);

            // Act
            FunctionConfiguration sendEmail = customer.TransientFunction("FunctionName");

            sendEmail.Returns <bool>();
            IEdmModel model = builder.GetEdmModel();

            // Assert
            Assert.Equal(1, model.SchemaElements.OfType <IEdmFunction>().Count());
            IEdmFunction function = Assert.Single(model.SchemaElements.OfType <IEdmFunction>());

            Assert.True(function.IsBound);
        }
        public void FailingToConfigureNavigationLinks_Results_In_ArgumentException_When_BuildingNavigationLink()
        {
            // Arrange
            ODataModelBuilder builder = GetSingletonModel();

            builder.Singleton <SingletonProduct>("Exchange").HasManyBinding(p => p.Orders, "Orders");
            builder.EntitySet <SingletonOrder>("Orders").EntityType.HasKey(p => p.ID);
            var model = builder.GetEdmModel();

            IEdmSingleton          exchange       = model.EntityContainer.FindSingleton("Exchange");
            IEdmNavigationProperty ordersProperty = exchange.EntityType().DeclaredNavigationProperties().Single();
            var linkBuilder = model.GetNavigationSourceLinkBuilder(exchange);

            // Act & Assert
            Assert.ThrowsArgument(
                () => linkBuilder.BuildNavigationLink(new EntityInstanceContext(), ordersProperty, ODataMetadataLevel.Default),
                "navigationProperty",
                "No NavigationLink factory was found for the navigation property 'Orders' from entity type " +
                "'System.Web.OData.Builder.SingletonProduct' on entity set or singleton 'Exchange'. " +
                "Try calling HasNavigationPropertyLink on the NavigationSourceConfiguration.");
        }
Beispiel #26
0
        public void DollarMetadata_Works_ForNullableReferencialConstraint_WithCustomReferentialConstraints()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            builder.EntityType <FkSupplier>().HasKey(c => c.Id);

            var product = builder.EntityType <FkProduct>().HasKey(o => o.Id);

            product.HasOptional(o => o.Supplier, (o, c) => o.SupplierId == c.Id);
            product.HasRequired(o => o.SupplierNav, (o, c) => o.SupplierKey == c.Id);

            IEdmModel model = builder.GetEdmModel();

            HttpConfiguration config = new[] { typeof(MetadataController) }.GetHttpConfiguration();
            HttpServer        server = new HttpServer(config);

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

            HttpClient client = new HttpClient(server);

            // Act
            HttpResponseMessage response = client.GetAsync("http://localhost/odata/$metadata").Result;

            // Assert
            Assert.True(response.IsSuccessStatusCode);

            Assert.Equal("application/xml", response.Content.Headers.ContentType.MediaType);
            string payload = response.Content.ReadAsStringAsync().Result;

            // non-nullable
            Assert.Contains("<Property Name=\"SupplierId\" Type=\"Edm.Int32\" />", payload);
            Assert.Contains("<NavigationProperty Name=\"Supplier\" Type=\"System.Web.OData.Formatter.FkSupplier\">", payload);
            Assert.Contains("<ReferentialConstraint Property=\"SupplierId\" ReferencedProperty=\"Id\" />", payload);

            // nullable
            Assert.Contains("<Property Name=\"SupplierKey\" Type=\"Edm.Int32\" Nullable=\"false\" />", payload);
            Assert.Contains("<NavigationProperty Name=\"SupplierNav\" Type=\"System.Web.OData.Formatter.FkSupplier\" Nullable=\"false\">", payload);
            Assert.Contains("<ReferentialConstraint Property=\"SupplierKey\" ReferencedProperty=\"Id\" />", payload);
        }
Beispiel #27
0
        public void BoundFunction_ForEnumTypeInODataModelBuilder()
        {
            // Arrange
            ODataModelBuilder builder = ODataModelBuilderMocks.GetModelBuilderMock <ODataModelBuilder>().Add_Color_EnumType();
            EntityTypeConfiguration <EnumModel> entityTypeConfiguration = builder.EntityType <EnumModel>();
            FunctionConfiguration functionConfiguration = entityTypeConfiguration.Function("BoundFunction");

            functionConfiguration.Parameter <Color?>("Color");
            functionConfiguration.Returns <Color>();

            // Act & Assert
            IEdmModel    model    = builder.GetEdmModel();
            IEdmFunction function = model.FindDeclaredOperations("Default.BoundFunction").Single() as IEdmFunction;

            IEdmTypeReference color      = function.Parameters.Single(p => p.Name == "Color").Type;
            IEdmTypeReference returnType = function.ReturnType;
            IEdmEnumType      colorType  = model.SchemaElements.OfType <IEdmEnumType>().Single(e => e.Name == "Color");

            Assert.True(color.IsNullable);
            Assert.Same(colorType, color.Definition);
            Assert.Same(colorType, returnType.Definition);
        }
Beispiel #28
0
        public void CanDefinePropertyOnDerivedType_NotPresentInBaseType_ButPresentInDerivedType()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();

            builder.ComplexType <DerivedComplexType>().DerivesFrom <BaseComplexType>().Property(m => m.BaseProperty);

            // Act
            IEdmModel model = builder.GetEdmModel();

            // Assert
            IEdmComplexType baseComplex = model.AssertHasComplexType(typeof(BaseComplexType));

            Assert.Null(baseComplex.BaseComplexType());
            Assert.Equal(0, baseComplex.Properties().Count());

            IEdmComplexType derivedComplex = model.AssertHasComplexType(typeof(DerivedComplexType));

            Assert.Equal(baseComplex, derivedComplex.BaseComplexType());
            Assert.Equal(1, derivedComplex.Properties().Count());
            derivedComplex.AssertHasPrimitiveProperty(model, "BaseProperty", EdmPrimitiveTypeKind.String, true);
        }
Beispiel #29
0
        public void UnboundAction_ForEnumTypeInODataModelBuilder()
        {
            // Arrange
            ODataModelBuilder   builder             = new ODataModelBuilder().Add_Color_EnumType();
            ActionConfiguration actionConfiguration = builder.Action("UnboundAction");

            actionConfiguration.Parameter <Color>("Color");
            actionConfiguration.Returns <Color>();

            // Act & Assert
            IEdmModel        model        = builder.GetEdmModel();
            IEdmActionImport actionImport = model.EntityContainer.OperationImports().Single(o => o.Name == "UnboundAction") as IEdmActionImport;

            IEdmTypeReference color      = actionImport.Action.Parameters.Single(p => p.Name == "Color").Type;
            IEdmTypeReference returnType = actionImport.Action.ReturnType;
            IEdmEnumType      colorType  = model.SchemaElements.OfType <IEdmEnumType>().Single(e => e.Name == "Color");

            Assert.False(color.IsNullable);
            Assert.Same(colorType, color.Definition);
            Assert.False(returnType.IsNullable);
            Assert.Same(colorType, returnType.Definition);
        }
        public void DefaultValue_PrecisionScaleAndMaxLength()
        {
            // Arrange
            ODataModelBuilder builder = new ODataModelBuilder();
            var entity = builder.EntityType <PrecisionEnitity>().HasKey(p => p.Id);

            entity.Property(p => p.DecimalProperty);
            entity.Property(p => p.StringProperty);

            // Act
            IEdmModel               model         = builder.GetEdmModel();
            IEdmEntityType          edmEntityType = model.SchemaElements.OfType <IEdmEntityType>().First(p => p.Name == "PrecisionEnitity");
            IEdmStringTypeReference stringType    =
                (IEdmStringTypeReference)edmEntityType.DeclaredProperties.First(p => p.Name.Equals("StringProperty")).Type;
            IEdmDecimalTypeReference decimalType =
                (IEdmDecimalTypeReference)edmEntityType.DeclaredProperties.First(p => p.Name.Equals("DecimalProperty")).Type;

            // Assert
            Assert.Equal(decimalType.Precision, null);
            Assert.Equal(decimalType.Scale, 0);
            Assert.Equal(stringType.MaxLength, null);
        }