private IEdmModel CreateTestMetadata(out IEdmEntityType entityType, out IEdmComplexType complexType) { EdmModel model = new EdmModel(); EdmEntityType modelEntityType = model.EntityType("EntityType", "TestNS") .KeyProperty("Id", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference); EdmComplexType modelComplexType = model.ComplexType("ComplexType", "TestNS") .Property("EntityProp", modelEntityType.ToTypeReference() as EdmTypeReference) .Property("EntityCollectionProp", EdmCoreModel.GetCollection(modelEntityType.ToTypeReference()) as EdmTypeReference); EdmEntityContainer container = new EdmEntityContainer("TestNS", "TestContainer"); container.AddFunctionAndFunctionImport(model, "FunctionImport1", EdmCoreModel.Instance.GetInt32(false)); container.AddFunctionAndFunctionImport(model, "PrimitiveValueFunctionImport", EdmCoreModel.Instance.GetInt32(false)); container.AddFunctionAndFunctionImport(model, "EntityValueFunctionImport", modelEntityType.ToTypeReference()); container.AddFunctionAndFunctionImport(model, "CollectionOfEntitiesFunctionImport", EdmCoreModel.GetCollection(modelEntityType.ToTypeReference())); model.AddElement(container); model.Fixup(); entityType = (IEdmEntityType)model.FindType("TestNS.EntityType"); ExceptionUtilities.Assert(entityType != null, "entityType != null"); complexType = (IEdmComplexType)model.FindType("TestNS.ComplexType"); ExceptionUtilities.Assert(complexType != null, "complexType != null"); return(model); }
/// <summary> /// Build a test model shared across several tests. /// </summary> /// <param name="addAnnotations">true if the annotations should be added upon construction; otherwise false.</param> /// <returns>Returns the test model.</returns> public static IEdmModel BuildODataAnnotationTestModel(bool addAnnotations) { // The metadata model with OData-specific annotations // - default entity container annotation // - HasStream annotation on entity type // - MimeType annotation on primitive property // - MimeType annotation on service operation EdmModel model = new EdmModel(); var addressType = new EdmComplexType(DefaultNamespaceName, "Address"); addressType.AddStructuralProperty("Street", StringNullableTypeRef); var zipProperty = addressType.AddStructuralProperty("Zip", Int32TypeRef); model.AddElement(addressType); if (addAnnotations) { model.SetMimeType(zipProperty, "text/plain"); } var personType = new EdmEntityType(DefaultNamespaceName, "PersonType", null, false, false, true); personType.AddKeys(personType.AddStructuralProperty("Id", Int32TypeRef)); var nameProperty = personType.AddStructuralProperty("Name", EdmCoreModel.Instance.GetString(isNullable: false)); personType.AddStructuralProperty("Address", new EdmComplexTypeReference(addressType, isNullable: false)); personType.AddStructuralProperty("Picture", EdmPrimitiveTypeKind.Stream, isNullable: false); model.AddElement(personType); if (addAnnotations) { model.SetMimeType(nameProperty, "text/plain"); } // set the default container EdmEntityContainer container = new EdmEntityContainer(DefaultNamespaceName, "DefaultContainer"); model.AddElement(container); container.AddEntitySet("People", personType); // NOTE: Function import parameters and return types must be nullable as per current CSDL spec var serviceOp = container.AddFunctionAndFunctionImport(model, "ServiceOperation1", Int32NullableTypeRef); var serviceOpFunc = serviceOp.Function.AsEdmFunction(); serviceOpFunc.AddParameter("a", Int32NullableTypeRef); serviceOpFunc.AddParameter("b", StringNullableTypeRef); if (addAnnotations) { model.SetMimeType(serviceOpFunc, "img/jpeg"); } return(model); }
private void AddExpectedFunctionImportToCollection(ODataPayloadElementCollection collection) { var expectedTypeAnnotation = collection.GetAnnotation <ExpectedTypeODataPayloadElementAnnotation>(); if (expectedTypeAnnotation == null) { expectedTypeAnnotation = new ExpectedTypeODataPayloadElementAnnotation(); collection.Add(expectedTypeAnnotation); } if (expectedTypeAnnotation.ProductFunctionImport == null) { var typeAnnotation = collection.GetAnnotation <EntityModelTypeAnnotation>(); var collectionType = typeAnnotation.EdmModelType; if (this.testDescriptor.PayloadEdmModel != null) { EdmModel model = this.testDescriptor.PayloadEdmModel as EdmModel; EdmEntityContainer container = model.EntityContainer as EdmEntityContainer; var functionImport = container.OperationImports().FirstOrDefault(f => { return(f.Operation.ReturnType != null && f.Operation.ReturnType == collectionType); }); if (functionImport == null) { functionImport = container.OperationImports().FirstOrDefault(f => { return(f.Operation.ReturnType != null && f.Operation.ReturnType.IsCollection()); }); if (functionImport == null) { var collectionNameAnnotation = collection.GetAnnotation <CollectionNameAnnotation>(); container.AddFunctionAndFunctionImport(model, collectionNameAnnotation == null ? "NewFunctionImport" : collectionNameAnnotation.Name, collectionType); this.testDescriptor.ResetCachedModel(); } } expectedTypeAnnotation.ProductFunctionImport = functionImport as EdmOperationImport; } } }
/// <summary> /// Build a test model shared across several tests. /// </summary> /// <returns>Returns the test model.</returns> public static EdmModel BuildTestModel() { // The metadata model var model = new EdmModel(); var addressType = new EdmComplexType(DefaultNamespaceName, "Address"); addressType.AddStructuralProperty("Street", StringNullableTypeRef); addressType.AddStructuralProperty("Zip", Int32TypeRef); addressType.AddStructuralProperty("SubAddress", new EdmComplexTypeReference(addressType, isNullable: false)); model.AddElement(addressType); var officeType = new EdmEntityType(DefaultNamespaceName, "OfficeType"); officeType.AddKeys(officeType.AddStructuralProperty("Id", Int32TypeRef)); officeType.AddStructuralProperty("Address", new EdmComplexTypeReference(addressType, isNullable: false)); model.AddElement(officeType); var officeWithNumberType = new EdmEntityType(DefaultNamespaceName, "OfficeWithNumberType", officeType); officeWithNumberType.AddStructuralProperty("Number", Int32TypeRef); model.AddElement(officeWithNumberType); var cityType = new EdmEntityType(DefaultNamespaceName, "CityType"); cityType.AddKeys(cityType.AddStructuralProperty("Id", Int32TypeRef)); cityType.AddStructuralProperty("Name", StringNullableTypeRef); cityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "CityHall", Target = officeType, TargetMultiplicity = EdmMultiplicity.Many }); cityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "DOL", Target = officeType, TargetMultiplicity = EdmMultiplicity.Many }); cityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "PoliceStation", Target = officeType, TargetMultiplicity = EdmMultiplicity.One }); cityType.AddStructuralProperty("Skyline", EdmPrimitiveTypeKind.Stream, isNullable: false); cityType.AddStructuralProperty("MetroLanes", EdmCoreModel.GetCollection(StringNullableTypeRef)); model.AddElement(cityType); var metropolitanCityType = new EdmEntityType(DefaultNamespaceName, "MetropolitanCityType", cityType); metropolitanCityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "ContainedOffice", Target = officeType, TargetMultiplicity = EdmMultiplicity.Many, ContainsTarget = true }); officeType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "ContainedCity", Target = metropolitanCityType, TargetMultiplicity = EdmMultiplicity.One, ContainsTarget = true }); model.AddElement(metropolitanCityType); var cityWithMapType = new EdmEntityType(DefaultNamespaceName, "CityWithMapType", cityType, false, false, true); model.AddElement(cityWithMapType); var cityOpenType = new EdmEntityType(DefaultNamespaceName, "CityOpenType", cityType, isAbstract: false, isOpen: true); model.AddElement(cityOpenType); var personType = new EdmEntityType(DefaultNamespaceName, "Person"); personType.AddKeys(personType.AddStructuralProperty("Id", Int32TypeRef)); personType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo { Name = "Friend", Target = personType, TargetMultiplicity = EdmMultiplicity.Many }); model.AddElement(personType); var employeeType = new EdmEntityType(DefaultNamespaceName, "Employee", personType); employeeType.AddStructuralProperty("CompanyName", StringNullableTypeRef); model.AddElement(employeeType); var managerType = new EdmEntityType(DefaultNamespaceName, "Manager", employeeType); managerType.AddStructuralProperty("Level", Int32TypeRef); model.AddElement(managerType); var container = new EdmEntityContainer(DefaultNamespaceName, "DefaultContainer"); model.AddElement(container); container.AddEntitySet("Offices", officeType); container.AddEntitySet("Cities", cityType); container.AddEntitySet("MetropolitanCities", metropolitanCityType); container.AddEntitySet("Persons", personType); container.AddEntitySet("Employee", employeeType); container.AddEntitySet("Manager", managerType); container.AddSingleton("Boss", personType); // Fixup will set DefaultContainer\TopLevelEntitySet\AssociationSet model.Fixup(); // NOTE: Function import parameters and return types must be nullable as per current CSDL spec var serviceOp = container.AddFunctionAndFunctionImport(model, "ServiceOperation1", Int32NullableTypeRef, null, false /*isComposable*/, false /*isBound*/); serviceOp.Function.AsEdmFunction().AddParameter("a", Int32NullableTypeRef); serviceOp.Function.AsEdmFunction().AddParameter("b", StringNullableTypeRef); container.AddFunctionAndFunctionImport(model, "PrimitiveResultOperation", Int32NullableTypeRef, null, false /*isComposable*/, false /*isBound*/); container.AddFunctionAndFunctionImport(model, "ComplexResultOperation", new EdmComplexTypeReference(addressType, isNullable: true), null, false /*isComposable*/, false /*isBound*/); container.AddFunctionAndFunctionImport(model, "PrimitiveCollectionResultOperation", EdmCoreModel.GetCollection(Int32NullableTypeRef), null, false /*isComposable*/, false /*isBound*/); container.AddFunctionAndFunctionImport(model, "ComplexCollectionResultOperation", EdmCoreModel.GetCollection(new EdmComplexTypeReference(addressType, isNullable: true)), null, false /*isComposable*/, false /*isBound*/); // Overload with 0 Param container.AddFunctionAndFunctionImport(model, "FunctionImportWithOverload", Int32NullableTypeRef, null, false /*isComposable*/, false /*isBound*/); // Overload with 1 Param var overloadWithOneParam = container.AddFunctionAndFunctionImport(model, "FunctionImportWithOverload", Int32NullableTypeRef, null, false /*isComposable*/, false /*isBound*/); overloadWithOneParam.Function.AsEdmFunction().AddParameter("p1", new EdmEntityTypeReference(cityWithMapType, isNullable: true)); // Overload with 2 Params var overloadWithTwoParams = container.AddFunctionAndFunctionImport(model, "FunctionImportWithOverload", Int32NullableTypeRef, null, false /*isComposable*/, false /*isBound*/); overloadWithTwoParams.Function.AsEdmFunction().AddParameter("p1", new EdmEntityTypeReference(cityType, isNullable: true)); overloadWithTwoParams.Function.AsEdmFunction().AddParameter("p2", StringNullableTypeRef); // Overload with 5 Params var overloadWithFiveParams = container.AddFunctionAndFunctionImport(model, "FunctionImportWithOverload", Int32NullableTypeRef, null, false /*isComposable*/, false /*isBound*/); overloadWithFiveParams.Function.AsEdmFunction().AddParameter("p1", EdmCoreModel.GetCollection(new EdmEntityTypeReference(cityType, isNullable: true))); overloadWithFiveParams.Function.AsEdmFunction().AddParameter("p2", EdmCoreModel.GetCollection(StringNullableTypeRef)); overloadWithFiveParams.Function.AsEdmFunction().AddParameter("p3", StringNullableTypeRef); overloadWithFiveParams.Function.AsEdmFunction().AddParameter("p4", new EdmComplexTypeReference(addressType, isNullable: true)); overloadWithFiveParams.Function.AsEdmFunction().AddParameter("p5", EdmCoreModel.GetCollection(new EdmComplexTypeReference(addressType, isNullable: true))); return(model); }
/// <summary> /// Creates a test model shared among parameter reader/writer tests. /// </summary> /// <returns>Returns a model with operation imports.</returns> public static IEdmModel BuildModelWithFunctionImport() { EdmCoreModel coreModel = EdmCoreModel.Instance; EdmModel model = new EdmModel(); const string defaultNamespaceName = DefaultNamespaceName; EdmEntityContainer container = new EdmEntityContainer(defaultNamespaceName, "TestContainer"); model.AddElement(container); EdmComplexType complexType = new EdmComplexType(defaultNamespaceName, "ComplexType"); complexType.AddProperty(new EdmStructuralProperty(complexType, "PrimitiveProperty", coreModel.GetString(false))); complexType.AddProperty(new EdmStructuralProperty(complexType, "ComplexProperty", complexType.ToTypeReference(false))); model.AddElement(complexType); EdmEnumType enumType = new EdmEnumType(defaultNamespaceName, "EnumType"); model.AddElement(enumType); EdmEntityType entityType = new EdmEntityType(defaultNamespaceName, "EntityType"); entityType.AddKeys(new IEdmStructuralProperty[] { new EdmStructuralProperty(entityType, "ID", coreModel.GetInt32(false)) }); entityType.AddProperty(new EdmStructuralProperty(entityType, "ComplexProperty", complexType.ToTypeReference())); container.AddFunctionAndFunctionImport(model, "FunctionImport_Primitive", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("primitive", coreModel.GetString(false)); container.AddFunctionAndFunctionImport(model, "FunctionImport_NullablePrimitive", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("nullablePrimitive", coreModel.GetString(true)); EdmCollectionType stringCollectionType = new EdmCollectionType(coreModel.GetString(true)); container.AddFunctionAndFunctionImport(model, "FunctionImport_PrimitiveCollection", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("primitiveCollection", stringCollectionType.ToTypeReference(false)); container.AddFunctionAndFunctionImport(model, "FunctionImport_Complex", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("complex", complexType.ToTypeReference(true)); EdmCollectionType complexCollectionType = new EdmCollectionType(complexType.ToTypeReference()); container.AddFunctionAndFunctionImport(model, "FunctionImport_ComplexCollection", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("complexCollection", complexCollectionType.ToTypeReference()); container.AddFunctionAndFunctionImport(model, "FunctionImport_Entry", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, true /*bindable*/).Function.AsEdmFunction().AddParameter("entry", entityType.ToTypeReference()); EdmCollectionType entityCollectionType = new EdmCollectionType(entityType.ToTypeReference()); container.AddFunctionAndFunctionImport(model, "FunctionImport_Feed", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, true /*bindable*/).Function.AsEdmFunction().AddParameter("feed", entityCollectionType.ToTypeReference()); container.AddFunctionAndFunctionImport(model, "FunctionImport_Stream", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("stream", coreModel.GetStream(false)); container.AddFunctionAndFunctionImport(model, "FunctionImport_Enum", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("enum", enumType.ToTypeReference()); var functionImport_PrimitiveTwoParameters = container.AddFunctionAndFunctionImport(model, "FunctionImport_PrimitiveTwoParameters", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/); var function_PrimitiveTwoParameters = functionImport_PrimitiveTwoParameters.Function.AsEdmFunction(); function_PrimitiveTwoParameters.AddParameter("p1", coreModel.GetInt32(false)); function_PrimitiveTwoParameters.AddParameter("p2", coreModel.GetString(false)); container.AddFunctionAndFunctionImport(model, "FunctionImport_Int", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("p1", coreModel.GetInt32(false)); container.AddFunctionAndFunctionImport(model, "FunctionImport_Double", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/).Function.AsEdmFunction().AddParameter("p1", coreModel.GetDouble(false)); EdmCollectionType int32CollectionType = new EdmCollectionType(coreModel.GetInt32(false)); container.AddActionAndActionImport(model, "FunctionImport_NonNullablePrimitiveCollection", null /*returnType*/, null /*entitySet*/, false /*bindable*/).Action.AsEdmAction().AddParameter("p1", int32CollectionType.ToTypeReference(false)); EdmComplexType complexType2 = new EdmComplexType(defaultNamespaceName, "ComplexTypeWithNullableProperties"); complexType2.AddProperty(new EdmStructuralProperty(complexType2, "StringProperty", coreModel.GetString(true))); complexType2.AddProperty(new EdmStructuralProperty(complexType2, "IntegerProperty", coreModel.GetInt32(true))); model.AddElement(complexType2); EdmEnumType enumType1 = new EdmEnumType(defaultNamespaceName, "enumType1"); enumType1.AddMember(new EdmEnumMember(enumType1, "enumType1_value1", new EdmEnumMemberValue(6))); model.AddElement(enumType1); var functionImport_MultipleNullableParameters = container.AddFunctionAndFunctionImport(model, "FunctionImport_MultipleNullableParameters", coreModel.GetString(false) /*returnType*/, null /*entitySet*/, false /*composable*/, false /*bindable*/); var function_MultipleNullableParameters = functionImport_MultipleNullableParameters.Function.AsEdmFunction(); function_MultipleNullableParameters.AddParameter("p1", coreModel.GetBinary(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p2", coreModel.GetBoolean(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p3", coreModel.GetByte(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p5", coreModel.GetDateTimeOffset(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p6", coreModel.GetDecimal(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p7", coreModel.GetDouble(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p8", coreModel.GetGuid(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p9", coreModel.GetInt16(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p10", coreModel.GetInt32(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p11", coreModel.GetInt64(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p12", coreModel.GetSByte(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p13", coreModel.GetSingle(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p14", coreModel.GetSpatial(EdmPrimitiveTypeKind.GeographyPoint, true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p15", coreModel.GetString(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p16", complexType2.ToTypeReference(true /*isNullable*/)); function_MultipleNullableParameters.AddParameter("p17", enumType1.ToTypeReference(true /*isNullable*/)); return(model); }
public void ReadBindableODataOperationTest() { EdmModel model = Test.OData.Utils.Metadata.TestModels.BuildTestModel() as EdmModel; EdmEntityContainer defaultContainer = model.FindEntityContainer("DefaultContainer") as EdmEntityContainer; IEdmEntitySet cities = defaultContainer.FindEntitySet("Cities"); IEdmEntityType cityType = (IEdmEntityType)model.FindDeclaredType("TestModel.CityType"); var addressInCity1BindableFunctionWithOverload = defaultContainer.AddActionAndActionImport(model, "AddressInCity", EdmCoreModel.Instance.GetBoolean(isNullable: true), null, true); var addressInCity1Action = addressInCity1BindableFunctionWithOverload.Action.AsEdmAction(); addressInCity1Action.AddParameter("city", new EdmEntityTypeReference(cityType, isNullable: true)); addressInCity1Action.AddParameter("address", EdmCoreModel.Instance.GetString(isNullable: true)); var funcWithOneParamImport = defaultContainer.AddFunctionAndFunctionImport(model, "BindableFunctionWithOverload", EdmCoreModel.Instance.GetInt32(true), null, false, true); var funcWithOneParam = funcWithOneParamImport.Function.AsEdmFunction(); funcWithOneParam.AddParameter("p1", new EdmEntityTypeReference(cityType, isNullable: true)); var funcWithTwoParamImport = defaultContainer.AddFunctionAndFunctionImport(model, "BindableFunctionWithOverload", EdmCoreModel.Instance.GetInt32(true), null, false, true); var funcWithTwoParam = funcWithTwoParamImport.Function.AsEdmFunction(); funcWithTwoParam.AddParameter("p1", new EdmEntityTypeReference(cityType, isNullable: true)); funcWithTwoParam.AddParameter("p2", EdmCoreModel.Instance.GetString(isNullable: true)); var testCases = new[] { new { DebugDescription = "No always bindable operations in payload", Json = "\"#TestModel.PrimitiveResultOperation\":{}", ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)" }, } }, new { DebugDescription = "Always bindable operations from default container and always bindable function group in payload", Json = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload\":{}", ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload", Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload" }, } }, new { DebugDescription = "Always bindable operations and function group with namespace from default container in payload", Json = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload\":{}", ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload", Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload" }, } }, new { DebugDescription = "Always bindable operations from non-default container and function overload with 1 param in payload", Json = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload(p1)\":{}", ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)" }, } }, new { DebugDescription = "Always bindable operations and function overload with 2 params, with namespace from non-default container in payload", Json = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{},\"#TestModel.BindableFunctionWithOverload(p1)\":{}", ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)" }, } }, new { DebugDescription = "All of the always bindable operations in payload", Json = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{}," + "\"#TestModel.BindableFunctionWithOverload(p1)\":{},\"#TestModel.BindableFunctionWithOverload(p1,p2)\":{}", ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)" }, } }, new { DebugDescription = "All of the always bindable operations with namespace in payload", Json = "\"#TestModel.PrimitiveResultOperation\":{},\"#TestModel.AddressInCity\":{}," + "\"#TestModel.BindableFunctionWithOverload(p1)\":{},\"#TestModel.BindableFunctionWithOverload(p1,p2)\":{}", ExpectedServiceOperationDescriptor = new[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/test/$metadata#TestModel.AddressInCity", Title = "TestModel.AddressInCity", Target = "http://odata.org/test/Cities(1)/TestModel.AddressInCity" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.PrimitiveResultOperation", Title = "TestModel.PrimitiveResultOperation", Target = "http://odata.org/test/Cities(1)/TestModel.PrimitiveResultOperation" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("()"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload" }, new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/test/$metadata#TestModel.BindableFunctionWithOverload" + Uri.EscapeDataString("(p2)"), Title = "TestModel.BindableFunctionWithOverload", Target = "http://odata.org/test/Cities(1)/TestModel.BindableFunctionWithOverload(p2=@p2)" }, } }, }; IEnumerable <PayloadReaderTestDescriptor> testDescriptors = testCases.Select( t => new PayloadReaderTestDescriptor(this.Settings) { DebugDescription = t.DebugDescription, PayloadEdmModel = model, PayloadElement = PayloadBuilder.Entity("TestModel.CityType") .JsonRepresentation( "{" + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#DefaultContainer.Cities/$entity\"," + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.CityType\"," + "\"Id\":1," + "\"Name\":\"New York\"," + t.Json + "}") .ExpectedEntityType(cityType, cities), ExpectedResultPayloadElement = (tc) => { var entityInstance = PayloadBuilder.Entity("TestModel.CityType"). PrimitiveProperty("Id", 1). PrimitiveProperty("Name", "New York"). StreamProperty("Skyline", "http://odata.org/test/Cities(1)/Skyline", "http://odata.org/test/Cities(1)/Skyline"). NavigationProperty("CityHall", "http://odata.org/test/Cities(1)/CityHall"). NavigationProperty("DOL", "http://odata.org/test/Cities(1)/DOL"). NavigationProperty("PoliceStation", "http://odata.org/test/Cities(1)/PoliceStation"); foreach (var op in t.ExpectedServiceOperationDescriptor) { entityInstance.OperationDescriptor(op); } return(entityInstance); }, SkipTestConfiguration = tc => tc.IsRequest }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations, (testDescriptor, testConfiguration) => { if (testConfiguration.IsRequest) { testDescriptor = new PayloadReaderTestDescriptor(testDescriptor); testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize); } // These descriptors are already tailored specifically for Json Light and // do not require normalization. testDescriptor.TestDescriptorNormalizers.Clear(); testDescriptor.RunTest(testConfiguration); }); }