コード例 #1
0
            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
                };
            }
コード例 #3
0
        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);
            });
        }
コード例 #5
0
        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));
            });
        }
コード例 #6
0
            /// <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);
            }
コード例 #7
0
        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));
            }
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        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));
            });
        }
コード例 #11
0
        /// <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;
        }
コード例 #12
0
        /// <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++;
            }
        }