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); }); }