private IEnumerable <PayloadReaderTestDescriptor> CreateCollectionPayloadsWithMetadata(bool withTypeNames) { // Start with the standard set of collections IEnumerable <PayloadReaderTestDescriptor> testDescriptors = PayloadReaderTestDescriptorGenerator.CreateCollectionTestDescriptors(this.Settings, withTypeNames); // Add collections with all of the primitive values (except null) testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreatePrimitiveValueTestDescriptors(this.Settings, false) .Where(primitivePayload => ((PrimitiveValue)primitivePayload.PayloadElement).ClrValue != null) .Select(primitivePayload => { IEdmTypeReference edmType = primitivePayload.PayloadElement.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType; var primitiveCollection = PayloadBuilder.PrimitiveMultiValue(withTypeNames ? EntityModelUtils.GetCollectionTypeName(edmType.FullName()) : null) .Item(((PrimitiveValue)primitivePayload.PayloadElement).ClrValue) .WithTypeAnnotation(EdmCoreModel.GetCollection(edmType)); if (!withTypeNames) { primitiveCollection.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }); } return(new PayloadReaderTestDescriptor(primitivePayload) { PayloadElement = primitiveCollection, }); })); // Add collections with all of the complex values (except null) testDescriptors = testDescriptors.Concat(PayloadReaderTestDescriptorGenerator.CreateComplexValueTestDescriptors(this.Settings, withTypeNames, false) .Where(complexPayload => !((ComplexInstance)complexPayload.PayloadElement).IsNull) .Select(complexPayload => { IEdmTypeReference edmComplexType = complexPayload.PayloadElement.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType; var complexCollection = PayloadBuilder.ComplexMultiValue(withTypeNames ? EntityModelUtils.GetCollectionTypeName(edmComplexType.FullName()) : null) .Item((ComplexInstance)complexPayload.PayloadElement) .WithTypeAnnotation(EdmCoreModel.GetCollection(edmComplexType)); if (!withTypeNames) { complexCollection.AddAnnotation(new SerializationTypeNameTestAnnotation() { TypeName = null }); } return(new PayloadReaderTestDescriptor(complexPayload) { PayloadElement = complexCollection, }); })); return(testDescriptors); }
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.Json ? ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_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; testDescriptor.RunTest(testConfiguration); }); }
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); }); }