public PayloadReaderTestDescriptor ToTestDescriptor(PayloadReaderTestDescriptor.Settings settings, IEdmModel model, bool withMetadataAnnotation = false) { IEdmEntityContainer container = model.FindEntityContainer("DefaultContainer"); IEdmEntitySet citiesEntitySet = container.FindEntitySet("Cities"); IEdmType cityType = model.FindType("TestModel.CityType"); EntityInstance entity = PayloadBuilder.Entity("TestModel.CityType") .ExpectedEntityType(cityType, citiesEntitySet) .JsonRepresentation( "{" + (withMetadataAnnotation ? ("\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://http://odata.org/test/$metadata#DefaultContainer.Cities/$entity\",") : string.Empty) + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.CityType\"," + this.Json + ",\"Id\":1" + "}"); foreach (PropertyInstance property in this.ExpectedEntity.Properties) { entity.Add(property.DeepCopy()); } entity.Add(PayloadBuilder.PrimitiveProperty("Id", 1)); return(new NavigationLinkTestCaseDescriptor(settings) { DebugDescription = this.DebugDescription, PayloadElement = entity, PayloadEdmModel = model, ExpectedException = this.ExpectedException, ExpectedIsCollectionValues = this.ExpectedIsCollectionValues, }); }
public PayloadReaderTestDescriptor ToTestDescriptor(PayloadReaderTestDescriptor.Settings settings, IEdmModel model, bool throwOnUndeclaredPropertyForNonOpenType) { var cityType = model.FindDeclaredType("TestModel.CityType").ToTypeReference(); var cities = model.EntityContainer.FindEntitySet("Cities"); EntityInstance entity = PayloadBuilder.Entity("TestModel.CityType").PrimitiveProperty("Id", 1) .ExpectedEntityType(cityType, cities) .JsonRepresentation( "{" + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities()/$entity\"," + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"TestModel.CityType\"," + "\"Id\":1," + this.Json + "}"); foreach (PropertyInstance property in this.ExpectedEntity.Properties) { entity.Add(property.DeepCopy()); } ExpectedException expectedException = this.ExpectedException; if (throwOnUndeclaredPropertyForNonOpenType) { expectedException = ODataExpectedExceptions.ODataException("ValidationUtils_PropertyDoesNotExistOnType", "UndeclaredProperty", "TestModel.CityType"); } return new PayloadReaderTestDescriptor(settings) { DebugDescription = this.DebugDescription, PayloadElement = entity, PayloadEdmModel = model, ExpectedException = expectedException }; }
private void AddFoldedLinksToEntityInsertPayload(DataServiceContextData contextData, EntityDescriptorData entityDescriptorData, EntityInstance payload) { var entityType = this.ModelSchema.EntityTypes.Single(t => t.FullName == entityDescriptorData.EntityClrType.FullName); foreach (var linkDescriptor in contextData.LinkDescriptorsData.Where(l => l.SourceDescriptor == entityDescriptorData)) { if (linkDescriptor.TargetDescriptor.State == EntityStates.Added) { continue; } var navigationProperty = entityType.AllNavigationProperties.Single(n => n.Name == linkDescriptor.SourcePropertyName); string contentType = MimeTypes.ApplicationAtomXml + ";type="; if (navigationProperty.ToAssociationEnd.Multiplicity == EndMultiplicity.Many) { contentType += "feed"; } else { contentType += "entry"; } // note: the edit-link is used rather than identity because the server needs to be able to query for the target entity // and the identity may not be an actual uri var link = new DeferredLink() { UriString = linkDescriptor.TargetDescriptor.EditLink.OriginalString } .WithContentType(contentType).WithTitleAttribute(linkDescriptor.SourcePropertyName); payload.Add(new NavigationPropertyInstance(linkDescriptor.SourcePropertyName, link)); } }
private void RunStreamPropertyTest(IEdmModel model, IEnumerable <StreamPropertyTestCase> testCases) { var cityType = model.FindDeclaredType("TestModel.CityType").ToTypeReference(); var cities = model.EntityContainer.FindEntitySet("Cities"); IEnumerable <PayloadReaderTestDescriptor> testDescriptors = testCases.Select(testCase => { IEdmTypeReference entityType = testCase.OwningEntityType ?? cityType; EntityInstance entity = PayloadBuilder.Entity(entityType.FullName()).PrimitiveProperty("Id", 1) .JsonRepresentation( "{" + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataContextAnnotationName + "\":\"http://odata.org/test/$metadata#TestModel.DefaultContainer.Cities/" + entityType.FullName() + "()/$entity\"," + "\"" + JsonLightConstants.ODataPropertyAnnotationSeparator + JsonLightConstants.ODataTypeAnnotationName + "\":\"" + entityType.FullName() + "\"," + "\"Id\": 1," + testCase.Json + "}") .ExpectedEntityType(entityType, cities); foreach (NamedStreamInstance streamProperty in testCase.ExpectedEntity.Properties.OfType <NamedStreamInstance>()) { entity.Add(streamProperty.DeepCopy()); } return(new PayloadReaderTestDescriptor(this.Settings) { DebugDescription = testCase.DebugDescription, PayloadEdmModel = model, PayloadElement = entity, ExpectedException = testCase.ExpectedException, SkipTestConfiguration = tc => testCase.OnlyResponse ? tc.IsRequest : false, InvalidOnRequest = testCase.InvalidOnRequest }); }); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, this.ReaderTestConfigurationProvider.JsonLightFormatConfigurations, (testDescriptor, testConfiguration) => { if (testConfiguration.IsRequest && testDescriptor.InvalidOnRequest) { testDescriptor = new PayloadReaderTestDescriptor(testDescriptor) { ExpectedException = ODataExpectedExceptions.ODataException("ODataJsonLightResourceDeserializer_StreamPropertyInRequest") }; } // These descriptors are already tailored specifically for Json Light and // do not require normalization. testDescriptor.TestDescriptorNormalizers.Clear(); var testConfigClone = new ReaderTestConfiguration(testConfiguration); testConfigClone.MessageReaderSettings.BaseUri = null; testDescriptor.RunTest(testConfigClone); }); }
public void ODataOperationReadTest() { EntityInstance entryWithOperations = PayloadBuilder.Entity(); entryWithOperations.Add(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/operationMetadata", Title = "operation title", Target = "http://odata.org/operationTarget" }); entryWithOperations.Add(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/operationMetadata", Title = "operation title", Target = "http://odata.org/operationTarget" }); var validCases = new[] { new { // action and function in atom namespace payloadElement = PayloadBuilder.Entity(), Xml = "<$operation metadata='http://odata.org/operationMetadata' title='operation title' target='http://odata.org/operationTarget'/>" }, new { // action and function with additional attributes payloadElement = entryWithOperations, Xml = "<m:$operation metadata='http://odata.org/operationMetadata' title='operation title' target='http://odata.org/operationTarget' nonamespace='nonsattribute' m:random='random'/>" }, new { // action and function with content payloadElement = entryWithOperations, Xml = "<m:$operation metadata='http://odata.org/operationMetadata' title='operation title' target='http://odata.org/operationTarget'><randomElement/> random text</m:$operation>" }, new { // action and function with additional attributes in with the same local name but in a different namespace payloadElement = entryWithOperations, Xml = @"<m:$operation metadata='http://odata.org/operationMetadata' title='operation title' target='http://odata.org/operationTarget' m:rel='ignored' m:target='ignored' m:title='ignored' m:metadata='ignored' />" }, new { // action and function after extra XML element payloadElement = entryWithOperations, Xml = "<randomElement>SomeText</randomElement><m:$operation metadata='http://odata.org/operationMetadata' title='operation title' target='http://odata.org/operationTarget' />" }, new { // action and function before extra XML element payloadElement = entryWithOperations, Xml = "<m:$operation metadata='http://odata.org/operationMetadata' title='operation title' target='http://odata.org/operationTarget' /><randomElement>SomeText</randomElement>" } }; var errorCases = new[] { new OperationReaderErrorTestCase { Xml = "<m:$operation/>", GetExpectedException = (arg) => ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_OperationMissingMetadataAttribute", arg), }, new OperationReaderErrorTestCase { Xml = "<m:$operation target='http://odata.org'/>", GetExpectedException = (arg) => ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_OperationMissingMetadataAttribute", arg), }, new OperationReaderErrorTestCase { Xml = "<m:$operation m:metadata='/operationMetadata' target='http://odata.org'/>", GetExpectedException = (arg) => ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_OperationMissingMetadataAttribute", arg), }, new OperationReaderErrorTestCase { Xml = "<m:$operation metadata='/operationMetadata'/>", GetExpectedException = (arg) => ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_OperationMissingTargetAttribute", arg), }, new OperationReaderErrorTestCase { Xml = "<m:$operation metadata='/operationMetadata' m:target='random text'/>", GetExpectedException = (arg) => ODataExpectedExceptions.ODataException("ODataAtomEntryAndFeedDeserializer_OperationMissingTargetAttribute", arg), }, }; IEnumerable <PayloadReaderTestDescriptor> testDescriptors = validCases.Select( vc => new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = vc.payloadElement.DeepCopy() .XmlRepresentation("<entry xmlns:m='http://docs.oasis-open.org/odata/ns/metadata'>" + vc.Xml.Replace("$operation", "action") + vc.Xml.Replace("$operation", "function") + "</entry>") }) .Concat(errorCases.Select( // concat error cases for m:action ec => new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity() .XmlRepresentation("<entry>" + ec.Xml.Replace("$operation", "action") + "</entry>"), ExpectedException = ec.GetExpectedException("action"), })) .Concat(errorCases.Select( // concat error cases for m:function ec => new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity() .XmlRepresentation("<entry>" + ec.Xml.Replace("$operation", "function") + "</entry>"), ExpectedException = ec.GetExpectedException("function"), })); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, ODataVersionUtils.AllSupportedVersions, this.ReaderTestConfigurationProvider.AtomFormatConfigurations, (testDescriptor, maxProtocolVersion, testConfiguration) => { if (maxProtocolVersion < testConfiguration.Version) { // This would fail anyway (no need to test it). return; } if (testConfiguration.IsRequest) { testDescriptor = new PayloadReaderTestDescriptor(testDescriptor); testDescriptor.ExpectedException = null; testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize); } testDescriptor.RunTest(testConfiguration.CloneAndApplyMaxProtocolVersion(maxProtocolVersion)); }); }
/// <summary> /// Visits an entry item. /// </summary> /// <param name="entry">The entry to visit.</param> protected override ODataPayloadElement VisitEntry(ODataResource entry) { ExceptionUtilities.CheckArgumentNotNull(entry, "entry"); EntityInstance entity = new EntityInstance(entry.TypeName, false); if (this.payloadContainsIdentityMetadata) { entity.Id = entry.Id == null ? null : entry.Id.OriginalString; if (entry.ReadLink != null) { entity.WithSelfLink(entry.ReadLink.OriginalString); } if (entry.EditLink != null) { entity.WithEditLink(entry.EditLink.OriginalString); } } if (this.payloadContainsEtagPropertiesForType(entry.TypeName)) { entity.ETag = entry.ETag; } ODataStreamReferenceValue mediaResource = entry.MediaResource; if (mediaResource != null) { entity = entity.AsMediaLinkEntry(); NamedStreamInstance namedStreamInstance = (NamedStreamInstance)this.Visit(mediaResource); entity.StreamETag = namedStreamInstance.ETag; entity.StreamSourceLink = namedStreamInstance.SourceLink; entity.StreamEditLink = namedStreamInstance.EditLink; entity.StreamContentType = namedStreamInstance.SourceLinkContentType ?? namedStreamInstance.EditLinkContentType; foreach (var namedStreamAtomLinkMetadataAnnotation in namedStreamInstance.Annotations.OfType <NamedStreamAtomLinkMetadataAnnotation>()) { entity.AddAnnotation(namedStreamAtomLinkMetadataAnnotation); } } // convert properties and navigation links entry.ProcessPropertiesPreservingPayloadOrder( property => entity.Add((PropertyInstance)this.Visit(property)), navigationLink => entity.Add((PropertyInstance)this.Visit(navigationLink))); var actions = entry.Actions; if (actions != null) { foreach (var operation in actions) { var serviceOperationDescriptor = this.Visit(operation) as ServiceOperationDescriptor; entity.Add(serviceOperationDescriptor); } } var functions = entry.Functions; if (functions != null) { foreach (var operation in functions) { var serviceOperationDescriptor = this.Visit(operation) as ServiceOperationDescriptor; entity.Add(serviceOperationDescriptor); } } this.ConvertSerializationTypeNameAnnotation(entry, entity); return(entity); }
private bool TryGetEntityInstance(JsonObject jsonObject, out ODataPayloadElement elem) { string uri = this.GetMetadataPropertyValue(jsonObject, UriFieldName); string id = this.GetMetadataPropertyValue(jsonObject, IdFieldName); string typeName = this.GetMetadataPropertyValue(jsonObject, TypeFieldName); string etag = this.GetMetadataPropertyValue(jsonObject, ETagFieldName); string streamSrc = this.GetMetadataPropertyValue(jsonObject, MediaSrcFieldName); string streamEdit = this.GetMetadataPropertyValue(jsonObject, EditMediaFieldName); string streamEtag = this.GetMetadataPropertyValue(jsonObject, MediaETagFieldName); string contentType = this.GetMetadataPropertyValue(jsonObject, ContentTypeFieldName); List <ServiceOperationDescriptor> actions = null; bool containsActionsMetadata = this.TryGetServiceOperationDescriptorAnnotations(jsonObject, "actions", out actions); List <ServiceOperationDescriptor> functions = null; bool containsFunctionMetadata = this.TryGetServiceOperationDescriptorAnnotations(jsonObject, "functions", out functions); // if this object has any property with key "__deferred" // or metadata tag returns a "uri", "id", or "etag" property, // or actions, or functions // return EntityInstance // else return ComplexInstance bool isEntity = this.ContainsDeferredLink(jsonObject); isEntity |= uri != null; isEntity |= id != null; isEntity |= etag != null; isEntity |= containsActionsMetadata; isEntity |= containsFunctionMetadata; if (isEntity) { EntityInstance entity = new EntityInstance(typeName, false, id, etag); if (containsActionsMetadata) { foreach (var action in actions) { entity.ServiceOperationDescriptors.Add(action); } } if (containsFunctionMetadata) { foreach (var function in functions) { entity.ServiceOperationDescriptors.Add(function); } } entity.EditLink = uri; entity.StreamSourceLink = streamSrc; entity.StreamEditLink = streamEdit; entity.StreamETag = streamEtag; entity.StreamContentType = contentType; foreach (JsonProperty prop in jsonObject.Properties) { if (prop.Name != MetadataFieldName && prop.Name != LinkInfoFieldName) { entity.Add(this.ConvertProperty(prop) as PropertyInstance); } } // Update entity navigation properties with association links JsonObject metaDataJsonObject = (JsonObject)jsonObject.Properties.Single(p1 => p1.Name == MetadataFieldName).Value; JsonProperty properties = metaDataJsonObject.Properties.FirstOrDefault(p2 => p2.Name == PropertiesFieldName); if (properties != null) { foreach (JsonProperty jp in ((JsonObject)properties.Value).Properties) { JsonProperty associationUriJsonProperty = ((JsonObject)jp.Value).Properties.SingleOrDefault(p => p.Name == AssociationUriFieldName); DeferredLink newAssociationLink = new DeferredLink(); if (associationUriJsonProperty != null) { newAssociationLink.UriString = ((JsonPrimitiveValue)associationUriJsonProperty.Value).Value as string; } var navigation = entity.Properties.SingleOrDefault(np => np.Name.Equals(jp.Name)); NavigationPropertyInstance navigationPropertyInstance = navigation as NavigationPropertyInstance; if (navigationPropertyInstance != null) { navigationPropertyInstance.AssociationLink = newAssociationLink; } else if (navigation is EmptyCollectionProperty) { ExpandedLink newExpandedLink = new ExpandedLink() { ExpandedElement = new EntitySetInstance() }; NavigationPropertyInstance newNavigation = new NavigationPropertyInstance(navigation.Name, newExpandedLink, newAssociationLink); entity.Replace(navigation, newNavigation); } else { ExceptionUtilities.Assert(navigation.ElementType == ODataPayloadElementType.NullPropertyInstance, "Invalid type of PropertyInstance : {0}", navigation.ElementType); ExpandedLink newExpandedLink = new ExpandedLink() { ExpandedElement = new EntityInstance() }; NavigationPropertyInstance newNavigation = new NavigationPropertyInstance(navigation.Name, newExpandedLink, newAssociationLink); entity.Replace(navigation, newNavigation); } } } elem = entity; return(true); } elem = null; return(false); }
/// <summary> /// Deserializes an atom entry into an entity instance /// </summary> /// <param name="entry">The xml for an atom entry</param> /// <returns>An entity instance</returns> private EntityInstance DeserializeEntity(XElement entry) { EntityInstance entity = new EntityInstance(); entity.IsNull = false; AddXmlBaseAnnotation(entity, entry); this.DeserializeEntryAttributes(entry, entity); // get the content and properties, as well as any MLE metadata XElement content = entry.Element(AtomContent); XElement properties = null; if (content != null) { XAttribute mediaSrc = content.Attribute(Src); XAttribute contentType = content.Attribute(Type); if (mediaSrc != null) { entity.StreamSourceLink = mediaSrc.Value; if (contentType != null) { entity.StreamContentType = contentType.Value; } } else { if (contentType != null) { entity.WithContentType(contentType.Value); } properties = content.Element(MetadataProperties); } } if (properties == null) { properties = entry.Element(MetadataProperties); if (properties != null) { entity.AsMediaLinkEntry(); } } if (properties != null) { foreach (XElement property in properties.Elements()) { entity.Add(this.DeserializeProperty(property)); } } // get the navigation properties var links = entry.Elements(AtomLink); var navigations = this.DeserializeNavigationProperties(links); navigations = this.DeserializeRelationshipLinks(links, navigations.ToList()); foreach (NavigationPropertyInstance nav in navigations) { entity.Add(nav); } var namedStreams = this.DeserializeNamedStreamProperties(links); foreach (NamedStreamInstance mediaStream in namedStreams) { entity.Add(mediaStream); } // Get actions and function descriptors var serviceOperationDescriptorXElements = entry.Elements().Where(e => e.Name == MetadataAction || e.Name == MetadataFunction); var serviceOperationDescriptors = this.DeserializeServiceOperatonDescriptors(serviceOperationDescriptorXElements); foreach (var actionDescriptorAnnotation in serviceOperationDescriptors) { entity.ServiceOperationDescriptors.Add(actionDescriptorAnnotation); } return(entity); }
public void ReadActionsAndFunctionsTest() { IEdmModel model = Microsoft.Test.OData.Utils.Metadata.TestModels.BuildTestModel(); IEnumerable <ServiceOperationDescriptor> operations = new ServiceOperationDescriptor[] { new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/Target" }, new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Title = "Title", Target = "http://odata.org/Target2" }, }; operations = operations.Concat(operations.Select(o => (ServiceOperationDescriptor) new ServiceOperationDescriptor { IsFunction = true, Metadata = o.Metadata, Title = o.Title, Target = o.Target })); IEnumerable <PayloadReaderTestDescriptor> testDescriptors = operations.Select(o => { EntityInstance entityInstance = PayloadBuilder.Entity("TestModel.CityType"); entityInstance.Add(o); return(new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = entityInstance, PayloadEdmModel = model }); }); // Add couple more handcrafted cases testDescriptors.Concat(new PayloadReaderTestDescriptor[] { // Duplicate action - different targets new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.CityType") .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action" }) .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action2" }), PayloadEdmModel = model }, // Duplicate action - same targets // same targets in a metadata - allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.CityType") .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action" }) .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#action", Target = "http://odata.org/service/action" }), PayloadEdmModel = model }, // Duplicate function - different targets and titles new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.CityType") .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1" }) .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function2", Title = "Function 2" }), PayloadEdmModel = model }, // Duplicate function - same targets and titles // same targets in a metadata - allowed new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.CityType") .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1" }) .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#function", Target = "http://odata.org/service/function", Title = "Function 1" }), PayloadEdmModel = model }, // Function and Action with the same name (ODL doesn't validate this case) new PayloadReaderTestDescriptor(this.Settings) { PayloadElement = PayloadBuilder.Entity("TestModel.CityType") .OperationDescriptor(new ServiceOperationDescriptor { IsAction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/service/action", Title = "Action" }) .OperationDescriptor(new ServiceOperationDescriptor { IsFunction = true, Metadata = "http://odata.org/service/$metadata#operation", Target = "http://odata.org/service/function", Title = "Function" }), PayloadEdmModel = model }, }); // Generate interesting payloads for the EntityInstance with actions/functions // TODO: Fix places where we've lost JsonVerbose coverage to add JsonLight testDescriptors = testDescriptors.SelectMany(td => this.PayloadGenerator.GenerateReaderPayloads(td)); this.CombinatorialEngineProvider.RunCombinations( testDescriptors, ODataVersionUtils.AllSupportedVersions, this.ReaderTestConfigurationProvider.ExplicitFormatConfigurations.Where(tc => tc.Format == ODataFormat.Atom), (testDescriptor, maxProtocolVersion, testConfiguration) => { if (maxProtocolVersion < testConfiguration.Version) { // This would fail since the DSV > MPV. return; } // In requests or if MPV < V3 we don't expect the operations to be read. if (testConfiguration.IsRequest) { testDescriptor = new PayloadReaderTestDescriptor(testDescriptor); testDescriptor.ExpectedResultNormalizers.Add(tc => RemoveOperationsNormalizer.Normalize); } testDescriptor.RunTest(testConfiguration.CloneAndApplyMaxProtocolVersion(maxProtocolVersion)); }); }
/// <summary> /// Deserializes an atom entry into an entity instance /// </summary> /// <param name="entry">The xml for an atom entry</param> /// <returns>An entity instance</returns> private EntityInstance DeserializeEntity(XElement entry) { EntityInstance entity = new EntityInstance(); entity.IsNull = false; AddXmlBaseAnnotation(entity, entry); this.DeserializeEntryAttributes(entry, entity); // get the content and properties, as well as any MLE metadata XElement content = entry.Element(AtomContent); XElement properties = null; if (content != null) { XAttribute mediaSrc = content.Attribute(Src); XAttribute contentType = content.Attribute(Type); if (mediaSrc != null) { entity.StreamSourceLink = mediaSrc.Value; if (contentType != null) { entity.StreamContentType = contentType.Value; } } else { if (contentType != null) { entity.WithContentType(contentType.Value); } properties = content.Element(MetadataProperties); } } if (properties == null) { properties = entry.Element(MetadataProperties); if (properties != null) { entity.AsMediaLinkEntry(); } } if (properties != null) { foreach (XElement property in properties.Elements()) { entity.Add(this.DeserializeProperty(property)); } } // get the navigation properties var links = entry.Elements(AtomLink); var navigations = this.DeserializeNavigationProperties(links); navigations = this.DeserializeRelationshipLinks(links, navigations.ToList()); foreach (NavigationPropertyInstance nav in navigations) { entity.Add(nav); } var namedStreams = this.DeserializeNamedStreamProperties(links); foreach (NamedStreamInstance mediaStream in namedStreams) { entity.Add(mediaStream); } // Get actions and function descriptors var serviceOperationDescriptorXElements = entry.Elements().Where(e => e.Name == MetadataAction || e.Name == MetadataFunction); var serviceOperationDescriptors = this.DeserializeServiceOperatonDescriptors(serviceOperationDescriptorXElements); foreach (var actionDescriptorAnnotation in serviceOperationDescriptors) { entity.ServiceOperationDescriptors.Add(actionDescriptorAnnotation); } return entity; }
/// <summary> /// Creates a set of interesting entity instances along with metadata. /// </summary> /// <param name="settings">The test descriptor settings to use.</param> /// <param name="model">If non-null, the method creates complex types for the complex values and adds them to the model.</param> /// <param name="withTypeNames">true if the payloads should specify type names.</param> /// <returns>List of test descriptors with interesting entity instances as payload.</returns> public static IEnumerable <PayloadTestDescriptor> CreateEntityInstanceTestDescriptors( EdmModel model, bool withTypeNames) { IEnumerable <PrimitiveValue> primitiveValues = TestValues.CreatePrimitiveValuesWithMetadata(fullSet: false); IEnumerable <ComplexInstance> complexValues = TestValues.CreateComplexValues(model, withTypeNames, fullSet: false); IEnumerable <NamedStreamInstance> streamReferenceValues = TestValues.CreateStreamReferenceValues(fullSet: false); IEnumerable <PrimitiveMultiValue> primitiveMultiValues = TestValues.CreatePrimitiveCollections(withTypeNames, fullSet: false); IEnumerable <ComplexMultiValue> complexMultiValues = TestValues.CreateComplexCollections(model, withTypeNames, fullSet: false); IEnumerable <NavigationPropertyInstance> navigationProperties = TestValues.CreateDeferredNavigationLinks(); // NOTE we have to copy the EntityModelTypeAnnotation on the primitive value to the NullPropertyInstance for null values since the // NullPropertyInstance does not expose a value. We will later copy it back to the value we generate for the null property. IEnumerable <PropertyInstance> primitiveProperties = primitiveValues.Select((pv, ix) => PayloadBuilder.Property("PrimitiveProperty" + ix, pv).CopyAnnotation <PropertyInstance, EntityModelTypeAnnotation>(pv)); IEnumerable <PropertyInstance> complexProperties = complexValues.Select((cv, ix) => PayloadBuilder.Property("ComplexProperty" + ix, cv)); IEnumerable <PropertyInstance> primitiveMultiValueProperties = primitiveMultiValues.Select((pmv, ix) => PayloadBuilder.Property("PrimitiveMultiValueProperty" + ix, pmv)); IEnumerable <PropertyInstance> complexMultiValueProperties = complexMultiValues.Select((cmv, ix) => PayloadBuilder.Property("ComplexMultiValueProperty" + ix, cmv)); PropertyInstance[][] propertyMatrix = new PropertyInstance[6][]; propertyMatrix[0] = primitiveProperties.ToArray(); propertyMatrix[1] = complexProperties.ToArray(); propertyMatrix[2] = streamReferenceValues.ToArray(); propertyMatrix[3] = primitiveMultiValueProperties.ToArray(); propertyMatrix[4] = complexMultiValueProperties.ToArray(); propertyMatrix[5] = navigationProperties.ToArray(); IEnumerable <PropertyInstance[]> propertyCombinations = propertyMatrix.ColumnCombinations(0, 1, 6); int count = 0; foreach (PropertyInstance[] propertyCombination in propertyCombinations) { // build the entity type, add it to the model EdmEntityType generatedEntityType = null; string typeName = "PGEntityType" + count; EdmEntityContainer container = null; EdmEntitySet entitySet = null; if (model != null) { // generate a new type with the auto-generated name, check that no type with this name exists and add the default key property to it. Debug.Assert(model.FindDeclaredType(typeName) == null, "Entity type '" + typeName + "' already exists."); generatedEntityType = new EdmEntityType("TestModel", typeName); generatedEntityType.AddKeys(generatedEntityType.AddStructuralProperty("Id", EdmPrimitiveTypeKind.Int32)); model.AddElement(generatedEntityType); container = model.EntityContainer as EdmEntityContainer; if (container == null) { container = new EdmEntityContainer("TestModel", "DefaultNamespace"); model.AddElement(container); } entitySet = container.AddEntitySet(typeName, generatedEntityType); } EntityInstance entityInstance = PayloadBuilder.Entity("TestModel." + typeName) .Property("Id", PayloadBuilder.PrimitiveValue(count).WithTypeAnnotation(EdmCoreModel.Instance.GetInt32(false))); for (int i = 0; i < propertyCombination.Length; ++i) { PropertyInstance currentProperty = propertyCombination[i]; entityInstance.Add(currentProperty); if (model != null) { if (entitySet == null) { entitySet = container.FindEntitySet(typeName) as EdmEntitySet; } switch (currentProperty.ElementType) { case ODataPayloadElementType.ComplexProperty: ComplexProperty complexProperty = (ComplexProperty)currentProperty; generatedEntityType.AddStructuralProperty(complexProperty.Name, complexProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); break; case ODataPayloadElementType.PrimitiveProperty: PrimitiveProperty primitiveProperty = (PrimitiveProperty)currentProperty; if (primitiveProperty.Value == null) { generatedEntityType.AddStructuralProperty( primitiveProperty.Name, PayloadBuilder.PrimitiveValueType(null)); } else { generatedEntityType.AddStructuralProperty(primitiveProperty.Name, primitiveProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); } break; case ODataPayloadElementType.NamedStreamInstance: NamedStreamInstance streamProperty = (NamedStreamInstance)currentProperty; generatedEntityType.AddStructuralProperty(streamProperty.Name, EdmPrimitiveTypeKind.Stream); break; case ODataPayloadElementType.EmptyCollectionProperty: throw new NotImplementedException(); case ODataPayloadElementType.NavigationPropertyInstance: NavigationPropertyInstance navigationProperty = (NavigationPropertyInstance)currentProperty; var navProperty = generatedEntityType.AddUnidirectionalNavigation(new EdmNavigationPropertyInfo() { ContainsTarget = false, Name = navigationProperty.Name, Target = generatedEntityType, TargetMultiplicity = EdmMultiplicity.One }); entitySet.AddNavigationTarget(navProperty, entitySet); break; case ODataPayloadElementType.ComplexMultiValueProperty: ComplexMultiValueProperty complexMultiValueProperty = (ComplexMultiValueProperty)currentProperty; generatedEntityType.AddStructuralProperty(complexMultiValueProperty.Name, complexMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); break; case ODataPayloadElementType.PrimitiveMultiValueProperty: PrimitiveMultiValueProperty primitiveMultiValueProperty = (PrimitiveMultiValueProperty)currentProperty; generatedEntityType.AddStructuralProperty(primitiveMultiValueProperty.Name, primitiveMultiValueProperty.Value.GetAnnotation <EntityModelTypeAnnotation>().EdmModelType); break; default: throw new NotSupportedException("Unsupported element type found : " + propertyCombination[i].ElementType); } } } if (generatedEntityType != null) { entityInstance.AddAnnotation(new EntityModelTypeAnnotation(generatedEntityType.ToTypeReference(true))); } yield return(new PayloadTestDescriptor() { PayloadElement = entityInstance, PayloadEdmModel = model }); count++; } }