public void CanCreateActionWithNonbindingParameters() { // Arrange // Act ODataModelBuilder builder = new ODataModelBuilder(); ActionConfiguration action = builder.Action("MyAction"); action.Parameter <string>("p0"); action.Parameter <int>("p1"); action.Parameter <Address>("p2"); action.CollectionParameter <string>("p3"); action.CollectionParameter <int>("p4"); action.CollectionParameter <ZipCode>("p5"); action.EntityParameter <Customer>("p6"); action.CollectionEntityParameter <Employee>("p7"); ParameterConfiguration[] parameters = action.Parameters.ToArray(); ComplexTypeConfiguration[] complexTypes = builder.StructuralTypes.OfType <ComplexTypeConfiguration>().ToArray(); EntityTypeConfiguration[] entityTypes = builder.StructuralTypes.OfType <EntityTypeConfiguration>().ToArray(); // Assert Assert.Equal(2, complexTypes.Length); Assert.Equal(typeof(Address).FullName, complexTypes[0].FullName); Assert.Equal(typeof(ZipCode).FullName, complexTypes[1].FullName); Assert.Equal(2, entityTypes.Length); Assert.Equal(typeof(Customer).FullName, entityTypes[0].FullName); Assert.Equal(typeof(Employee).FullName, entityTypes[1].FullName); Assert.Equal(8, parameters.Length); Assert.Equal("p0", parameters[0].Name); Assert.Equal("Edm.String", parameters[0].TypeConfiguration.FullName); Assert.Equal("p1", parameters[1].Name); Assert.Equal("Edm.Int32", parameters[1].TypeConfiguration.FullName); Assert.Equal("p2", parameters[2].Name); Assert.Equal(typeof(Address).FullName, parameters[2].TypeConfiguration.FullName); Assert.Equal("p3", parameters[3].Name); Assert.Equal("Collection(Edm.String)", parameters[3].TypeConfiguration.FullName); Assert.Equal("p4", parameters[4].Name); Assert.Equal("Collection(Edm.Int32)", parameters[4].TypeConfiguration.FullName); Assert.Equal("p5", parameters[5].Name); Assert.Equal(string.Format("Collection({0})", typeof(ZipCode).FullName), parameters[5].TypeConfiguration.FullName); Assert.Equal("p6", parameters[6].Name); Assert.Equal(typeof(Customer).FullName, parameters[6].TypeConfiguration.FullName); Assert.Equal("p7", parameters[7].Name); Assert.Equal(string.Format("Collection({0})", typeof(Employee).FullName), parameters[7].TypeConfiguration.FullName); }
public void DollarMetadata_Works_WithActionParameterNullable_ReturnTypeNullable() { // Arrange const string expectMetadata = @"<Schema Namespace='Default' xmlns='http://docs.oasis-open.org/odata/ns/edm'> <Action Name='NullableAction' IsBound='true'> <Parameter Name='bindingParameter' Type='System.Web.OData.Formatter.FormatterPerson' /> <Parameter Name='param' Type='Edm.String' Unicode='false' /> <ReturnType Type='System.Web.OData.Formatter.FormatterAddress' /> </Action> <Action Name='NonNullableAction' IsBound='true'> <Parameter Name='bindingParameter' Type='System.Web.OData.Formatter.FormatterPerson' /> <Parameter Name='param' Type='Edm.String' Nullable='false' Unicode='false' /> <ReturnType Type='System.Web.OData.Formatter.FormatterAddress' Nullable='false' /> </Action> <EntityContainer Name='Container' /> </Schema> </edmx:DataServices> </edmx:Edmx>"; ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); EntityTypeConfiguration <FormatterPerson> person = builder.EntityType <FormatterPerson>(); ActionConfiguration action = person.Action("NullableAction").Returns <FormatterAddress>(); action.Parameter <string>("param"); action = person.Action("NonNullableAction").Returns <FormatterAddress>(); action.OptionalReturn = false; action.Parameter <string>("param").OptionalParameter = false; 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); Assert.Contains(expectMetadata.Replace("'", "\""), response.Content.ReadAsStringAsync().Result); }
public void CanCreateActionWithNonbindingParameters_AddParameterNonGenericMethod() { // Arrange // Act ODataModelBuilder builder = new ODataModelBuilder(); ActionConfiguration action = builder.Action("MyAction"); action.Parameter(typeof(string), "p0"); action.Parameter(typeof(int), "p1"); action.Parameter(typeof(Address), "p2"); ParameterConfiguration[] parameters = action.Parameters.ToArray(); // Assert Assert.Equal(3, parameters.Length); Assert.Equal("p0", parameters[0].Name); Assert.Equal("Edm.String", parameters[0].TypeConfiguration.FullName); Assert.Equal("p1", parameters[1].Name); Assert.Equal("Edm.Int32", parameters[1].TypeConfiguration.FullName); Assert.Equal("p2", parameters[2].Name); Assert.Equal(typeof(Address).FullName, parameters[2].TypeConfiguration.FullName); }
public void RemoveOperationByNameThrowsWhenAmbiguous() { // Arrange // Act ODataModelBuilder builder = new ODataModelBuilder(); ActionConfiguration action1 = builder.Action("Format"); ActionConfiguration action2 = builder.Action("Format"); action2.Parameter <int>("SegmentSize"); Assert.Throws <InvalidOperationException>(() => { builder.RemoveOperation("Format"); }); }
public void BoundAction_ForEnumTypeInODataConventionModelBuilder() { // Arrange ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); EntityTypeConfiguration <EnumModel> entityTypeConfiguration = builder.EntityType <EnumModel>(); ActionConfiguration actionConfiguration = entityTypeConfiguration.Action("BoundAction"); actionConfiguration.Parameter <Color>("Color"); actionConfiguration.ReturnsCollection <Color>(); // Act & Assert IEdmModel model = builder.GetEdmModel(); IEdmAction action = model.FindDeclaredOperations("Default.BoundAction").Single() as IEdmAction; IEdmTypeReference color = action.Parameters.Single(p => p.Name == "Color").Type; IEdmTypeReference returnType = action.ReturnType; IEdmEnumType colorType = model.SchemaElements.OfType <IEdmEnumType>().Single(e => e.Name == "Color"); Assert.Same(colorType, color.Definition); Assert.True(returnType.IsCollection()); Assert.Same(colorType, returnType.AsCollection().ElementType().Definition); }
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 CanCreateActionWithNonbindingParametersAsNullable() { // Arrange & Act ODataModelBuilder builder = new ODataModelBuilder(); ActionConfiguration action = builder.Action("MyAction"); action.Parameter <string>("p0"); action.Parameter <string>("p1").OptionalParameter = false; action.Parameter <int>("p2").OptionalParameter = true; action.Parameter <int>("p3"); action.Parameter <Address>("p4"); action.Parameter <Address>("p5").OptionalParameter = false; action.CollectionParameter <ZipCode>("p6"); action.CollectionParameter <ZipCode>("p7").OptionalParameter = false; action.EntityParameter <Customer>("p8"); action.EntityParameter <Customer>("p9").OptionalParameter = false; action.CollectionEntityParameter <Customer>("p10"); action.CollectionEntityParameter <Customer>("p11").OptionalParameter = false; Dictionary <string, ParameterConfiguration> parameters = action.Parameters.ToDictionary(e => e.Name, e => e); // Assert Assert.True(parameters["p0"].OptionalParameter); Assert.False(parameters["p1"].OptionalParameter); Assert.True(parameters["p2"].OptionalParameter); Assert.False(parameters["p3"].OptionalParameter); Assert.True(parameters["p4"].OptionalParameter); Assert.False(parameters["p5"].OptionalParameter); Assert.True(parameters["p6"].OptionalParameter); Assert.False(parameters["p7"].OptionalParameter); Assert.True(parameters["p8"].OptionalParameter); Assert.False(parameters["p9"].OptionalParameter); Assert.True(parameters["p10"].OptionalParameter); Assert.False(parameters["p11"].OptionalParameter); }
public void CanBuildOperationBoundToCollectionCacheForIEdmModel() { // Arrange ODataModelBuilder builder = new ODataModelBuilder(); EntityTypeConfiguration <Customer> customer = builder.EntitySet <Customer>("Customers").EntityType; customer.HasKey(c => c.ID); customer.Property(c => c.Name); customer.ComplexProperty(c => c.Address); EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType; movie.HasKey(m => m.ID); movie.HasKey(m => m.Name); EntityTypeConfiguration <Blockbuster> blockBuster = builder.EntityType <Blockbuster>().DerivesFrom <Movie>(); EntityTypeConfiguration movieConfiguration = builder.StructuralTypes.OfType <EntityTypeConfiguration>().Single(t => t.Name == "Movie"); // build actions that are bindable to the collection of entity customer.Collection.Action("CollectionCustomerActionInCache1"); customer.Collection.Action("CollectionCustomerActionInCache2"); movie.Collection.Action("CollectionMovieActionInCache3"); ActionConfiguration movieActionIncache4 = builder.Action("CollectionMovieActionInCache4"); CollectionTypeConfiguration collectionConfiguration = new CollectionTypeConfiguration(movieConfiguration, typeof(Movie)); movieActionIncache4.SetBindingParameter("bindingParameter", collectionConfiguration); blockBuster.Collection.Action("CollectionBlockbusterActionInCache5"); // build functions that are bindable to the collection of entity customer.Collection.Function("CollectionCustomerFunctionInCache1").Returns <int>(); customer.Collection.Function("CollectionCustomerFunctionInCache2").Returns <int>(); movie.Collection.Function("CollectionMovieFunctionInCache3").Returns <int>(); blockBuster.Collection.Function("CollectionBlockbusterFunctionInCache5").Returns <int>(); // build actions that are either: bindable to an entity, have no parameter, have only complex parameter customer.Action("CustomersActionNotInCache1"); customer.Function("CustomersFunctionNotInCache1").Returns <int>(); movie.Action("MoviesActionNotInCache2"); builder.Action("NoParametersNotInCache3"); ActionConfiguration addressParameterNotInCache4 = builder.Action("AddressParameterNotInCache4"); addressParameterNotInCache4.Parameter <Address>("address"); IEdmModel model = builder.GetEdmModel(); IEdmEntityType customerType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Customer"); IEdmEntityType movieType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Movie"); IEdmEntityType blockBusterType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Blockbuster"); // Act BindableOperationFinder annotation = new BindableOperationFinder(model); var movieOperations = annotation.FindOperationsBoundToCollection(movieType).ToArray(); var customerOperations = annotation.FindOperationsBoundToCollection(customerType).ToArray(); var blockBusterOperations = annotation.FindOperationsBoundToCollection(blockBusterType).ToArray(); // Assert Assert.Equal(3, movieOperations.Length); Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieActionInCache3")); Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieActionInCache4")); Assert.Single(movieOperations.Where(a => a.Name == "CollectionMovieFunctionInCache3")); Assert.Equal(4, customerOperations.Length); Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerActionInCache1")); Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerActionInCache2")); Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerFunctionInCache1")); Assert.Single(customerOperations.Where(a => a.Name == "CollectionCustomerFunctionInCache2")); Assert.Equal(5, blockBusterOperations.Length); Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionBlockbusterActionInCache5")); Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionBlockbusterFunctionInCache5")); Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieActionInCache3")); Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieActionInCache4")); Assert.Single(blockBusterOperations.Where(a => a.Name == "CollectionMovieFunctionInCache3")); }
public void CanBuildBoundOperationCacheForIEdmModel() { // Arrange ODataModelBuilder builder = new ODataModelBuilder(); EntityTypeConfiguration <Customer> customer = builder.EntitySet <Customer>("Customers").EntityType; customer.HasKey(c => c.ID); customer.Property(c => c.Name); customer.ComplexProperty(c => c.Address); EntityTypeConfiguration <Movie> movie = builder.EntitySet <Movie>("Movies").EntityType; movie.HasKey(m => m.ID); movie.HasKey(m => m.Name); EntityTypeConfiguration <Blockbuster> blockBuster = builder.EntityType <Blockbuster>().DerivesFrom <Movie>(); EntityTypeConfiguration movieConfiguration = builder.StructuralTypes.OfType <EntityTypeConfiguration>().Single(t => t.Name == "Movie"); // build actions that are bindable to a single entity customer.Action("InCache1_CustomerAction"); customer.Action("InCache2_CustomerAction"); movie.Action("InCache3_MovieAction"); ActionConfiguration incache4_MovieAction = builder.Action("InCache4_MovieAction"); incache4_MovieAction.SetBindingParameter("bindingParameter", movieConfiguration); blockBuster.Action("InCache5_BlockbusterAction"); // build actions that are either: bindable to a collection of entities, have no parameter, have only complex parameter customer.Collection.Action("NotInCache1_CustomersAction"); movie.Collection.Action("NotInCache2_MoviesAction"); ActionConfiguration notInCache3_NoParameters = builder.Action("NotInCache3_NoParameters"); ActionConfiguration notInCache4_AddressParameter = builder.Action("NotInCache4_AddressParameter"); notInCache4_AddressParameter.Parameter <Address>("address"); IEdmModel model = builder.GetEdmModel(); IEdmEntityType customerType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Customer"); IEdmEntityType movieType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Movie"); IEdmEntityType blockBusterType = model.SchemaElements.OfType <IEdmEntityType>().Single(e => e.Name == "Blockbuster"); // Act BindableOperationFinder annotation = new BindableOperationFinder(model); IEdmAction[] movieActions = annotation.FindOperations(movieType) .OfType <IEdmAction>() .ToArray(); IEdmAction[] customerActions = annotation.FindOperations(customerType) .OfType <IEdmAction>() .ToArray(); IEdmAction[] blockBusterActions = annotation.FindOperations(blockBusterType) .OfType <IEdmAction>() .ToArray(); // Assert Assert.Equal(2, customerActions.Length); Assert.NotNull(customerActions.SingleOrDefault(a => a.Name == "InCache1_CustomerAction")); Assert.NotNull(customerActions.SingleOrDefault(a => a.Name == "InCache2_CustomerAction")); Assert.Equal(2, movieActions.Length); Assert.NotNull(movieActions.SingleOrDefault(a => a.Name == "InCache3_MovieAction")); Assert.NotNull(movieActions.SingleOrDefault(a => a.Name == "InCache4_MovieAction")); Assert.Equal(3, blockBusterActions.Length); Assert.NotNull(blockBusterActions.SingleOrDefault(a => a.Name == "InCache3_MovieAction")); Assert.NotNull(blockBusterActions.SingleOrDefault(a => a.Name == "InCache4_MovieAction")); Assert.NotNull(blockBusterActions.SingleOrDefault(a => a.Name == "InCache5_BlockbusterAction")); }