public void NullValueNonPropertyErrorTests() { EdmModel model = new EdmModel(); var entityType = model.EntityType("OwningType", "TestModel").KeyProperty("ID", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference); model.EntityContainer("DefaultContainer"); var entitySet = model.EntitySet("EntitySet", entityType); IEnumerable<PayloadReaderTestDescriptor> testDescriptors = new[] { new PayloadReaderTestDescriptor(this.Settings) { DebugDescription = "null collection - should fail.", PayloadEdmModel = model, PayloadElement = PayloadBuilder.PrimitiveCollection().ExpectedCollectionItemType(EdmDataTypes.Int32) .JsonRepresentation( "{" + "\"@odata.context\":\"http://odata.org/test/$metadata#Edm.Null\"" + "}"), ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind", "http://odata.org/test/$metadata#Edm.Null", "Collection") }, new PayloadReaderTestDescriptor(this.Settings) { DebugDescription = "null entry - should fail.", PayloadEdmModel = model, PayloadElement = PayloadBuilder.NullEntity().ExpectedEntityType(entityType, entitySet) .JsonRepresentation( "{" + "\"@odata.context\":\"http://odata.org/test/$metadata#Edm.Null\"" + "}"), ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind", "http://odata.org/test/$metadata#Edm.Null", "Entry") }, new PayloadReaderTestDescriptor(this.Settings) { DebugDescription = "null feed - should fail.", PayloadEdmModel = model, PayloadElement = PayloadBuilder.EntitySet().ExpectedEntityType(entityType, entitySet) .JsonRepresentation( "{" + "\"@odata.context\":\"http://odata.org/test/$metadata#Edm.Null\"" + "}"), ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightContextUriParser_ContextUriDoesNotMatchExpectedPayloadKind", "http://odata.org/test/$metadata#Edm.Null", "Feed") }, }; this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations, (testDescriptor, testConfiguration) => { if (testConfiguration.IsRequest) { return; } // These descriptors are already tailored specifically for Json Light and // do not require normalization. testDescriptor.TestDescriptorNormalizers.Clear(); testDescriptor.RunTest(testConfiguration); }); }
public void ActionAndFunctionTest() { // <m:action Metadata=URI title?="title" target=URI /> Uri actionMetadata = new Uri("http://odata.org/test/$metadata#defaultAction"); Uri actionMetadata2 = new Uri("#action escaped relative metadata", UriKind.Relative); Uri actionMetadata3 = new Uri("../#action escaped relative metadata", UriKind.Relative); string actionTitle = "Default Action"; Uri actionTarget = new Uri("http://odata.org/defaultActionTarget"); Uri actionTarget2 = new Uri("http://odata.org/defaultActionTarget2"); ODataAction action_r1_t1 = new ODataAction() { Metadata = actionMetadata, Title = actionTitle, Target = actionTarget }; ODataAction action_r1_t2 = new ODataAction() { Metadata = actionMetadata, Title = actionTitle, Target = actionTarget2 }; ODataAction action_r2_t1 = new ODataAction() { Metadata = actionMetadata2, Title = actionTitle, Target = actionTarget }; ODataAction action_r3_t1 = new ODataAction() { Metadata = actionMetadata3, Title = actionTitle, Target = actionTarget }; Uri functionMetadata = new Uri("http://odata.org/test/$metadata#defaultFunction"); Uri functionMetadata2 = new Uri("#function escaped relative metadata", UriKind.Relative); Uri functionMetadata3 = new Uri("\\#function escaped relative metadata", UriKind.Relative); string functionTitle = "Default Function"; Uri functionTarget = new Uri("http://odata.org/defaultFunctionTarget"); Uri functionTarget2 = new Uri("http://odata.org/defaultFunctionTarget2"); ODataFunction function_r1_t1 = new ODataFunction() { Metadata = functionMetadata, Title = functionTitle, Target = functionTarget }; ODataFunction function_r1_t2 = new ODataFunction() { Metadata = functionMetadata, Title = functionTitle, Target = functionTarget2 }; ODataFunction function_r2_t1 = new ODataFunction() { Metadata = functionMetadata2, Title = functionTitle, Target = functionTarget }; ODataFunction function_r3_t1 = new ODataFunction() { Metadata = functionMetadata3, Title = functionTitle, Target = functionTarget }; var actionCases = new[] { new { ODataActions = new ODataAction[] { action_r1_t1 }, Atom = GetAtom(action_r1_t1), JsonLight = GetJsonLightForRelGroup(action_r1_t1), }, new { ODataActions = new ODataAction[] { action_r1_t1, action_r1_t2 }, Atom = GetAtom(action_r1_t1) + GetAtom(action_r1_t2), JsonLight = GetJsonLightForRelGroup(action_r1_t1, action_r1_t2), }, new { ODataActions = new ODataAction[] { action_r1_t1, action_r2_t1 }, Atom = GetAtom(action_r1_t1) + GetAtom(action_r2_t1), JsonLight = GetJsonLightForRelGroup(action_r1_t1) + "," + GetJsonLightForRelGroup(action_r2_t1), }, new { ODataActions = new ODataAction[] { action_r1_t1, action_r2_t1, action_r1_t2 }, Atom = GetAtom(action_r1_t1) + GetAtom(action_r2_t1) + GetAtom(action_r1_t2), JsonLight = GetJsonLightForRelGroup(action_r1_t1, action_r1_t2) + "," + GetJsonLightForRelGroup(action_r2_t1), }, new { ODataActions = new ODataAction[] { action_r3_t1 }, Atom = GetAtom(action_r3_t1), JsonLight = GetJsonLightForRelGroup(action_r3_t1), }, }; var functionCases = new[] { new { ODataFunctions = new ODataFunction[] { function_r1_t1 }, Atom = GetAtom(function_r1_t1), JsonLight = GetJsonLightForRelGroup(function_r1_t1), }, new { ODataFunctions = new ODataFunction[] { function_r1_t1, function_r1_t2 }, Atom = GetAtom(function_r1_t1) + GetAtom(function_r1_t2), JsonLight = GetJsonLightForRelGroup(function_r1_t1, function_r1_t2), }, new { ODataFunctions = new ODataFunction[] { function_r1_t1, function_r2_t1 }, Atom = GetAtom(function_r1_t1) + GetAtom(function_r2_t1), JsonLight = GetJsonLightForRelGroup(function_r1_t1) + "," + GetJsonLightForRelGroup(function_r2_t1), }, new { ODataFunctions = new ODataFunction[] { function_r1_t1, function_r2_t1, function_r1_t2 }, Atom = GetAtom(function_r1_t1) + GetAtom(function_r2_t1) + GetAtom(function_r1_t2), JsonLight = GetJsonLightForRelGroup(function_r1_t1, function_r1_t2) + "," + GetJsonLightForRelGroup(function_r2_t1), }, new { ODataFunctions = new ODataFunction[] { function_r3_t1 }, Atom = GetAtom(function_r3_t1), JsonLight = GetJsonLightForRelGroup(function_r3_t1), }, }; var queryResults = from actionCase in actionCases from functionCase in functionCases select new { actionCase.ODataActions, functionCase.ODataFunctions, Atom = string.Concat(actionCase.Atom, functionCase.Atom), JsonLight = string.Join(",", new[] { actionCase.JsonLight, functionCase.JsonLight }.Where(x => x != null)) }; EdmModel model = new EdmModel(); EdmEntityType edmEntityTypeCustomer = model.EntityType("Customer", "TestModel"); EdmEntityContainer edmEntityContainer = model.EntityContainer("DefaultContainer","TestModel" ); EdmEntitySet edmEntitySetCustermors = model.EntitySet("Customers", edmEntityTypeCustomer); var testDescriptors = queryResults.Select(testCase => { ODataEntry entry = ObjectModelUtils.CreateDefaultEntry("TestModel.Customer"); if (testCase.ODataActions != null) { foreach (var action in testCase.ODataActions) { entry.AddAction(action); } } if (testCase.ODataFunctions != null) { foreach (var function in testCase.ODataFunctions) { entry.AddFunction(function); } } return new PayloadWriterTestDescriptor<ODataItem>( this.Settings, entry, (testConfiguration) => { if (testConfiguration.Format == ODataFormat.Atom) { return new AtomWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Xml = "<ODataOperations>" + testCase.Atom + "</ODataOperations>", ExpectedException2 = entry.Actions != null && entry.Actions.Contains(null) ? ODataExpectedExceptions.ODataException("ValidationUtils_EnumerableContainsANullItem", "ODataEntry.Actions") : testConfiguration.IsRequest && entry.Actions != null && entry.Actions.Any() ? ODataExpectedExceptions.ODataException("WriterValidationUtils_OperationInRequest", GetFirstOperationMetadata(entry)) : entry.Functions != null && entry.Functions.Contains(null) ? ODataExpectedExceptions.ODataException("ValidationUtils_EnumerableContainsANullItem", "ODataEntry.Functions") : testConfiguration.IsRequest && entry.Functions != null && entry.Functions.Any() ? ODataExpectedExceptions.ODataException("WriterValidationUtils_OperationInRequest", GetFirstOperationMetadata(entry)) : null, FragmentExtractor = (result) => { var actions = result.Elements(TestAtomConstants.ODataMetadataXNamespace + "action"); var functions = result.Elements(TestAtomConstants.ODataMetadataXNamespace + "function"); result = new XElement("ODataOperations", actions, functions); if (result.FirstNode == null) { result.Add(string.Empty); } return result; } }; } else if (testConfiguration.Format == ODataFormat.Json) { return new JsonWriterTestExpectedResults(this.Settings.ExpectedResultSettings) { Json = string.Join( "$(NL)", "{", testCase.JsonLight, "}"), ExpectedException2 = entry.Actions != null && entry.Actions.Contains(null) ? ODataExpectedExceptions.ODataException("ValidationUtils_EnumerableContainsANullItem", "ODataEntry.Actions") : testConfiguration.IsRequest && entry.Actions != null && entry.Actions.Any() ? ODataExpectedExceptions.ODataException("WriterValidationUtils_OperationInRequest", GetFirstOperationMetadata(entry)) : entry.Actions != null && entry.Actions.Any(a => !a.Metadata.IsAbsoluteUri && !a.Metadata.OriginalString.StartsWith("#")) ? ODataExpectedExceptions.ODataException("ValidationUtils_InvalidMetadataReferenceProperty", entry.Actions.First(a => a.Metadata.OriginalString.Contains(" ")).Metadata.OriginalString) : entry.Functions != null && entry.Functions.Contains(null) ? ODataExpectedExceptions.ODataException("ValidationUtils_EnumerableContainsANullItem", "ODataEntry.Functions") : testConfiguration.IsRequest && entry.Functions != null && entry.Functions.Any() ? ODataExpectedExceptions.ODataException("WriterValidationUtils_OperationInRequest", GetFirstOperationMetadata(entry)) : entry.Functions != null && entry.Functions.Any(f => !f.Metadata.IsAbsoluteUri && !f.Metadata.OriginalString.StartsWith("#")) ? ODataExpectedExceptions.ODataException("ValidationUtils_InvalidMetadataReferenceProperty", entry.Functions.First(f => f.Metadata.OriginalString.Contains(" ")).Metadata.OriginalString) : null, FragmentExtractor = (result) => { var actionsAndFunctions = result.Object().Properties.Where(p => p.Name.Contains("#")).ToList(); var jsonResult = new JsonObject(); actionsAndFunctions.ForEach(p => { // NOTE we remove all annotations here and in particular the text annotations to be able to easily compare // against the expected results. This however means that we do not distinguish between the indented and non-indented case here. p.RemoveAllAnnotations(true); jsonResult.Add(p); }); return jsonResult; } }; } else { string formatName = testConfiguration.Format == null ? "null" : testConfiguration.Format.GetType().Name; throw new NotSupportedException("Invalid format detected: " + formatName); } }); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors.PayloadCases(WriterPayloads.EntryPayloads), this.WriterTestConfigurationProvider.ExplicitFormatConfigurationsWithIndent, (testDescriptor, testConfiguration) => { testConfiguration = testConfiguration.Clone(); testConfiguration.MessageWriterSettings.SetServiceDocumentUri(ServiceDocumentUri); if (testConfiguration.Format == ODataFormat.Json) { if (testDescriptor.IsGeneratedPayload) { return; } // We need a model, entity set and entity type for JSON Light testDescriptor = new PayloadWriterTestDescriptor<ODataItem>(testDescriptor) { Model = model, PayloadEdmElementContainer = edmEntitySetCustermors, PayloadEdmElementType = edmEntityTypeCustomer, }; } TestWriterUtils.WriteAndVerifyODataPayload(testDescriptor, testConfiguration, this.Assert, this.Logger); }); }
public void TopLevelPropertiesWithMetadataTest() { IEnumerable<PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreatePrimitiveValueTestDescriptors(this.Settings); testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, true)); testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateCollectionTestDescriptors(this.Settings, true)); testDescriptors = testDescriptors.Select(collectionTestDescriptor => collectionTestDescriptor.InProperty("propertyName")); testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td)); // Limit to only top-level property payloads testDescriptors = testDescriptors.Where(td => td.PayloadElement is PropertyInstance); // Add a couple of invalid cases which use a standard model EdmModel model = new EdmModel(); model.ComplexType("UnusedComplexType"); EdmEntityType unusedEntityType = model.EntityType("UnusedEntityType"); unusedEntityType.AddKeys(unusedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false)); unusedEntityType.Property("Name", EdmPrimitiveTypeKind.String, isNullable: false); EdmEntityType streamPropertyEntityType = model.EntityType("EntityTypeWithStreamProperty"); streamPropertyEntityType.AddKeys(streamPropertyEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false)); streamPropertyEntityType.AddStructuralProperty("Video", EdmPrimitiveTypeKind.Stream, isNullable: false); streamPropertyEntityType.Property("NonStreamProperty", EdmPrimitiveTypeKind.Boolean, isNullable: false); EdmEntityType navigationPropertyEntityType = model.EntityType("EntityTypeWithNavigationProperty"); navigationPropertyEntityType.AddKeys(navigationPropertyEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32, isNullable: false)); navigationPropertyEntityType.NavigationProperty("Navigation", streamPropertyEntityType); model.Fixup(); EdmEntityContainer container = model.EntityContainer as EdmEntityContainer; EdmFunction nameFunction = new EdmFunction(container.Namespace, "NameFunctionImport", EdmCoreModel.Instance.GetInt32(false), false /*isBound*/, null, false /*isComposable*/); model.AddElement(nameFunction); container.AddFunctionImport("NameFunctionImport", nameFunction); model.Fixup(); var videoPropertyType = model.GetEntityType("TestModel.EntityTypeWithStreamProperty").Properties().Single(p => p.Name == "Video").Type; var explicitTestDescriptors = new[] { // Non existant type name new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("TestModel.NonExistantType")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "TestModel.NonExistantType"), // This test has different meaning in JSON-L (no expected type + non-existent typename) SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, // Existing type name without namespace new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("UnusedComplexType")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "UnusedComplexType"), // This test has different meaning in JSON-L (no expected type + non-existent typename) SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, // Existing type of wrong kind new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("propertyName", PayloadBuilder.ComplexValue("TestModel.UnusedEntityType")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectValueTypeKind", "TestModel.UnusedEntityType", "Entity"), // This test has different meaning in JSON-L SkipTestConfiguration = (tc) => tc.Format == ODataFormat.Json, }, // A stream is not allowed in a property with a non-stream property kind. new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.EntityTypeWithStreamProperty").StreamProperty("NonStreamProperty", "http://readlink", "http://editlink"), PayloadEdmModel = model, ExpectedResultCallback = tc => new PayloadReaderTestExpectedResult(this.Settings.ExpectedResultSettings) { ExpectedException = tc.Format == ODataFormat.Atom ? tc.IsRequest ? null : ODataExpectedExceptions.ODataException("ValidationUtils_MismatchPropertyKindForStreamProperty", "NonStreamProperty") : tc.Format == ODataFormat.Json ? ODataExpectedExceptions.ODataException("ODataJsonLightEntryAndFeedDeserializer_PropertyWithoutValueWithWrongType", "NonStreamProperty", "Edm.Boolean") : ODataExpectedExceptions.ODataException("JsonReaderExtensions_UnexpectedNodeDetected", "PrimitiveValue", "StartObject") }, }, // Top-level property of stream type is not allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(videoPropertyType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeStream"), }, // Top-level deferred navigation property is not allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(streamPropertyEntityType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeEntityKind"), }, // Top-level expanded navigation property is not allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveProperty("Video", 42).ExpectedPropertyType(streamPropertyEntityType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ArgumentException("ODataMessageReader_ExpectedPropertyTypeEntityKind"), }, }; testDescriptors = testDescriptors.Concat(explicitTestDescriptors); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations, (testDescriptor, testConfiguration) => { var property = testDescriptor.PayloadElement as PropertyInstance; if (property != null && testConfiguration.Format == ODataFormat.Atom) { property.Name = null; } testDescriptor.RunTest(testConfiguration); }); }
public void StreamPropertiesProjectionTest() { EdmModel model = new EdmModel(); var container = new EdmEntityContainer("TestModel", "DefaultContainer"); model.AddElement(container); EdmEntityType townType = model.EntityType("TownType"); townType.KeyProperty("Id", EdmCoreModel.Instance.GetInt32(false)); townType.StreamProperty("MapSmall"); townType.StreamProperty("MapMedium"); townType.NavigationProperty("NavProp", townType); EdmEntityType cityType = model.EntityType("CityType", null, townType); cityType.StreamProperty("CityLogo"); EdmEntitySet townsSet = model.EntitySet("Towns", townType); model.Fixup(); var testCases = new ProjectionTestCase[] { #region No $select new ProjectionTestCase { DebugDescription = "No $select => three templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall").StreamProperty("MapMedium").StreamProperty("CityLogo").NavigationProperty("NavProp", /*url*/null), ProjectionString = null, }, new ProjectionTestCase { DebugDescription = "No $select + one property in the payload => two templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium").StreamProperty("CityLogo").NavigationProperty("NavProp", /*url*/null), ProjectionString = null, }, new ProjectionTestCase { DebugDescription = "No $select + three properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read").NavigationProperty("NavProp", /*url*/null), ProjectionString = null, }, #endregion No $select #region Empty $select new ProjectionTestCase { DebugDescription = "Empty $select => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ProjectionString = string.Empty, }, new ProjectionTestCase { DebugDescription = "Empty $select + one property in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read"), ProjectionString = string.Empty, }, new ProjectionTestCase { DebugDescription = "Empty $select + three properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read"), ProjectionString = string.Empty, }, #endregion Empty $select #region $select=* new ProjectionTestCase { DebugDescription = "$select=* => three templatized stream properties and and one templatized navigation.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall").StreamProperty("MapMedium").StreamProperty("CityLogo").NavigationProperty("NavProp", /*url*/null), ProjectionString = "*", }, new ProjectionTestCase { DebugDescription = "$select=* + one property in the payload => two templatized stream properties and one templatized navigation.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium").StreamProperty("CityLogo").NavigationProperty("NavProp", /*url*/null), ProjectionString = "*", }, new ProjectionTestCase { DebugDescription = "$select=* + three properties in the payload => no templatized stream properties, one templatized navigation.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read").NavigationProperty("NavProp", /*url*/null), ProjectionString = "*", }, #endregion $select=* #region $select=MapMedium new ProjectionTestCase { DebugDescription = "$select=MapMedium => one templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapMedium"), ProjectionString = "MapMedium", }, new ProjectionTestCase { DebugDescription = "$select=MapMedium + MapMedium property in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapMedium", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapMedium", "http://odata.org/stream/read"), ProjectionString = "MapMedium", }, new ProjectionTestCase { DebugDescription = "$select=MapMedium + MapSmall property in the payload => one templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium"), ProjectionString = "MapMedium", }, new ProjectionTestCase { DebugDescription = "$select=MapMedium + three properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read"), ProjectionString = "MapMedium", }, #endregion $select=MapMedium #region $select=NavProp/* new ProjectionTestCase { DebugDescription = "$select=NavProp/* => three templatized stream properties and and one templatized navigation.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2)), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).StreamProperty("MapSmall").StreamProperty("MapMedium").StreamProperty("CityLogo").NavigationProperty("NavProp", /*url*/null)), ProjectionString = "NavProp/*", }, new ProjectionTestCase { DebugDescription = "$select=NavProp/* + one property in the payload => two templatized stream properties and one templatized navigation.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).StreamProperty("MapSmall", "http://odata.org/stream/read")), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium").StreamProperty("CityLogo").NavigationProperty("NavProp", /*url*/null)), ProjectionString = "NavProp/*", }, new ProjectionTestCase { DebugDescription = "$select=NavProp/* + three properties in the payload => no templatized stream properties, one templatized navigation.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read")), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).StreamProperty("MapSmall", "http://odata.org/stream/read").StreamProperty("MapMedium", "http://odata.org/stream/read").StreamProperty("CityLogo", "http://odata.org/stream/read").NavigationProperty("NavProp", /*url*/null)), ProjectionString = "NavProp/*", }, #endregion $select=NavProp/* #region $select=NavProp/NavProp/MapMedium new ProjectionTestCase { DebugDescription = "$select=NavProp/NavProp/MapMedium => one templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 3))), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 3).StreamProperty("MapMedium"))), ProjectionString = "NavProp/NavProp/MapMedium", }, #endregion $select=NavProp/NavProp/MapMedium #region $select=NavProp/NavProp new ProjectionTestCase { DebugDescription = "$select=NavProp/NavProp => three templatized stream properties and one navigation property.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 3))), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).ExpandedNavigationProperty("NavProp", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 3).StreamProperty("MapSmall").StreamProperty("MapMedium").StreamProperty("CityLogo").NavigationProperty("NavProp", /*url*/null))), ProjectionString = "NavProp/NavProp", }, #endregion $select=NavProp/NavProp #region $select=TestModel.CityType/CityLogo new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/CityLogo on base type => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ProjectionString = "TestModel.CityType/CityLogo", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/CityLogo on derived type => specific property templatized.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("CityLogo"), ProjectionString = "TestModel.CityType/CityLogo", }, #endregion $select=TestModel.CityType/CityLogo #region $select=TestModel.CityType/MapSmall new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/MapSmall on base type => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ProjectionString = "TestModel.CityType/MapSmall", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/MapSmall on derived type => specific property templatized.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall"), ProjectionString = "TestModel.CityType/MapSmall", }, #endregion $select=TestModel.CityType/MapSmall #region $select=TestModel.TownType/MapSmall new ProjectionTestCase { DebugDescription = "$select=TestModel.TownType/MapSmall on base type => specific property templatized..", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall"), ProjectionString = "TestModel.TownType/MapSmall", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.TownType/MapSmall on derived type => specific property templatized.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).StreamProperty("MapSmall"), ProjectionString = "TestModel.TownType/MapSmall", }, #endregion $select=TestModel.TownType/MapSmall }; IEnumerable<PayloadReaderTestDescriptor> testDescriptors = testCases.Select(testCase => new PayloadReaderTestDescriptor(this.Settings) { DebugDescription = testCase.DebugDescription, PayloadEdmModel = model, PayloadElement = testCase.PayloadEntity .WithContextUriProjection(testCase.ProjectionString) .ExpectedEntityType(townType, townsSet), ExpectedResultPayloadElement = tc => testCase.ExpectedEntity, ExpectedException = testCase.ExpectedException, }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { // These descriptors are already tailored specifically for Json Light and // do not require normalization. testDescriptor.TestDescriptorNormalizers.Clear(); testDescriptor.RunTest(testConfiguration); }); }
public void NavigationPropertiesProjectionTest() { EdmModel model = new EdmModel(); EdmEntityType townType = model.EntityType("TownType"); townType.KeyProperty("Id", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference); townType.NavigationProperty("NavProp1", townType); EdmEntitySet townsSet = model.EntitySet("Towns", townType); EdmEntityType cityType = new EdmEntityType("TestModel", "CityType", townType); model.AddElement(cityType); cityType.NavigationProperty("NavProp2", townType); model.EntitySet("Cities", cityType); EdmEntityType cityType2 = new EdmEntityType("TestModel", "DuplicateCityType", townType); model.AddElement(cityType2); cityType2.NavigationProperty("NavProp2", townType); model.EntitySet("DuplicateCities", cityType2); model.Fixup(); var testCases = new ProjectionTestCase[] { #region No $select new ProjectionTestCase { DebugDescription = "No $select => two templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1) .NavigationProperty("NavProp1", /*url*/null).NavigationProperty("NavProp2", /*url*/null), ProjectionString = null, }, new ProjectionTestCase { DebugDescription = "No $select + one property in the payload => one templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1) .NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", /*url*/null), ProjectionString = null, }, new ProjectionTestCase { DebugDescription = "No $select + two properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1) .NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ProjectionString = null, }, #endregion No $select #region Empty $select new ProjectionTestCase { DebugDescription = "Empty $select => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ProjectionString = string.Empty, }, new ProjectionTestCase { DebugDescription = "Empty $select + one property in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1"), ProjectionString = string.Empty, }, new ProjectionTestCase { DebugDescription = "Empty $select + two properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ProjectionString = string.Empty, }, #endregion Empty $select #region $select=* new ProjectionTestCase { DebugDescription = "$select=* => two templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", /*url*/null).NavigationProperty("NavProp2", /*url*/null), ProjectionString = "*", }, new ProjectionTestCase { DebugDescription = "$select=* + one property in the payload => one templatized property.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2").NavigationProperty("NavProp1", /*url*/null), ProjectionString = "*", }, new ProjectionTestCase { DebugDescription = "$select=* + two properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ProjectionString = "*", }, #endregion $select=* #region $select=NavProp2,* new ProjectionTestCase { DebugDescription = "$select=NavProp2,* => two templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", /*url*/null).NavigationProperty("NavProp2", /*url*/null), ProjectionString = "NavProp2,*", }, new ProjectionTestCase { DebugDescription = "$select=NavProp2,* + NavProp2 property in the payload => one templatized property.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2").NavigationProperty("NavProp1", /*url*/null), ProjectionString = "NavProp2,*", }, new ProjectionTestCase { DebugDescription = "$select=NavProp2,* + NavProp1 property in the payload => one templatized property.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", /*url*/null), ProjectionString = "NavProp2,*", }, new ProjectionTestCase { DebugDescription = "$select=NavProp2,* + two properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ProjectionString = "NavProp2,*", }, #endregion $select=NavProp2,* #region $select=NavProp1,NavProp2 new ProjectionTestCase { DebugDescription = "$select=NavProp1,NavProp2 => two templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", /*url*/null).NavigationProperty("NavProp2", /*url*/null), ProjectionString = "NavProp1,NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=NavProp1,NavProp2 + NavProp2 property in the payload => one templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2").NavigationProperty("NavProp1", /*url*/null), ProjectionString = "NavProp1,NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=NavProp1,NavProp2 + two properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ProjectionString = "NavProp1,NavProp2", }, #endregion $select=NavProp1,NavProp2 #region $select=NavProp2 new ProjectionTestCase { DebugDescription = "$select=NavProp2 => one templatized property.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", /*url*/null), ProjectionString = "NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=NavProp2 + NavProp2 property in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", "http://odata.org/nav2"), ProjectionString = "NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=NavProp2 + NavProp1 property in the payload => one templatized property.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", /*url*/null), ProjectionString = "NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=NavProp2 + two properties in the payload => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", "http://odata.org/nav1").NavigationProperty("NavProp2", "http://odata.org/nav2"), ProjectionString = "NavProp2", }, #endregion $select=NavProp2 #region $select=NavProp1/* new ProjectionTestCase { DebugDescription = "$select=NavProp1/* => three templatized stream properties and and one templatized navigation.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2)), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).NavigationProperty("NavProp1", /*url*/null).NavigationProperty("NavProp2", /*url*/null)), ProjectionString = "NavProp1/*", }, #endregion $select=NavProp/* #region $select=NavProp1/NavProp1 new ProjectionTestCase { DebugDescription = "$select=NavProp1/NavProp1 => one templatized navigation property.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2)), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).NavigationProperty("NavProp1", /*url*/null)), ProjectionString = "NavProp1/NavProp1", }, new ProjectionTestCase { DebugDescription = "$select=NavProp1/NavProp1 with expand => two templatized navigation properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 3))), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 3).NavigationProperty("NavProp1", /*url*/null).NavigationProperty("NavProp2", /*url*/null))), ProjectionString = "NavProp1/NavProp1", }, #endregion $select=NavProp1/NavProp1 #region $select=TestModel.CityType/NavProp2 new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/NavProp2 on base type => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ProjectionString = "TestModel.CityType/NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/NavProp2 on derived type => specific property templatized.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp2", /*url*/null), ProjectionString = "TestModel.CityType/NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/NavProp2 on different derived type => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.DuplicateCityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.DuplicateCityType").PrimitiveProperty("Id", 1), ProjectionString = "TestModel.CityType/NavProp2", }, #endregion $select=TestModel.CityType/NavProp2 #region $select=TestModel.CityType/NavProp1 new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/NavProp1 on base type => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ProjectionString = "TestModel.CityType/NavProp1", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/NavProp1 on derived type => specific property templatized.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", /*url*/null), ProjectionString = "TestModel.CityType/NavProp1", }, #endregion $select=TestModel.CityType/NavProp1 #region $select=TestModel.TownType/NavProp1 new ProjectionTestCase { DebugDescription = "$select=TestModel.TownType/NavProp1 on base type => specific property templatized..", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", /*url*/null), ProjectionString = "TestModel.TownType/NavProp1", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.TownType/NavProp1 on derived type => specific property templatized.", PayloadEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1), ExpectedEntity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1).NavigationProperty("NavProp1", /*url*/null), ProjectionString = "TestModel.TownType/NavProp1", }, #endregion $select=TestModel.TownType/NavProp1 #region $select=NavProp1/TestModel.City/NavProp2 new ProjectionTestCase { DebugDescription = "$select=NavProp1/TestModel.TownType/NavProp2 on expanded base type => no templatized property.", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 2)), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 2)), ProjectionString = "NavProp1/TestModel.TownType/NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=NavProp1/TestModel.TownType/NavProp2 on expanded derived type type => specific templatized property.", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2)), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 2).NavigationProperty("NavProp2", /*url*/null)), ProjectionString = "NavProp1/TestModel.TownType/NavProp2", }, new ProjectionTestCase { DebugDescription = "$select=TestModel.CityType/* on different derived type => no templatized properties.", PayloadEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.DuplicateCityType").PrimitiveProperty("Id", 2)), ExpectedEntity = PayloadBuilder.Entity("TestModel.TownType").PrimitiveProperty("Id", 1).ExpandedNavigationProperty("NavProp1", PayloadBuilder.Entity("TestModel.DuplicateCityType").PrimitiveProperty("Id", 2)), ProjectionString = "TestModel.CityType/*", }, #endregion $select=NavProp1/TestModel.City/NavProp2 }; IEnumerable<PayloadReaderTestDescriptor> testDescriptors = testCases.Select(testCase => new PayloadReaderTestDescriptor(this.Settings) { DebugDescription = testCase.DebugDescription, PayloadEdmModel = model, PayloadElement = testCase.PayloadEntity .WithContextUriProjection(testCase.ProjectionString) .ExpectedEntityType(townType, townsSet), ExpectedResultPayloadElement = tc => testCase.ExpectedEntity, ExpectedException = testCase.ExpectedException, }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations.Where(tc => !tc.IsRequest), (testDescriptor, testConfiguration) => { // These descriptors are already tailored specifically for Json Light and // do not require normalization. testDescriptor.TestDescriptorNormalizers.Clear(); testDescriptor.RunTest(testConfiguration); }); }
/// <summary> /// Creates a feed containing entities of types that derive from the same base /// </summary> /// <param name="model">The entity model schema. The method will modify the model and call Fixup().</param> /// <param name="withTypeNames">True if the payloads should specify type names.</param> /// <returns>The feed containing derived typed entities.</returns> public static IEnumerable<Taupo.OData.Common.PayloadTestDescriptor> GetFeeds(EdmModel model, bool withTypeNames) { ExceptionUtilities.CheckArgumentNotNull(model, "model"); List<Taupo.OData.Common.PayloadTestDescriptor> payloads = new List<Taupo.OData.Common.PayloadTestDescriptor>(); EdmEntityType baseType = model.EntityType("MyBaseType").KeyProperty("Id", (EdmPrimitiveTypeReference) EdmCoreModel.Instance.GetGuid(false)); model.Fixup(); EntityInstance instance = PayloadBuilder.Entity(withTypeNames ? "TestModel." + baseType.Name : null).Property("Id", PayloadBuilder.PrimitiveValue(Guid.NewGuid())); instance.Id = "urn:id"; EntitySetInstance emptySet = PayloadBuilder.EntitySet().WithTypeAnnotation(baseType); payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = emptySet }); var emptySetWithInlineCount = emptySet.DeepCopy(); emptySetWithInlineCount.InlineCount = 0; // Inline count (note we skip for v1 and request because inline count is valid on response only on V2 and above. payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = emptySetWithInlineCount, SkipTestConfiguration = (tc => tc.IsRequest) }); var emptySetWithNextLinkAndCount = emptySet.DeepCopy(); emptySetWithNextLinkAndCount.InlineCount = 0; emptySetWithNextLinkAndCount.NextLink = "http://www.odata.org/Feed"; // inline count + next link payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = emptySetWithNextLinkAndCount, SkipTestConfiguration = (tc => tc.IsRequest) }); var emptySetWithNextLink = emptySet.DeepCopy(); emptySetWithNextLink.NextLink = "http://www.odata.org/Feed"; // next link payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = emptySetWithNextLink, SkipTestConfiguration = (tc => tc.IsRequest) }); EntitySetInstance singleEntity = PayloadBuilder.EntitySet().Append(instance).WithTypeAnnotation(baseType); payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = singleEntity.DeepCopy() }); var singleEntityWithInlineCount = singleEntity.DeepCopy(); singleEntityWithInlineCount.InlineCount = 1; // inline count payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = singleEntityWithInlineCount, SkipTestConfiguration = (tc => tc.IsRequest) }); var singleEntityWithNextLinkAndCount = singleEntity.DeepCopy(); singleEntityWithInlineCount.InlineCount = 1; singleEntityWithNextLinkAndCount.NextLink = "http://www.odata.org/Feed"; // inline count + next link payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = singleEntityWithNextLinkAndCount, SkipTestConfiguration = (tc => tc.IsRequest) }); var singleEntityWithNextLink = singleEntity.DeepCopy(); singleEntityWithNextLink.NextLink = "http://www.odata.org/Feed"; // next link payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = singleEntityWithNextLink, SkipTestConfiguration = (tc => tc.IsRequest) }); EntitySetInstance multipleEntity = PayloadBuilder.EntitySet().Append(instance.GenerateSimilarEntries(3)).WithTypeAnnotation(baseType); payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = multipleEntity }); var multipleEntityWithInlineCount = multipleEntity.DeepCopy(); multipleEntityWithInlineCount.InlineCount = 3; // inline count payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = multipleEntityWithInlineCount, SkipTestConfiguration = (tc => tc.IsRequest) }); var multipleEntityWithNextLinkAndCount = multipleEntity.DeepCopy(); multipleEntityWithNextLinkAndCount.InlineCount = 3; multipleEntityWithNextLinkAndCount.NextLink = "http://www.odata.org/Feed"; // inline count + next link payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = multipleEntityWithNextLinkAndCount, SkipTestConfiguration = (tc => tc.IsRequest) }); var multipleEntityWithNextLink = multipleEntity.DeepCopy(); multipleEntityWithNextLink.NextLink = "http://www.odata.org/Feed"; // next link payloads.Add(new Taupo.OData.Common.PayloadTestDescriptor() { PayloadEdmModel = model, PayloadElement = multipleEntityWithNextLink, SkipTestConfiguration = (tc => tc.IsRequest) }); return payloads; }
public void ComplexValueWithMetadataTest() { // Use some standard complex value payloads first IEnumerable<PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, true); // Add metadata validation tests EdmModel model = new EdmModel(); var innerComplexType = model.ComplexType("InnerComplexType"); innerComplexType.AddStructuralProperty("name", EdmCoreModel.Instance.GetString(true)); var complexType = model.ComplexType("ComplexType"); complexType.AddStructuralProperty("number", EdmPrimitiveTypeKind.Int32); complexType.AddStructuralProperty("string", EdmCoreModel.Instance.GetString(true)); complexType.AddStructuralProperty("complex", MetadataUtils.ToTypeReference(innerComplexType, true)); var entityType = model.EntityType("EntityType"); entityType.KeyProperty("Id", EdmCoreModel.Instance.GetInt32(false)); model.Fixup(); // Test that different types of properties not present in the metadata all fail IEnumerable<PropertyInstance> undeclaredPropertyTestCases = new PropertyInstance[] { PayloadBuilder.PrimitiveProperty("undeclared", 42), PayloadBuilder.Property("undeclared", PayloadBuilder.ComplexValue(innerComplexType.FullName())), PayloadBuilder.Property("undeclared", PayloadBuilder.PrimitiveMultiValue(EntityModelUtils.GetCollectionTypeName("Edm.Int32"))), PayloadBuilder.Property("undeclared", PayloadBuilder.ComplexMultiValue(EntityModelUtils.GetCollectionTypeName("TestModel.InnerComplexType"))), }; testDescriptors = testDescriptors.Concat( undeclaredPropertyTestCases.Select(tc => { return new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType) .Property(tc), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", "undeclared", "TestModel.ComplexType"), }; })); testDescriptors = testDescriptors.Concat(new[] { // Property which should take typename not from value but from the parent metadata new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType) .Property("complex", PayloadBuilder.ComplexValue(innerComplexType.FullName()).PrimitiveProperty("name", null) .JsonRepresentation("{ \"name\" : null }").XmlRepresentation("<d:name m:null=\"true\" />") .AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null })), PayloadEdmModel = model, }, // Property which is declared in the metadata but with a different type new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType) .Property("complex", PayloadBuilder.ComplexValue(complexType.FullName())), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncompatibleType", "TestModel.ComplexType", "TestModel.InnerComplexType"), }, // Property which is declared in the metadata but with a wrong kind new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue(complexType.FullName()).WithTypeAnnotation(complexType) .Property("complex", PayloadBuilder.ComplexValue(entityType.FullName())), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_IncorrectTypeKind", "TestModel.EntityType", "Complex", "Entity"), }, new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue("").WithTypeAnnotation(complexType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", string.Empty) }, new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue("TestModel.NonExistant").WithTypeAnnotation(complexType), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "TestModel.NonExistant"), }, }); // Wrap the complex type in a property testDescriptors = testDescriptors .Select((td, index) => new PayloadReaderTestDescriptor(td) { PayloadDescriptor = td.PayloadDescriptor.InProperty("propertyName" + index)}) .SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td)); // Handcrafted cases testDescriptors = testDescriptors.Concat(new[] { // Top-level complex property without expected type new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Property("property", PayloadBuilder.ComplexValue(complexType.FullName()).PrimitiveProperty("number", 42)), PayloadEdmModel = model }, }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations, (testDescriptor, testConfiguration) => { var property = testDescriptor.PayloadElement as PropertyInstance; if (property != null && testConfiguration.Format == ODataFormat.Atom) { property.Name = null; } testDescriptor.RunTest(testConfiguration); }); }
public void ComplexValueIgnorePropertyNullValuesTest() { var versions = new Version[] { null, new Version(4, 0), }; EdmModel edmModel = new EdmModel(); IEdmComplexType countryRegionType = edmModel.ComplexType("CountryRegion") .Property("Name", EdmPrimitiveTypeKind.String) .Property("CountryRegionCode", EdmPrimitiveTypeKind.String); IEdmComplexType countryRegionNullType = edmModel.ComplexType("CountryRegionNull") .Property("Name", EdmPrimitiveTypeKind.String) .Property("CountryRegionCode", EdmPrimitiveTypeKind.String); IEdmComplexType addressType = edmModel.ComplexType("Address") .Property("Street", EdmPrimitiveTypeKind.String) .Property("StreetNull", EdmCoreModel.Instance.GetString(true) as EdmTypeReference) .Property("Numbers", EdmCoreModel.GetCollection(EdmCoreModel.Instance.GetInt32(false)) as EdmTypeReference) .Property("CountryRegion", new EdmComplexTypeReference(countryRegionType, false)) .Property("CountryRegionNull", new EdmComplexTypeReference(countryRegionNullType, true)); edmModel.EntityType("Customer") .KeyProperty("ID", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference) .Property("Address", new EdmComplexTypeReference(addressType, false)); edmModel.Fixup(); this.CombinatorialEngineProvider.RunCombinations( new ODataNullValueBehaviorKind[] { ODataNullValueBehaviorKind.Default, ODataNullValueBehaviorKind.DisableValidation, ODataNullValueBehaviorKind.IgnoreValue }, versions, versions, TestReaderUtils.ODataBehaviorKinds, (nullPropertyValueReaderBehavior, dataServiceVersion, edmVersion, behaviorKind) => { edmModel.SetEdmVersion(edmVersion); // Now we set the 'IgnoreNullValues' annotation on all properties IEdmComplexType edmAddressType = (IEdmComplexType)edmModel.FindType("TestModel.Address"); foreach (IEdmStructuralProperty edmProperty in edmAddressType.StructuralProperties()) { edmModel.SetNullValueReaderBehavior(edmProperty, nullPropertyValueReaderBehavior); } EntityInstance customerPayload = PayloadBuilder.Entity("TestModel.Customer") .PrimitiveProperty("ID", 1) .Property("Address", PayloadBuilder.ComplexValue("TestModel.Address") .PrimitiveProperty("Street", "One Microsoft Way") .PrimitiveProperty("StreetNull", "One Microsoft Way") .Property("Numbers", PayloadBuilder.PrimitiveMultiValue("Collection(Edm.Int32)").Item(1).Item(2)) .Property("CountryRegion", PayloadBuilder.ComplexValue("TestModel.CountryRegion") .PrimitiveProperty("Name", "Austria") .PrimitiveProperty("CountryRegionCode", "AUT")) .Property("CountryRegionNull", PayloadBuilder.ComplexValue("TestModel.CountryRegionNull") .PrimitiveProperty("Name", "Austria") .PrimitiveProperty("CountryRegionCode", "AUT"))); var testCases = new[] { // Complex types that are not nullable should not allow null values. // Null primitive property in the payload and non-nullable property in the model new IgnoreNullValueTestCase { PropertyName = "Street", ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "Street", "Edm.String"), }, // Null complex property in the payload and non-nullable property in the model new IgnoreNullValueTestCase { PropertyName = "CountryRegion", ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "CountryRegion", "TestModel.CountryRegion"), }, // Null collection property in the payload and non-nullable property in the model new IgnoreNullValueTestCase { PropertyName = "Numbers", ExpectedResponseException = ODataExpectedExceptions.ODataException("ReaderValidationUtils_NullNamedValueForNonNullableType", "Numbers", "Collection(Edm.Int32)"), }, // Complex types that are nullable should allow null values. // Null primitive property in the payload and nullable property in the model new IgnoreNullValueTestCase { PropertyName = "StreetNull", }, // Null complex property in the payload and nullable property in the model new IgnoreNullValueTestCase { PropertyName = "CountryRegionNull", }, }; Func<IgnoreNullValueTestCase, ReaderTestConfiguration, PayloadReaderTestDescriptor> createTestDescriptor = (testCase, testConfig) => { EntityInstance payloadValue = customerPayload.DeepCopy(); ComplexInstance payloadAddressValue = ((ComplexProperty)payloadValue.GetProperty("Address")).Value; SetToNull(payloadAddressValue, testCase.PropertyName); ComplexInstance resultValue = payloadValue; if (testConfig.IsRequest && nullPropertyValueReaderBehavior == ODataNullValueBehaviorKind.IgnoreValue) { resultValue = customerPayload.DeepCopy(); ComplexInstance resultAddressValue = ((ComplexProperty)resultValue.GetProperty("Address")).Value; resultAddressValue.Remove(resultAddressValue.GetProperty(testCase.PropertyName)); } return new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = payloadValue, PayloadEdmModel = edmModel, ExpectedResultPayloadElement = tc => { if (tc.Format == ODataFormat.Json) { // under the client knob ODL will compute edit links, ids, etc // so we need to update the expected payload if (tc.RunBehaviorKind == TestODataBehaviorKind.WcfDataServicesClient) { var entity = resultValue as EntityInstance; if (entity != null) { if (!tc.IsRequest) { entity.Id = "http://odata.org/test/Customer(1)"; entity.EditLink = "http://odata.org/test/Customer(1)"; entity.WithSelfLink("http://odata.org/test/Customer(1)"); } } } var tempDescriptor = new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = resultValue, PayloadEdmModel = edmModel, }; JsonLightPayloadElementFixup.Fixup(tempDescriptor); return tempDescriptor.PayloadElement; } return resultValue; }, ExpectedException = (testConfig.IsRequest && nullPropertyValueReaderBehavior != ODataNullValueBehaviorKind.Default) ? null : testCase.ExpectedResponseException }; }; this.CombinatorialEngineProvider.RunCombinations( testCases, this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations, (testCase, testConfiguration) => { testConfiguration = testConfiguration.CloneAndApplyBehavior(behaviorKind); testConfiguration.MessageReaderSettings.BaseUri = null; PayloadReaderTestDescriptor testDescriptor = createTestDescriptor(testCase, testConfiguration); testDescriptor.RunTest(testConfiguration); }); }); }
public void BatchReaderMixedEncodingTest() { EdmModel model = new EdmModel(); EdmEntityType personType = model.EntityType("Person") .KeyProperty("Id", EdmCoreModel.Instance.GetInt32(false) as EdmTypeReference) .Property("Name", EdmPrimitiveTypeKind.String, isNullable: true); model.Fixup(); EdmEntitySet personSet = model.EntitySet("Person", personType); EntityInstance personInstance = PayloadBuilder.Entity("TestModel.Person") .Property("Id", PayloadBuilder.PrimitiveValue(1)) .Property("Name", PayloadBuilder.PrimitiveValue("Mr Foo Baz")); ODataUriSegment root = ODataUriBuilder.Root(new Uri("http://www.odata.org")); ODataUri testUri = new ODataUri(root, ODataUriBuilder.EntitySet(personSet)); Encoding[] encodings = new Encoding[] { Encoding.UTF8, Encoding.BigEndianUnicode, Encoding.Unicode }; IEnumerable<BatchReaderMixedEncodingTestCase> testCases = encodings.SelectMany(batchEncoding => encodings.Select(changesetEncoding => new BatchReaderMixedEncodingTestCase { BatchEncoding = batchEncoding, Changesets = new[] { new BatchReaderMixedEncodingChangeset { ChangesetEncoding = changesetEncoding, Operations = new[] { new BatchReaderMixedEncodingOperation { OperationEncoding = Encoding.Unicode, PayloadFormat = ODataFormat.Atom, }, new BatchReaderMixedEncodingOperation { // Uses changeset's encoding PayloadFormat = ODataFormat.Atom, }, }, }, new BatchReaderMixedEncodingChangeset { Operations = new[] { new BatchReaderMixedEncodingOperation { // Uses batch's encoding OperationEncoding = batchEncoding, PayloadFormat = ODataFormat.Atom, }, }, }, }, } )); this.CombinatorialEngineProvider.RunCombinations( testCases, this.ReaderTestConfigurationProvider.DefaultFormatConfigurations, (testCase, testConfiguration) => { var testPayload = personInstance.DeepCopy(); if (!testConfiguration.IsRequest) { testPayload.AddAnnotation(new PayloadFormatVersionAnnotation() { Response = true, ResponseWrapper = true }); } var testDescriptor = this.CreateTestDescriptor(testCase, testPayload, testUri, testConfiguration.IsRequest); testDescriptor.PayloadEdmModel = model; testDescriptor.RunTest(testConfiguration); }); }
public void OpenPropertiesTest() { // Interesting values to test as open properties. // Only test complex and collection values here, since open primitive properties rely on format specific primitive type support. // The open primitive properties tests are thus format specific and are here: // JSON - PrimitiveValueReaderJsonTests.UntypedPrimitiveValueTest // ATOM - PrimitiveValueReaderAtomTests.PrimitiveValueWithoutType IEnumerable<PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, true, false); // Add spatial open property tests testDescriptors = testDescriptors.Concat(new[] { new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveValue(GeographyFactory.Point(10, 20, 30, 40).Build()) }, new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.PrimitiveValue(GeometryFactory.Point(10, 20, 30, 40).Build()) } }); // Add couple of hand-crafted payloads testDescriptors = testDescriptors.Concat(new[] { // Open complex value with undeclared type - must fail new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue("TestModel.NonExistantType"), ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_UnrecognizedTypeName", "TestModel.NonExistantType"), }, // Open complex null value new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.ComplexValue("TestModel.NonEmptyComplexType", true), }, }); testDescriptors = testDescriptors // Wrap the property in an open entity .Select(td => { EdmModel model = (EdmModel)td.PayloadEdmModel; model = model == null ? new EdmModel() : (EdmModel)Test.OData.Utils.Metadata.MetadataUtils.Clone(model); var entityType = model.EntityType("OpenEntityType", "TestModel", null, false, true); entityType.AddKeys(entityType.AddStructuralProperty("ID", EdmPrimitiveTypeKind.Int32)); entityType.AddStructuralProperty("DateTimeProperty", EdmPrimitiveTypeKind.DateTimeOffset); var complexType = model.ComplexType("NonEmptyComplexType"); complexType.AddStructuralProperty("P1", EdmPrimitiveTypeKind.Int32); complexType.AddStructuralProperty("P2", EdmCoreModel.Instance.GetString(true)); model = model.Fixup(); return new PayloadReaderTestDescriptor(td) { PayloadElement = PayloadBuilder.Entity("TestModel.OpenEntityType") .PrimitiveProperty("ID", 42) .Property("OpenProperty", td.PayloadElement), PayloadEdmModel = model }; }); // Add a couple of hand crafted payloads { EdmModel model = new EdmModel(); var entityType = model.EntityType("OpenEntityType", null, null, false, true); entityType.KeyProperty("ID", EdmCoreModel.Instance.GetInt32(false)); model = model.Fixup(); testDescriptors = testDescriptors.Concat(new PayloadReaderTestDescriptor[] { // Open stream property is not allowed. new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.OpenEntityType").PrimitiveProperty("ID", 42) .StreamProperty("OpenProperty", "http://odata.org/readlink"), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_OpenStreamProperty", "OpenProperty"), // TODO: In JSON we recognize this as a complex property - once we make a decision about the bug enable the test for JSON. SkipTestConfiguration = tc => tc.Format != ODataFormat.Atom || tc.IsRequest }, // Open deferred navigation property is not allowed. new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.OpenEntityType").PrimitiveProperty("ID", 42) .NavigationProperty("OpenProperty", "http://odata.org/navprop"), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_OpenNavigationProperty", "OpenProperty", "TestModel.OpenEntityType"), // TODO: In JSON we recognize this as a complex property - once we make a decision about the bug enable the test for JSON. SkipTestConfiguration = tc => tc.Format != ODataFormat.Atom }, // Open expanded navigation property (entry) is not allowed. new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.OpenEntityType").PrimitiveProperty("ID", 42) .ExpandedNavigationProperty("OpenProperty", PayloadBuilder.Entity("TestModel.OpenEntityType")), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_OpenNavigationProperty", "OpenProperty", "TestModel.OpenEntityType"), // This can't work in JSON as it is recognized as a complex value - and will fail for different reasons SkipTestConfiguration = tc => tc.Format != ODataFormat.Atom }, // Open expanded navigation property (feed) is not allowed. new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.OpenEntityType").PrimitiveProperty("ID", 42) .ExpandedNavigationProperty("OpenProperty", PayloadBuilder.EntitySet()), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("ValidationUtils_OpenNavigationProperty", "OpenProperty", "TestModel.OpenEntityType"), // This can't work in JSON as it may be recognized as a complex value - and will fail for different reasons SkipTestConfiguration = tc => tc.Format != ODataFormat.Atom }, // Open property with same name as non-open property new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.OpenEntityType").PrimitiveProperty("ID", 42).PrimitiveProperty("DateTimeProperty", new DateTimeOffset(DateTime.Now)) .PrimitiveProperty("DateTimeProperty", new DateTimeOffset(DateTime.Now.AddDays(1.0))), PayloadEdmModel = model, ExpectedException = ODataExpectedExceptions.ODataException("DuplicatePropertyNamesChecker_DuplicatePropertyNamesNotAllowed", "DateTimeProperty"), // In JSON Light this fails for different reasons, related to missing/multiple type annotations (depending on how it is serialised) SkipTestConfiguration = tc => tc.Format == ODataFormat.Json, }, }); } testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td)); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations, (testDescriptor, testConfiguration) => { testDescriptor.RunTest(testConfiguration); }); }
public static ODataProperty[] CreateDefaultCollectionProperties(EdmModel model = null) { if (model != null) { var addressType = model.ComplexType("AddressType", "My") .Property("Street", EdmPrimitiveTypeKind.String) .Property("City", EdmPrimitiveTypeKind.String); model.EntityType("EntryWithCollectionProperties", "TestModel") .Property("EmptyCollection", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetString(false)))) .Property("PrimitiveCollection", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetInt32(false)))) .Property("IntCollectionNoTypeName", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetInt32(false)))) .Property("StringCollectionNoTypeName", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetString(false)))) .Property("GeographyCollectionNoTypeName", new EdmCollectionTypeReference(new EdmCollectionType(EdmCoreModel.Instance.GetSpatial(EdmPrimitiveTypeKind.Geography, false)))) .Property("ComplexCollection", new EdmCollectionTypeReference(new EdmCollectionType(new EdmComplexTypeReference(addressType, true)))); } return new ODataProperty[] { new ODataProperty { Name = "EmptyCollection", Value = new ODataCollectionValue() { TypeName = EntityModelUtils.GetCollectionTypeName("Edm.String"), } }, new ODataProperty { Name = "PrimitiveCollection", Value = new ODataCollectionValue() { TypeName = EntityModelUtils.GetCollectionTypeName("Edm.Int32"), Items = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } } }, new ODataProperty { Name = "IntCollectionNoTypeName", Value = new ODataCollectionValue() { TypeName = EntityModelUtils.GetCollectionTypeName("Edm.Int32"), Items = new int[] { 0, 1, 2 } } }, new ODataProperty { Name = "StringCollectionNoTypeName", Value = new ODataCollectionValue() { TypeName = EntityModelUtils.GetCollectionTypeName("Edm.String"), Items = new string[] { "One", "Two", "Three" } } }, new ODataProperty { Name = "GeographyCollectionNoTypeName", Value = new ODataCollectionValue() { TypeName = EntityModelUtils.GetCollectionTypeName("Edm.Geography"), Items = new object[] { ObjectModelUtils.GeographyCollectionValue, ObjectModelUtils.GeographyLineStringValue, ObjectModelUtils.GeographyMultiLineStringValue, ObjectModelUtils.GeographyMultiPointValue, ObjectModelUtils.GeographyMultiPolygonValue, ObjectModelUtils.GeographyPointValue, ObjectModelUtils.GeographyPolygonValue, ObjectModelUtils.GeographyValue } } }, new ODataProperty { Name = "ComplexCollection", Value = new ODataCollectionValue() { TypeName = EntityModelUtils.GetCollectionTypeName("My.AddressType"), Items = new [] { new ODataComplexValue() { TypeName = "My.AddressType", Properties = new [] { new ODataProperty() { Name = "Street", Value = "One Redmond Way" }, new ODataProperty() { Name = "City", Value = " Redmond" }, } }, new ODataComplexValue() { TypeName = null, Properties = new [] { new ODataProperty() { Name = "Street", Value = "Am Euro Platz 3" }, new ODataProperty() { Name = "City", Value = "Vienna " }, } } } } }, }; }
public static ODataProperty[] CreateDefaultComplexProperties(EdmModel model = null) { if (model != null) { var addressType = model.ComplexType("AddressType", "My") .Property("Street", EdmPrimitiveTypeKind.String) .Property("City", EdmPrimitiveTypeKind.String); var streetType = model.ComplexType("StreetType", "My") .Property("StreetName", EdmPrimitiveTypeKind.String) .Property("Number", EdmPrimitiveTypeKind.Int32); var nestedAddressType = model.ComplexType("NestedAddressType", "My") .Property("Street", new EdmComplexTypeReference(streetType, true)) .Property("City", EdmPrimitiveTypeKind.String); model.EntityType("EntryWithComplexProperties", "TestModel") .Property("ComplexAddress", new EdmComplexTypeReference(addressType, true)) .Property("NestedComplex", new EdmComplexTypeReference(nestedAddressType, true)); } return new ODataProperty[] { new ODataProperty() { Name = "ComplexAddress", Value = new ODataComplexValue() { TypeName = "My.AddressType", Properties = new [] { new ODataProperty() { Name = "Street", Value = "One Redmond Way" }, new ODataProperty() { Name = "City", Value = " Redmond" }, } } }, new ODataProperty() { Name = "NestedComplex", Value = new ODataComplexValue() { TypeName = "My.NestedAddressType", Properties = new [] { new ODataProperty() { Name = "Street", Value = new ODataComplexValue() { TypeName = "My.StreetType", Properties = new [] { new ODataProperty { Name = "StreetName", Value = "One Redmond Way" }, new ODataProperty { Name = "Number", Value = 1234 }, } } }, new ODataProperty() { Name = "City", Value = "Redmond " }, } } }, }; }
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; }