public OperationSerializerTests()
        {
            ResourceType intType = ResourceType.GetPrimitiveResourceType(typeof(int));

            var customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "FQ.NS", "Customer", false);
            customerType.CanReflectOnInstanceType = false;
            customerType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, intType) { CanReflectOnInstanceTypeProperty = false });
            customerType.SetReadOnly();

            var operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType), new ServiceActionParameter("P2", intType) }, null);
            operation.SetReadOnly();
            this.baseTypeOperation = new OperationWrapper(operation);

            var bestCustomerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, customerType, "FQ.NS", "BestCustomer", false);
            bestCustomerType.SetReadOnly();

            operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", bestCustomerType) }, null);
            operation.SetReadOnly();
            this.derivedTypeOperation = new OperationWrapper(operation);

            operation = new ServiceAction("Unambiguous", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType) }, null);
            operation.SetReadOnly();
            this.unambiguousOperation = new OperationWrapper(operation);

            this.entityToSerialize = EntityToSerialize.CreateFromExplicitValues(new object(), bestCustomerType, new TestSerializedEntityKey("http://odata.org/Service.svc/Customers(0)/", bestCustomerType.FullName));

            this.testSubject = CreateOperationSerializer(AlwaysAdvertiseActions);
        }
        public OperationLinkBuilderTests()
        {
            ResourceType intType = ResourceType.GetPrimitiveResourceType(typeof(int));

            var customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "FQ.NS", "Customer", false);
            customerType.CanReflectOnInstanceType = false;
            customerType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, intType) { CanReflectOnInstanceTypeProperty = false });
            customerType.SetReadOnly();

            var operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType), new ServiceActionParameter("P2", intType) }, null);
            operation.SetReadOnly();
            this.operationWithParameters = new OperationWrapper(operation);

            var typeWithEscapedName = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "FQ NS", "+ /", false);
            typeWithEscapedName.CanReflectOnInstanceType = false;
            typeWithEscapedName.AddProperty(new ResourceProperty("Number", ResourcePropertyKind.Primitive, intType) { CanReflectOnInstanceTypeProperty = false });
            typeWithEscapedName.SetReadOnly();

            operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType), new ServiceActionParameter("P2", typeWithEscapedName) }, null);
            operation.SetReadOnly();
            this.operationWithEscapedParameter = new OperationWrapper(operation);

            var bestCustomerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, customerType, "FQ.NS", "BestCustomer", false);
            bestCustomerType.SetReadOnly();

            operation = new ServiceAction("Action", intType, OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("P1", customerType) }, null);
            operation.SetReadOnly();
            this.operationBoundToBaseType = new OperationWrapper(operation);

            this.entityToSerialize = EntityToSerialize.CreateFromExplicitValues(new object(), bestCustomerType, new TestSerializedEntityKey("http://odata.org/Service.svc/Customers/", bestCustomerType.FullName));

            var metadataUri = new Uri("http://odata.org/Service.svc/$metadata");
            this.testSubject = new OperationLinkBuilder("MyContainer", metadataUri);
        }
        public void DataServiceProviderWrapperShouldFailOnMultipleActionsWithSameNameAndBindingType()
        {
            var entityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Fake.NS", "Type", false) { CanReflectOnInstanceType = false };
            entityType.AddProperty(new ResourceProperty("Id", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int))) {CanReflectOnInstanceTypeProperty = false});
            entityType.SetReadOnly();

            var resourceSet = new ResourceSet("MyEntitySet", entityType);
            resourceSet.SetReadOnly();

            ResourceType stringType = ResourceType.GetPrimitiveResourceType(typeof(string));
            var duplicateAction1 = new ServiceAction("Duplicate", stringType, OperationParameterBindingKind.Always, new[] { new ServiceActionParameter("p1", entityType), new ServiceActionParameter("p2", stringType) }, null);
            duplicateAction1.SetReadOnly();
            var duplicateAction2 = new ServiceAction("Duplicate", ResourceType.GetPrimitiveResourceType(typeof(int)), OperationParameterBindingKind.Sometimes, new[] { new ServiceActionParameter("p1", entityType) }, null);
            duplicateAction2.SetReadOnly();

            var actionProvider = new TestActionProvider
            {
                GetServiceActionsCallback = ctx => new[] { duplicateAction1, duplicateAction2 }
            };

            var providerWrapper = CreateProviderWrapper(actionProvider, p => p.AddResourceSet(resourceSet));

            Action getVisibleOperations = () => providerWrapper.GetVisibleOperations().ToList();
            getVisibleOperations.ShouldThrow<DataServiceException>()
                .WithMessage(ErrorStrings.DataServiceActionProviderWrapper_DuplicateAction("Duplicate"))
                .And.StatusCode.Should().Be(500);
        }
Example #4
0
        public void VerifyVersionOfEntityWithGeographyPropertyIsV3()
        {
            ResourceType rt = new ResourceType(typeof(IDictionary<string, string>), ResourceTypeKind.EntityType, null, "TestNamespace", "TestEntity", false);
            var keyProperty = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int))) {CanReflectOnInstanceTypeProperty = false };
            var geographyProperty = new ResourceProperty("GeographyProperty", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(Geography))) { CanReflectOnInstanceTypeProperty = false };
            rt.AddProperty(keyProperty);
            rt.AddProperty(geographyProperty);
            rt.SetReadOnly();

            Assert.AreEqual(v4, rt.MetadataVersion, "MetadataVersion must be 4.0");
            Assert.AreEqual(MetadataEdmSchemaVersion.Version4Dot0, rt.SchemaVersion, "Schema version must be 4.0");
        }
Example #5
0
        public void AddResourceSet(string name, string typeName)
        {
            DSP.ResourceType resourceType = GetResourceType(typeName);

            if (resourceType != null)
            {
                resourceType.SetReadOnly();
                SetDerivedReadOnly(resourceType);

                DSP.ResourceSet newResourceSet = new DSP.ResourceSet(name, resourceType);
                newResourceSet.SetReadOnly();
                addedContainers.Add(newResourceSet);
            }
        }
        private static EntityToSerialize CreateEntityToSerialize(bool shouldIncludeTypeSegment)
        {
            ResourceType baseType = new ResourceType(typeof(MyType), ResourceTypeKind.EntityType, null, "TestNamespace", "BaseType", /*isAbstract*/ false);
            baseType.AddProperty(new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, new ResourceType(typeof(int), ResourceTypeKind.Primitive, null, "int")));

            baseType.SetReadOnly();

            Uri serviceUri = new Uri("http://dummy");

            KeySerializer keySerializer = KeySerializer.Create(UrlConvention.CreateWithExplicitValue(false));

            Func<ResourceProperty, object> getPropertyValue = p => "fakePropertyValue";
            return EntityToSerialize.Create(new MyType { ID = 42 }, baseType, "MySet", shouldIncludeTypeSegment, getPropertyValue, keySerializer, serviceUri);
        }
        public void InvalidCasesTest()
        {
            ResourceProperty id = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int))) { CanReflectOnInstanceTypeProperty = false };
            ResourceType customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "CustomerType", false);
            customerType.AddProperty(id);
            ResourceType orderType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "OrderType", false);
            orderType.AddProperty(id);

            ResourceProperty customerOrders = new ResourceProperty("Orders", ResourcePropertyKind.ResourceSetReference, orderType);
            ResourceProperty orderCustomer = new ResourceProperty("Customer", ResourcePropertyKind.ResourceReference, customerType);
            customerType.AddProperty(customerOrders);
            orderType.AddProperty(orderCustomer);
            customerOrders.CanReflectOnInstanceTypeProperty = false;
            orderCustomer.CanReflectOnInstanceTypeProperty = false;
            customerType.SetReadOnly();
            orderType.SetReadOnly();

            ResourceSet customerSet = new ResourceSet("Customers", customerType);
            ResourceSet orderSet = new ResourceSet("Orders", orderType);

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSetEnd),
                "Value cannot be null.\r\nParameter name: resourceSet",
                null, customerType, customerOrders);

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSetEnd),
                "Value cannot be null.\r\nParameter name: resourceType",
                customerSet, null, customerOrders);

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSetEnd),
                "The resourceProperty parameter must be a navigation property on the resource type specified by the resourceType parameter.",
                customerSet, customerType, id);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSetEnd),
                "The resourceProperty parameter must be a navigation property on the resource type specified by the resourceType parameter.",
                customerSet, customerType, orderCustomer);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSetEnd),
                "The resourceType parameter must be a type that is assignable to the resource set specified by the resourceSet parameter.",
                customerSet,
                orderType,
                orderCustomer);
        }
        public void InvalidCasesTest()
        {
            ResourceProperty id = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int))) { CanReflectOnInstanceTypeProperty = false };
            ResourceType customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "CustomerType", false);
            customerType.AddProperty(id);
            ResourceType orderType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "OrderType", false);
            orderType.AddProperty(id);

            ResourceProperty customerOrders = new ResourceProperty("Orders", ResourcePropertyKind.ResourceSetReference, orderType);
            ResourceProperty orderCustomer = new ResourceProperty("Customer", ResourcePropertyKind.ResourceReference, customerType);
            customerType.AddProperty(customerOrders);
            orderType.AddProperty(orderCustomer);
            customerOrders.CanReflectOnInstanceTypeProperty = false;
            orderCustomer.CanReflectOnInstanceTypeProperty = false;
            customerType.SetReadOnly();
            orderType.SetReadOnly();

            ResourceSet customerSet = new ResourceSet("Customers", customerType);
            ResourceSet orderSet = new ResourceSet("Orders", orderType);

            ResourceAssociationSetEnd end1 = new ResourceAssociationSetEnd(customerSet, customerType, null);
            ResourceAssociationSetEnd end2 = new ResourceAssociationSetEnd(orderSet, orderType, null);

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSet), 
                "Value cannot be null or empty.\r\nParameter name: name", 
                null, end1, end2);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSet), 
                "Value cannot be null or empty.\r\nParameter name: name", 
                string.Empty, end1, end2);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSet), 
                "Value cannot be null.\r\nParameter name: end1", 
                "Customer_Order", null, end2);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSet), 
                "Value cannot be null.\r\nParameter name: end2", 
                "Customer_Order", end1, null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceAssociationSet),
                "The ResourceProperty of the ResourceAssociationEnds cannot both be null.", 
                "Customer_Order", end1, end2);

        }
Example #9
0
        public void InvalidCasesTest()
        {
            ResourceType rt = (ResourceType)ResourceTypeUtils.GetTestInstance(typeof(ResourceType));

            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => rt.AddProperty(new ResourceProperty("ID", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(double)))),
                "A property with same name 'ID' already exists in type 'Foo.NoBaseType'. Please make sure that there is no property with the same name defined in one of the base types.",
                "cannot add property with the same name");

            ResourceType derivedType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, rt, "Namespace", "CustomerWithBirthday", false);

            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => derivedType.AddProperty(new ResourceProperty("p1", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int)))),
                "Key properties cannot be defined in derived types.",
                "Cannot add key properties to derived type");

            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => {
                    ResourceType resourceType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "NoBaseType", false);
                    resourceType.SetReadOnly();
                    // Accessing any properties collection will invoke the validation logic
                    resourceType.KeyProperties.Single();
                },
                "The entity type 'Foo.NoBaseType' does not have any key properties. Please make sure that one or more key properties are defined for this entity type.",
                "Entity Type must have key Properties");

            // should be able to add property with same name as that in the base type. This will throw when we make the derived type readonly.
            derivedType.AddProperty(new ResourceProperty("ID", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int))));
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => {
                    derivedType.SetReadOnly();
                    // Accessing any properties collection will invoke the validation logic
                    derivedType.Properties.First();
                },
                "A property with same name 'ID' already exists in type 'Namespace.CustomerWithBirthday'. Please make sure that there is no property with the same name defined in one of the base types.",
                "cannot add property with the same name as that in base type");

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceType),
                "ResourceTypeKind.Primitive, ResourceTypeKind.Collection and ResourceTypeKind.EntityCollection are not valid values for the 'resourceTypeKind' parameter.\r\nParameter name: resourceTypeKind",
                typeof(object), ResourceTypeKind.Primitive, null, "foo", "bar", false);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceType),
                "ResourceTypeKind.Primitive, ResourceTypeKind.Collection and ResourceTypeKind.EntityCollection are not valid values for the 'resourceTypeKind' parameter.\r\nParameter name: resourceTypeKind",
                typeof(object), ResourceTypeKind.Collection, null, "foo", "bar", false);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceType),
                "ResourceTypeKind.Primitive, ResourceTypeKind.Collection and ResourceTypeKind.EntityCollection are not valid values for the 'resourceTypeKind' parameter.\r\nParameter name: resourceTypeKind",
                typeof(object), ResourceTypeKind.EntityCollection, null, "foo", "bar", false);

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ResourceType),
                "The CLR type for the resource type cannot be a value type.\r\nParameter name: instanceType", 
                typeof(int), ResourceTypeKind.ComplexType, null, "foo", "bar", false);

            ExceptionUtils.ExpectedException<ArgumentException>(
                () => ResourceType.GetCollectionResourceType(ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream))),
                "The ItemType of a collection resource type cannot be of type 'Edm.Stream'.\r\nParameter name: itemType");

            ResourceType ct = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "Foo", "Bar", false);
            ResourceType pt = ResourceType.GetPrimitiveResourceType(typeof(string));
            ResourceType primitiveCollection = ResourceType.GetCollectionResourceType(pt);
            ResourceType et = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "EntityResourceType", false);
            ResourceType entityCollection = ResourceType.GetEntityCollectionResourceType(et);

            ExceptionUtils.ExpectedException<ArgumentException>(
                () => ResourceType.GetEntityCollectionResourceType(null),
                "Value cannot be null.\r\nParameter name: itemType");
            ResourceType[] types = new ResourceType[] { ct, pt, primitiveCollection, entityCollection };
            AstoriaTestNS.TestUtil.RunCombinations(
                types,
                r =>
                {
                    ExceptionUtils.ExpectedException<ArgumentException>(
                        () => ResourceType.GetEntityCollectionResourceType(r),
                        "Only collections of an entity type are supported.");
                });

            types = new ResourceType[] { ct, pt, primitiveCollection, entityCollection };
            ResourceProperty key = new ResourceProperty("KeyProperty", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string)));
            ResourceProperty etag = new ResourceProperty("ETagProperty", ResourcePropertyKind.ETag | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string)));
            ResourceProperty primitive = new ResourceProperty("Property", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string)));
            AstoriaTestNS.TestUtil.RunCombinations(
                types,
                r =>
                {
                    ExceptionUtils.ThrowsException<InvalidOperationException>(
                        () => r.AddProperty(key),
                        "Cannot add key property to non-entity types");

                    ExceptionUtils.ThrowsException<InvalidOperationException>(
                        () => r.AddProperty(etag),
                        "Cannot add key property to non-entity types");

                    ExceptionUtils.ThrowsException<InvalidOperationException>(
                        () => r.AddProperty(new ResourceProperty("Stream1", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)))),
                        "Cannot add key property to non-entity types");
                });

            ExceptionUtils.ThrowsException<InvalidOperationException>(
                () =>
                {
                    pt.AddProperty(primitive);
                    primitiveCollection.AddProperty(primitive);
                    entityCollection.AddProperty(primitive);
                },
                "Cannot add property to primitive, primitive collection or entity collection types");

            types = new ResourceType[] { pt, ct, et, primitiveCollection, entityCollection };
            AstoriaTestNS.TestUtil.RunCombinations(
                new ResourceTypeKind[] { ResourceTypeKind.EntityType, ResourceTypeKind.ComplexType },
                types,
                (derivedTypeKind, baseResourceType) =>
                {
                    if (baseResourceType.ResourceTypeKind == derivedTypeKind)
                    {
                        return;
                    }

                    ExceptionUtils.ExpectedException<ArgumentException>(
                        () => new ResourceType(typeof(object), derivedTypeKind, baseResourceType, "Foo", "NewDerivedType", false),
                        string.Format("A resource type of kind '{0}' cannot derive from a base resource type of kind '{1}'. Inheritance is only supported when resource types are of the same kind.\r\nParameter name: resourceTypeKind",
                            derivedTypeKind.ToString(), baseResourceType.ResourceTypeKind.ToString()),
                        "Cannot derive from a resource type of different kind.");
                });
        }
        public void GetTargetSetTestsSetBindingTypeShouldPerformCorrectValidation()
        {
            ResourceType actorEntityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "foo", "Actor", false) { CanReflectOnInstanceType = false };
            ResourceProperty idProperty = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int))) { CanReflectOnInstanceTypeProperty = false };
            actorEntityType.AddProperty(idProperty);

            ResourceType addressComplexType = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "foo", "Address", false) { CanReflectOnInstanceType = false };
            addressComplexType.AddProperty(new ResourceProperty("StreetAddress", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string))) { CanReflectOnInstanceTypeProperty = false });
            addressComplexType.AddProperty(new ResourceProperty("ZipCode", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int))) { CanReflectOnInstanceTypeProperty = false });

            actorEntityType.AddProperty(new ResourceProperty("PrimaryAddress", ResourcePropertyKind.ComplexType, addressComplexType) { CanReflectOnInstanceTypeProperty = false });
            actorEntityType.AddProperty(new ResourceProperty("OtherAddresses", ResourcePropertyKind.Collection, ResourceType.GetCollectionResourceType(addressComplexType)) { CanReflectOnInstanceTypeProperty = false });

            ResourceType movieEntityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "foo", "Movie", false) { CanReflectOnInstanceType = false };
            movieEntityType.AddProperty(idProperty);

            ResourceProperty moviesNavProp = new ResourceProperty("Movies", ResourcePropertyKind.ResourceSetReference, movieEntityType) { CanReflectOnInstanceTypeProperty = false };
            actorEntityType.AddProperty(moviesNavProp);
            ResourceProperty actorsNavProp = new ResourceProperty("Actors", ResourcePropertyKind.ResourceSetReference, actorEntityType) { CanReflectOnInstanceTypeProperty = false };
            movieEntityType.AddProperty(actorsNavProp);

            ResourceType derivedActorEntityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, actorEntityType, "foo", "DerivedActor", false) { CanReflectOnInstanceType = false };
            ResourceType derivedMovieEntityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, movieEntityType, "foo", "DerivedMovie", false) { CanReflectOnInstanceType = false };

            actorEntityType.SetReadOnly();
            derivedActorEntityType.SetReadOnly();
            movieEntityType.SetReadOnly();
            derivedMovieEntityType.SetReadOnly();
            addressComplexType.SetReadOnly();
            DataServiceProviderSimulator providerSimulator = new DataServiceProviderSimulator();
            providerSimulator.AddResourceType(actorEntityType);
            providerSimulator.AddResourceType(derivedActorEntityType);
            providerSimulator.AddResourceType(movieEntityType);
            providerSimulator.AddResourceType(derivedMovieEntityType);
            providerSimulator.AddResourceType(addressComplexType);

            ResourceSet actorSet = new ResourceSet("Actors", actorEntityType);
            ResourceSet movieSet = new ResourceSet("Movies", movieEntityType);
            actorSet.SetReadOnly();
            movieSet.SetReadOnly();
            providerSimulator.AddResourceSet(actorSet);
            providerSimulator.AddResourceSet(movieSet);

            providerSimulator.AddResourceAssociationSet(new ResourceAssociationSet("Actors_Movies", new ResourceAssociationSetEnd(actorSet, actorEntityType, moviesNavProp), new ResourceAssociationSetEnd(movieSet, movieEntityType, actorsNavProp)));

            DataServiceConfiguration config = new DataServiceConfiguration(providerSimulator);
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = ODataProtocolVersion.V4;

            var dataService = new DataServiceSimulator()
            {
                OperationContext = new DataServiceOperationContext(new DataServiceHostSimulator())
            };

            dataService.ProcessingPipeline = new DataServiceProcessingPipeline();
            DataServiceStaticConfiguration staticConfiguration = new DataServiceStaticConfiguration(dataService.Instance.GetType(), providerSimulator);
            IDataServiceProviderBehavior providerBehavior = DataServiceProviderBehavior.CustomDataServiceProviderBehavior;

            DataServiceProviderWrapper provider = new DataServiceProviderWrapper(
                new DataServiceCacheItem(
                    config, 
                    staticConfiguration), 
                providerSimulator, 
                providerSimulator, 
                dataService,
                false);
            dataService.Provider = provider;
            provider.ProviderBehavior = providerBehavior;

            var testCases = new[]
            {
                new
                {
                    AppendParameterName = true,
                    Path = "",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    ErrorMessage = default(string)
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/Movies",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = ResourceSetWrapper.CreateResourceSetWrapper(movieSet, provider, set => set),
                    ErrorMessage = default(string)
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/Movies/Actors/Movies",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = ResourceSetWrapper.CreateResourceSetWrapper(movieSet, provider, set => set),
                    ErrorMessage = default(string)
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/foo.DerivedActor/Movies/foo.DerivedMovie/Actors/foo.DerivedActor/Movies",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = ResourceSetWrapper.CreateResourceSetWrapper(movieSet, provider, set => set),
                    ErrorMessage = default(string)
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/' is not a valid expression because it contains an empty segment or it ends with '/'."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/Movies/",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/Movies/' is not a valid expression because it contains an empty segment or it ends with '/'."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/Movies//Actors",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = ResourceSetWrapper.CreateResourceSetWrapper(movieSet, provider, set => set),
                    ErrorMessage = "The path expression '{0}/Movies//Actors' is not a valid expression because it contains an empty segment or it ends with '/'."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/foo.DerivedActor",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/foo.DerivedActor' is not a valid expression because it ends with the type identifier 'foo.DerivedActor'. A valid path expression must not end in a type identifier."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/Movies/foo.DerivedMovie",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/Movies/foo.DerivedMovie' is not a valid expression because it ends with the type identifier 'foo.DerivedMovie'. A valid path expression must not end in a type identifier."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/Foo",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/Foo' is not a valid expression because the segment 'Foo' is not a type identifier or a property on the resource type 'foo.Actor'."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/ID",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/ID' is not a valid expression because the segment 'ID' is a property of type 'Edm.Int32'. A valid path expression must only contain properties of entity type."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/OtherAddresses",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/OtherAddresses' is not a valid expression because the segment 'OtherAddresses' is a property of type 'Collection(foo.Address)'. A valid path expression must only contain properties of entity type."
                },
                new
                {
                    AppendParameterName = true,
                    Path = "/Movies/Actors/PrimaryAddress",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression '{0}/Movies/Actors/PrimaryAddress' is not a valid expression because the segment 'PrimaryAddress' is a property of type 'foo.Address'. A valid path expression must only contain properties of entity type."
                },
                new
                {
                    AppendParameterName = false,
                    Path = "foo",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression 'foo' is not a valid path expression. A valid path expression must start with the binding parameter name '{0}'."
                },
                new
                {
                    AppendParameterName = false,
                    Path = "abc/pqr",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression 'abc/pqr' is not a valid path expression. A valid path expression must start with the binding parameter name '{0}'."
                },
                new
                {
                    AppendParameterName = false,
                    Path = "actorParameter",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression 'actorParameter' is not a valid path expression. A valid path expression must start with the binding parameter name '{0}'."
                },
                new
                {
                    AppendParameterName = false,
                    Path = "actorsParameter",
                    BindingSet = ResourceSetWrapper.CreateResourceSetWrapper(actorSet, provider, set => set),
                    TargetSet = default(ResourceSetWrapper),
                    ErrorMessage = "The path expression 'actorsParameter' is not a valid path expression. A valid path expression must start with the binding parameter name '{0}'."
                },
            };

            ServiceActionParameter actorParameter = new ServiceActionParameter("actor", actorEntityType);
            ServiceActionParameter actorsParameter = new ServiceActionParameter("actors", ResourceType.GetEntityCollectionResourceType(actorEntityType));
            var parameters = new ServiceActionParameter[] { actorParameter, actorsParameter };

            foreach (var parameter in parameters)
            {
                foreach (var testCase in testCases)
                {
                    string pathString = testCase.AppendParameterName ? parameter.Name + testCase.Path : testCase.Path;
                    var path = new ResourceSetPathExpression(pathString);
                    Assert.AreEqual(pathString, path.PathExpression);
                    string expectedErrorMessage = testCase.ErrorMessage == null ? null : string.Format(testCase.ErrorMessage, parameter.Name);
                    try
                    {
                        path.SetBindingParameter(parameter);
                        path.InitializePathSegments(provider);
                        var targetSet = path.GetTargetSet(provider, testCase.BindingSet);
                        Assert.IsNull(expectedErrorMessage, "Expecting exception but received none.");
                        Assert.AreEqual(targetSet.Name, testCase.TargetSet.Name);
                    }
                    catch (InvalidOperationException e)
                    {
                        Assert.AreEqual(expectedErrorMessage, e.Message);
                    }
                }
            }
        }
 private static ResourceType CreateDerivedType(string name, ResourceType baseType)
 {
     var resourceType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, baseType, "FQ.NS", name, false) { CanReflectOnInstanceType = false };
     resourceType.SetReadOnly();
     return resourceType;
 }
        private static ResourceType CreateResourceTypeWithKeyProperties(params string[] keyPropertyNames)
        {
            var resourceType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "FQ.NS", "EntityType", false) {CanReflectOnInstanceType = false};

            foreach (var keyPropertyName in keyPropertyNames)
            {
                resourceType.AddProperty(new ResourceProperty(keyPropertyName, ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int))) {CanReflectOnInstanceTypeProperty = false});
            }

            resourceType.SetReadOnly();
            return resourceType;
        }
        /// <summary>
        /// Ensures that the product caches resource types based on their names.
        /// </summary>
        /// <param name="type">The resource type which may or may not be cached.</param>
        /// <param name="throwIfAlreadyCached">Whether or not to throw if the resource type is already cached.</param>
        /// <param name="addToCache">Whether or not to add the type to the cache. Certain code paths do not cache all the resource type they could.</param>
        /// <returns>The same resource type if not cached, or a copy if it was.</returns>
        private ResourceType EnforceMetadataCache(ResourceType type, bool throwIfAlreadyCached, bool addToCache)
        {
            if (type == null)
            {
                return null;
            }

            if (!ProviderImplementationSettings.Current.EnforceMetadataCaching)
            {
                return type;
            }

            if (type.ResourceTypeKind != ResourceTypeKind.ComplexType && type.ResourceTypeKind != ResourceTypeKind.EntityType)
            {
                return type;
            }

            bool cached;
            if (addToCache)
            {
                cached = !this.resourceTypeCache.Add(type.FullName);
            }
            else
            {
                cached = this.resourceTypeCache.Contains(type.FullName);
            }

            if (!cached)
            {
                return type;
            }

            ExceptionUtilities.Assert(!throwIfAlreadyCached, "Resource type '{0}' was resolved more than once", type.Name);

            var copy = new ResourceType(typeof(object), type.ResourceTypeKind, null, type.Namespace, type.Name, !type.IsAbstract);
            copy.SetReadOnly();
            return copy;
        }
Example #14
0
        public void AddingPropertiesTest()
        {
            ResourceType complexType = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "namespace", "Address", false);
            ResourceType entityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Namespace", "Order", false);

            IEnumerable<ResourceProperty> primitiveResourceProperties =
                ResourceTypeUtils.GetPrimitiveResourceTypes().Where(rt => rt.FullName != "Edm.Stream").Select(rt => new ResourceProperty("PrimitiveProperty", ResourcePropertyKind.Primitive, rt));
            IEnumerable<ResourceProperty> keyResourceProperties =
                GetKeyResourceTypes().Where(rt => !rt.FullName.StartsWith("Edm.Geography") && !rt.FullName.StartsWith("Edm.Geometry")).Select(rt => new ResourceProperty("KeyProperty", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, rt));
            IEnumerable<ResourceProperty> etagResourceProperties =
                ResourceTypeUtils.GetPrimitiveResourceTypes().Where(rt => !rt.FullName.StartsWith("Edm.Geography") && !rt.FullName.StartsWith("Edm.Geometry") && rt.FullName != "Edm.Stream").Select(rt => new ResourceProperty("ETagProperty", ResourcePropertyKind.Primitive | ResourcePropertyKind.ETag, rt));

            IEnumerable<ResourceProperty> complexProperties = new ResourceProperty[] {
                    new ResourceProperty("ComplexProperty", ResourcePropertyKind.ComplexType, complexType) };
            IEnumerable<ResourceProperty> navigationProperties = new ResourceProperty[] {
                    new ResourceProperty("ResourceReferenceProperty", ResourcePropertyKind.ResourceReference, entityType),
                    new ResourceProperty("ResourceSetReferenceProperty", ResourcePropertyKind.ResourceSetReference, entityType)};
            IEnumerable<ResourceProperty> collectionProperties = ResourceTypeUtils.GetPrimitiveResourceTypes().Except(new [] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)) }).Concat(new ResourceType[] { complexType })
                .Select(rt => new ResourceProperty("CollectionProperty", ResourcePropertyKind.Collection, ResourceType.GetCollectionResourceType(rt)));

            // Primitive resource type - no properties can be added
            foreach (ResourceType primitiveResourceType in ResourceTypeUtils.GetPrimitiveResourceTypes())
                foreach (ResourceProperty property in primitiveResourceProperties.Concat(keyResourceProperties).Concat(etagResourceProperties)
                                                        .Concat(complexProperties).Concat(navigationProperties).Concat(collectionProperties))
                {
                    ExceptionUtils.ThrowsException<InvalidOperationException>(
                        () => primitiveResourceType.AddProperty(property),
                        string.Format("Adding property {0} to primitive resource type {1} should fail.", property.Name, primitiveResourceType.FullName));
                }

            // Collection resource type - no properties can be added
            foreach (ResourceType CollectionResourceType in ResourceTypeUtils.GetPrimitiveResourceTypes().Except(new[] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)) }).Concat(new ResourceType[] { complexType })
                                                            .Select(rt => ResourceType.GetCollectionResourceType(rt)))
                foreach (ResourceProperty property in primitiveResourceProperties.Concat(keyResourceProperties).Concat(etagResourceProperties)
                                                        .Concat(complexProperties).Concat(navigationProperties).Concat(collectionProperties))
                {
                    ExceptionUtils.ThrowsException<InvalidOperationException>(
                        () => CollectionResourceType.AddProperty(property),
                        string.Format("Adding property {0} to a collection resource type {1} should fail.", property.Name, CollectionResourceType.FullName));
                }

            // Collection resource type - no properties can be added
            foreach (ResourceType collectionResourceType in (new ResourceType[] { entityType }).Select(rt => ResourceType.GetEntityCollectionResourceType(rt)))
                foreach (ResourceProperty property in primitiveResourceProperties.Concat(keyResourceProperties).Concat(etagResourceProperties)
                                                        .Concat(complexProperties).Concat(navigationProperties).Concat(collectionProperties))
                {
                    ExceptionUtils.ThrowsException<InvalidOperationException>(
                        () => collectionResourceType.AddProperty(property),
                        string.Format("Adding property {0} to a collection resource type {1} should fail.", property.Name, collectionResourceType.FullName));
                }

            // Complex resource type - only primitive, complex and collection properties can be added
            foreach (ResourceProperty property in primitiveResourceProperties.Concat(complexProperties).Concat(collectionProperties))
            {
                ResourceType t = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "Ns", "Address", false);
                t.AddProperty(property);
            }

            // It is possible to add navigation property to a complex type.
            // Once this is fixed remove this foreach and add navigationProperties to the list for the next foreach.
            foreach (var p in navigationProperties)
            {
                ResourceType t = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "Ns", "Address", false);
                t.AddProperty(p);
                t.SetReadOnly();
            }

            foreach (ResourceProperty property in keyResourceProperties.Concat(etagResourceProperties))
            {
                ResourceType t = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "Ns", "Address", false);
                ExceptionUtils.ThrowsException<InvalidOperationException>(
                    () => t.AddProperty(property),
                    string.Format("Adding key or etag property {0} to complex resource type should fail.", property.Name));
            }

            // Entity resource type
            foreach (ResourceProperty property in primitiveResourceProperties.Concat(keyResourceProperties).Concat(etagResourceProperties)
                                                    .Concat(complexProperties).Concat(navigationProperties).Concat(collectionProperties))
            {
                ResourceType t = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Ns", "Order", false);
                if (property.ResourceType.InstanceType == typeof(System.IO.Stream) && (property.Kind & ResourcePropertyKind.Stream) != ResourcePropertyKind.Stream)
                {
                    ExceptionUtils.ThrowsException<InvalidOperationException>(
                        () =>
                        {
                            t.AddProperty(property);
                        },
                        "Adding Stream type as primitive property should fail");
                }
                else
                {
                    t.AddProperty(property);
                }
            }
        }
Example #15
0
        public void AddNamedStreamValidationTest()
        {
            ResourceProperty idProperty = new ResourceProperty("ID", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceProperty name = new ResourceProperty("Name", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(string)));
            idProperty.CanReflectOnInstanceTypeProperty = false;
            name.CanReflectOnInstanceTypeProperty = false;

            ResourceType entityType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "entityType", false);

            // Adding named stream to readonly type
            entityType.AddProperty(idProperty);
            entityType.SetReadOnly();
            ResourceProperty stream1 = new ResourceProperty("Stream1", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)));
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => entityType.AddProperty(stream1),
                string.Format("The resource type '{0}' cannot be modified since it is already set to read-only.", entityType.FullName),
                "Adding to a sealed type should fail.");

            // Adding a named stream which will collide with properties declared on this type
            ResourceType type1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "type1", true);
            type1.AddProperty(idProperty);
            ResourceProperty idStream = new ResourceProperty("ID", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)));
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type1.AddProperty(idStream),
                "A property with same name 'ID' already exists in type 'namespace.type1'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Named stream can't have the same name as a property.");

            // Adding a named stream which will collide with properties declared on base type
            type1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "type1", true);
            type1.AddProperty(idProperty);
            ResourceType type2 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, type1, "namespace", "type2", false);
            // We don't detect name collision between named streams and properties until we enumerate properties after the type is set to readonly.
            idStream = new ResourceProperty("ID", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)));
            type2.AddProperty(idStream);
            type2.Properties.Count();
            type2.SetReadOnly();
            // Detect name collision now.
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type2.Properties.Count(),
                "A property with same name 'ID' already exists in type 'namespace.type2'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Named stream can't have the same name as a property on base type.");

            // Adding a named stream which will collide with named streams declared on this type
            type1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "type1", true);
            type1.AddProperty(idProperty);
            ResourceProperty nameStream = new ResourceProperty("Name", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)));
            type1.AddProperty(nameStream);
            // Adding the same named stream instance
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type1.AddProperty(nameStream),
                "A property with same name 'Name' already exists in type 'namespace.type1'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Named stream can't have the same name as another named stream.");
            // Adding a new instance with the same name
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type1.AddProperty(new ResourceProperty("Name", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)))),
                "A property with same name 'Name' already exists in type 'namespace.type1'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Named stream can't have the same name as another named stream - new instance.");

            // Adding a named stream which will collide with named streams declared on base type
            type1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "type1", true);
            type1.AddProperty(idProperty);
            type1.AddProperty(nameStream);
            type2 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, type1, "namespace", "type2", false);
            type2.AddProperty(nameStream);  // Adding the same instance
            type2.SetReadOnly();
            // Delay detection until ValidateType(), this is because you can add named streams to the base type that collides with those on the derived type.
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type2.Properties.Count(),
                "A property with same name 'Name' already exists in type 'namespace.type2'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Named stream can't have the same name as another named stream - new instance.");
            type2 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, type1, "namespace", "type2", false);
            type2.AddProperty(new ResourceProperty(nameStream.Name, ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream))));  // Adding a new instance with the same name
            type2.SetReadOnly();
            // Delay detection until ValidaType(), this is because you can add named streams to the base type that collides with those on the derived type.
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type2.Properties.Count(),
                "A property with same name 'Name' already exists in type 'namespace.type2'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Named stream can't have the same name as another named stream - new instance.");

            // Adding a property which will collide with named streams declared on this type
            type1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "type1", true);
            type1.AddProperty(idProperty);
            nameStream = new ResourceProperty("Name", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)));
            type1.AddProperty(nameStream);
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type1.AddProperty(name),
                "A property with same name 'Name' already exists in type 'namespace.type1'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Can't add property with the same name as a named stream.");

            // Adding a property which will collide with named streams declared on base type
            type1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "type1", true);
            type1.AddProperty(idProperty);
            type1.AddProperty(nameStream);
            // We don't detect name collision between named streams and properties until we enumerate properties after the type is set to readonly.
            type2 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, type1, "namespace", "type2", false);
            type2.AddProperty(name);
            type2.Properties.Count();
            type2.SetReadOnly();
            // Detect name collision now.
            ExceptionUtils.ExpectedException<InvalidOperationException>(
                () => type2.Properties.Count(),
                "A property with same name 'Name' already exists in type 'namespace.type2'. Please make sure that there is no property with the same name defined in one of the base types.",
                "Can't add property with the same name as a named stream on base type.");
        }
        public void ServiceOperationConstructorInvalidTests()
        {
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "The 'resultType' parameter must be null when the 'resultKind' parameter value is 'Void', however the 'resultType' parameter cannot be null when the 'resultKind' parameter is of any value other than 'Void'. Please make sure that the 'resultKind' parameter value is set according to the 'resultType' parameter value.",
                "op", ServiceOperationResultKind.Void, ResourceType.GetPrimitiveResourceType(typeof(int)), null, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "The 'resultType' parameter must be null when the 'resultKind' parameter value is 'Void', however the 'resultType' parameter cannot be null when the 'resultKind' parameter is of any value other than 'Void'. Please make sure that the 'resultKind' parameter value is set according to the 'resultType' parameter value.",
                "op", ServiceOperationResultKind.DirectValue, null, null, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "A parameter with the name 'p1' already exists. Please make sure that every parameter has a unique name.",
                "op", ServiceOperationResultKind.Void, null, null, "GET",
                new ServiceOperationParameter[] { 
                        new ServiceOperationParameter("p1", ResourceType.GetPrimitiveResourceType(typeof(int))),
                        new ServiceOperationParameter("p1", ResourceType.GetPrimitiveResourceType(typeof(string))) });
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "The resource type 'Collection(foo.Customer)' is not a type that can be returned by a service operation. A service operation can only return values of an entity type, a complex type or any primitive type, other than the stream type.",
                "op", ServiceOperationResultKind.QueryWithMultipleResults, ResourceType.GetEntityCollectionResourceType(new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "foo", "Customer", false)), null, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "The resource type 'Edm.Stream' is not a type that can be returned by a service operation. A service operation can only return values of an entity type, a complex type or any primitive type, other than the stream type.",
                "op", ServiceOperationResultKind.DirectValue, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)), null, "GET", null);

            ResourceProperty p = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceType customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "NoBaseType", false);
            customerType.AddProperty(p);
            customerType.SetReadOnly();
            ResourceSet customerSet = new ResourceSet("Customers", customerType);
            ResourceType orderType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "NoBaseType", false);
            orderType.AddProperty(p);
            orderType.SetReadOnly();

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "'resultSet' must be null when 'resultType' is null or not an EntityType.",
                "op", ServiceOperationResultKind.Void, null, customerSet, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "'resultSet' must be null when 'resultType' is null or not an EntityType.",
                "op", ServiceOperationResultKind.DirectValue, ResourceType.GetPrimitiveResourceType(typeof(int)), customerSet, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "When 'resultType' is an entity type, 'resultSet' cannot be null and the resource type of 'resultSet' must be assignable from 'resultType'.",
                "op", ServiceOperationResultKind.QueryWithMultipleResults, customerType, null, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "When 'resultType' is an entity type, 'resultSet' cannot be null and the resource type of 'resultSet' must be assignable from 'resultType'.",
                "op", ServiceOperationResultKind.QueryWithMultipleResults, orderType, customerSet, "GET", null);

            ExceptionUtils.ThrowsException<InvalidOperationException>(
                () =>
                {
                    ServiceOperation op = new ServiceOperation("op", ServiceOperationResultKind.Void, null, null, "GET", null);
                    op.MimeType = null;
                },
                "MimeType cannot be set to null");

            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "Value cannot be null or empty.\r\nParameter name: method",
                "op", ServiceOperationResultKind.DirectValue, ResourceType.GetPrimitiveResourceType(typeof(int)), null, null, null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "Value cannot be null or empty.\r\nParameter name: method",
                "op", ServiceOperationResultKind.DirectValue, ResourceType.GetPrimitiveResourceType(typeof(int)), null, string.Empty, null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "Value cannot be null or empty.\r\nParameter name: name",
                null, ServiceOperationResultKind.DirectValue, ResourceType.GetPrimitiveResourceType(typeof(int)), null, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "Value cannot be null or empty.\r\nParameter name: name",
                string.Empty, ServiceOperationResultKind.DirectValue, ResourceType.GetPrimitiveResourceType(typeof(int)), null, "GET", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "An invalid HTTP method 'PUT' was specified for the service operation 'op'. Only the HTTP 'POST' and 'GET' methods are supported for service operations.",
                "op", ServiceOperationResultKind.Void, null, null, "PUT", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "An invalid HTTP method 'PATCH' was specified for the service operation 'op'. Only the HTTP 'POST' and 'GET' methods are supported for service operations.",
                "op", ServiceOperationResultKind.Void, null, null, "PATCH", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "An invalid HTTP method 'DELETE' was specified for the service operation 'op'. Only the HTTP 'POST' and 'GET' methods are supported for service operations.",
                "op", ServiceOperationResultKind.Void, null, null, "DELETE", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "An invalid HTTP method 'HEAD' was specified for the service operation 'op'. Only the HTTP 'POST' and 'GET' methods are supported for service operations.",
                "op", ServiceOperationResultKind.Void, null, null, "HEAD", null);
            ExceptionUtils.CheckInvalidConstructorParameters(
                typeof(ServiceOperation),
                "An invalid HTTP method 'Some Method' was specified for the service operation 'op'. Only the HTTP 'POST' and 'GET' methods are supported for service operations.",
                "op", ServiceOperationResultKind.Void, null, null, "Some Method", null);
        }
        public void ServiceActionConstructorTests()
        {
            ResourceProperty id = new ResourceProperty("ID", ResourcePropertyKind.Primitive | ResourcePropertyKind.Key, ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceType customerType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "Customer", false);
            customerType.AddProperty(id);
            customerType.SetReadOnly();
            ResourceSet customerSet = new ResourceSet("Customers", customerType);
            ResourceType orderType = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "Foo", "Order", false);
            orderType.AddProperty(id);
            orderType.SetReadOnly();

            ResourceType complexType = new ResourceType(typeof(object), ResourceTypeKind.ComplexType, null, "foo", "Address", false);
            ResourceType collectionOfPrimitive = ResourceType.GetCollectionResourceType(ResourceType.GetPrimitiveResourceType(typeof(int)));
            ResourceType collectionOfComplex = ResourceType.GetCollectionResourceType(complexType);
            ResourceType collectionOfCustomer = ResourceType.GetEntityCollectionResourceType(customerType);
            ResourceType collectionOfOrder = ResourceType.GetEntityCollectionResourceType(orderType);

            var types = ResourceTypeUtils.GetPrimitiveResourceTypes().Concat(new ResourceType[] { null, customerType, orderType, complexType, collectionOfPrimitive, collectionOfComplex, collectionOfCustomer, collectionOfOrder });
            var resultSetsOrPathExpressions = new object[] { null, customerSet, new ResourceSetPathExpression("p1/Foo") };
            var parameters = types.Except(new[] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)) }).Select(t => t != null ? new ServiceActionParameter[] { new ServiceActionParameter("p1", t) } : new ServiceActionParameter[0]);
            parameters = parameters.Concat(types.Except(new[] { ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)), null }).ToList().Combinations(2).Select(tt => new ServiceActionParameter[] { new ServiceActionParameter("p1", tt[0]), new ServiceActionParameter("p2", tt[1]) }));
            var operationParameterBindings = new OperationParameterBindingKind[] { OperationParameterBindingKind.Never, OperationParameterBindingKind.Sometimes, OperationParameterBindingKind.Always };

            AstoriaTestNS.TestUtil.RunCombinations(
                types, resultSetsOrPathExpressions, parameters, operationParameterBindings,
                (returnType, resultSetOrPathExpression, paramList, operationParameterBindingKind) =>
            {
                ServiceAction action = null;
                ResourceSet resourceSet = resultSetOrPathExpression as ResourceSet;
                ResourceSetPathExpression pathExpression = resultSetOrPathExpression as ResourceSetPathExpression;
                bool bindable = (operationParameterBindingKind == OperationParameterBindingKind.Always || operationParameterBindingKind == OperationParameterBindingKind.Sometimes);
                Exception e = null;

                try
                {
                    if (pathExpression != null)
                    {
                        bindable = true;
                        action = new ServiceAction("foo", returnType, OperationParameterBindingKind.Sometimes, paramList, pathExpression);
                    }
                    else
                    {
                        action = new ServiceAction("foo", returnType, resourceSet, operationParameterBindingKind, paramList);
                    }
                }
                catch (Exception ex)
                {
                    e = ex;
                }
                if (resourceSet != null && operationParameterBindingKind != OperationParameterBindingKind.Never)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "When 'returnType' is an entity type or an entity collection type, 'resultSetPathExpression' and 'resultSet' cannot be both null and the resource type of the result set must be assignable from 'returnType'.");
                }
                else if (returnType != null && (returnType.ResourceTypeKind == ResourceTypeKind.EntityType || returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection) &&
                    (resourceSet == null && pathExpression == null ||
                    resourceSet != null && returnType.ResourceTypeKind == ResourceTypeKind.EntityType && resourceSet.ResourceType != returnType ||
                    resourceSet != null && returnType.ResourceTypeKind == ResourceTypeKind.EntityCollection && resourceSet.ResourceType != ((EntityCollectionResourceType)returnType).ItemType))
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "When 'returnType' is an entity type or an entity collection type, 'resultSetPathExpression' and 'resultSet' cannot be both null and the resource type of the result set must be assignable from 'returnType'.");
                }
                else if ((returnType == null || returnType.ResourceTypeKind != ResourceTypeKind.EntityCollection && returnType.ResourceTypeKind != ResourceTypeKind.EntityType) && resourceSet != null)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "'resultSet' must be null when 'returnType' is null, not an entity type or not an entity collection type.");
                }
                else if ((returnType == null || returnType.ResourceTypeKind != ResourceTypeKind.EntityCollection && returnType.ResourceTypeKind != ResourceTypeKind.EntityType) && pathExpression != null)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "'resultSetPathExpression' must be null when 'returnType' is null, not an entity type or not an entity collection type.");
                }
                else if (returnType == ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream)))
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "The resource type 'Edm.Stream' is not a type that can be returned by a function or action. A function or action can only return values of an entity type, an entity collection type, a complex type, a collection type or any primitive type, other than the stream type.\r\nParameter name: returnType");
                }
                else if (paramList.Length > 0 && paramList.Skip(bindable ? 1 : 0).Any(p => p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType || p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection))
                {
                    var param = paramList.Skip(bindable ? 1 : 0).First(p => p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityType || p.ParameterType.ResourceTypeKind == ResourceTypeKind.EntityCollection);
                    var parameterTypeKind = param.ParameterType.ResourceTypeKind;
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, string.Format("The '{0}' parameter is of resource type kind '{1}' and it is not the binding parameter. Parameter of type kind '{1}' is only supported for the binding parameter.", param.Name, parameterTypeKind));
                }
                else if (pathExpression != null && !bindable)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "The binding parameter type must be an entity type or an entity collection type when 'resultSetPathExpression' is not null.");
                }
                else if (bindable && paramList.Length == 0)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "Bindable actions or functions must have at least one parameter, where the first parameter is the binding parameter.\r\nParameter name: operationParameterBindingKind");
                }
                else if (pathExpression != null && bindable && paramList.First().ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType && paramList.First().ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "The binding parameter type must be an entity type or an entity collection type when 'resultSetPathExpression' is not null.");
                }
                else if (paramList.Length > 0 && bindable && paramList[0].ParameterType.ResourceTypeKind != ResourceTypeKind.EntityType && paramList[0].ParameterType.ResourceTypeKind != ResourceTypeKind.EntityCollection)
                {
                    ExceptionUtils.IsExpectedException<ArgumentException>(e, "An action's binding parameter must be of type Entity or EntityCollection.\r\nParameter name: parameters");
                }
                else
                {
                    Assert.IsNull(e, "Received exception but expected none. Exception message: {0}", e == null ? string.Empty : e.Message);
                    Assert.IsNotNull(action, "Action should be constructed.");

                    Assert.AreEqual("foo", action.Name, "unexpected name");
                    Assert.AreEqual(returnType, action.ReturnType, "unexpected return type");
                    Assert.AreEqual(resourceSet, action.ResourceSet, "unexpected result set");
                    Assert.AreEqual(pathExpression, action.ResultSetPathExpression, "unexpected path expression");
                    Assert.IsTrue(!bindable || action.BindingParameter == action.Parameters.First(), "unexpected binding parameter");
                    Assert.IsTrue(action.Method == "POST", "HttpMethod must be POST for ServiceActions.");
                    Assert.IsTrue(action.ResourceSet == null || action.ResultSetPathExpression == null, "'resultSet' and 'resultSetPathExpression' cannot be both set by the constructor.");
                }
            });
        }
        private void PopulateTestMetadata()
        {
            ResourceType entityType = new ResourceType(typeof(TestEntityType), ResourceTypeKind.EntityType, null, "AstoriaUnitTests.Tests.Server", "TestEntityType", false);
            entityType.CanReflectOnInstanceType = true;
            entityType.AddProperty(new ResourceProperty("ID", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(Int32))));
            entityType.AddProperty(new ResourceProperty("Name", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(String))));
            entityType.AddProperty(new ResourceProperty("Spatial", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(Geography))));
            entityType.AddProperty(new ResourceProperty("Point", ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(GeographyPoint))));
            entityType.SetReadOnly();

            serviceFactory.AddResourceType(entityType);

            ResourceSet entitySet = new ResourceSet("Entities", entityType);
            entitySet.SetReadOnly();
            serviceFactory.AddResourceSet(entitySet);
        }
Example #19
0
        private static DataServiceProviderWrapper CreateProvider(out DataServiceConfiguration config, out DataServiceOperationContext operationContext)
        {
            var baseUri = new Uri("http://localhost");
            var host = new DataServiceHostSimulator()
            {
                AbsoluteServiceUri = baseUri,
                AbsoluteRequestUri = new Uri(baseUri.AbsoluteUri + "/$metadata", UriKind.Absolute),
                RequestHttpMethod = "GET",
                RequestAccept = "application/xml+atom",
                RequestVersion = "4.0",
                RequestMaxVersion = "4.0",
            };

            operationContext = new DataServiceOperationContext(host);
            var dataService = new DataServiceSimulator() { OperationContext = operationContext };
            operationContext.InitializeAndCacheHeaders(dataService);

            DataServiceProviderSimulator providerSimulator = new DataServiceProviderSimulator();
            providerSimulator.ContainerNamespace = "MyModel";
            providerSimulator.ContainerName = "CustomersContainer";

            ResourceType customerEntityType = new ResourceType(
                typeof(object), ResourceTypeKind.EntityType, null, "MyModel", "Customer", false)
            { 
                CanReflectOnInstanceType = false 
            };

            ResourcePropertyKind idPropertyKind = ResourcePropertyKind.Primitive | ResourcePropertyKind.Key;
            ResourceProperty idProperty = new ResourceProperty(
                "Id", idPropertyKind, ResourceType.GetPrimitiveResourceType(typeof(int)))
            { 
                CanReflectOnInstanceTypeProperty = false 
            };
            customerEntityType.AddProperty(idProperty);

            ResourcePropertyKind firstNamePropertyKind = ResourcePropertyKind.Primitive | ResourcePropertyKind.Key;
            ResourceProperty firstNameProperty = new ResourceProperty(
                "FirstName", firstNamePropertyKind, ResourceType.GetPrimitiveResourceType(typeof(string)))
            {
                CanReflectOnInstanceTypeProperty = false
            };
            customerEntityType.AddProperty(firstNameProperty);            
            
            customerEntityType.SetReadOnly();
            providerSimulator.AddResourceType(customerEntityType);

            ResourceSet customerSet = new ResourceSet("Customers", customerEntityType);
            customerSet.SetReadOnly();
            providerSimulator.AddResourceSet(customerSet);

            config = new DataServiceConfiguration(providerSimulator);
            config.SetEntitySetAccessRule("*", EntitySetRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = ODataProtocolVersion.V4;

            IDataServiceProviderBehavior providerBehavior = DataServiceProviderBehavior.CustomDataServiceProviderBehavior;
            DataServiceStaticConfiguration staticConfig = new DataServiceStaticConfiguration(dataService.Instance.GetType(), providerSimulator);

            DataServiceProviderWrapper provider = new DataServiceProviderWrapper(
                new DataServiceCacheItem(config, staticConfig), providerSimulator, providerSimulator, dataService, false);

            dataService.ProcessingPipeline = new DataServiceProcessingPipeline();
            dataService.Provider = provider;
            provider.ProviderBehavior = providerBehavior;
            dataService.ActionProvider = DataServiceActionProviderWrapper.Create(dataService);
#if DEBUG
            dataService.ProcessingPipeline.SkipDebugAssert = true;
#endif
            operationContext.RequestMessage.InitializeRequestVersionHeaders(VersionUtil.ToVersion(config.DataServiceBehavior.MaxProtocolVersion));
            return provider;
        }
Example #20
0
        public void AddNamedStreamTest()
        {
            ResourceType type1 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, null, "namespace", "type1", true);
            type1.CanReflectOnInstanceType = false;
            ResourceProperty id = new ResourceProperty("ID", ResourcePropertyKind.Key | ResourcePropertyKind.Primitive, ResourceType.GetPrimitiveResourceType(typeof(int)));
            type1.AddProperty(id);
            id.CanReflectOnInstanceTypeProperty = false;

            ResourceType type2 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, type1, "namespace", "type2", false);
            type2.AddProperty(new ResourceProperty("Stream1", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream))));
            type2.AddProperty(new ResourceProperty("Stream2", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream))));

            ResourceType type3 = new ResourceType(typeof(object), ResourceTypeKind.EntityType, type2, "namespace", "type3", false);
            type3.AddProperty(new ResourceProperty("Stream3", ResourcePropertyKind.Stream, ResourceType.GetPrimitiveResourceType(typeof(System.IO.Stream))));

            Assert.AreEqual(0, type1.GetNamedStreams().Count(), "Wrong count");
            Assert.AreEqual(0, type1.GetNamedStreamsDeclaredOnThisType().Count(), "Wrong count");
            
            Assert.AreEqual(2, type2.GetNamedStreams().Count(), "Wrong count");
            Assert.IsNotNull(type2.GetNamedStreams().Single(s => s.Name == "Stream1"), "Unexpected null");
            Assert.IsNotNull(type2.GetNamedStreams().Single(s => s.Name == "Stream2"), "Unexpected null");
            
            Assert.AreEqual(2, type2.GetNamedStreamsDeclaredOnThisType().Count(), "Wrong count");
            Assert.IsNotNull(type2.GetNamedStreamsDeclaredOnThisType().Single(s => s.Name == "Stream1"), "Unexpected null");
            Assert.IsNotNull(type2.GetNamedStreamsDeclaredOnThisType().Single(s => s.Name == "Stream2"), "Unexpected null");
            
            Assert.AreEqual(3, type3.GetNamedStreams().Count(), "Wrong count");
            Assert.IsNotNull(type3.GetNamedStreams().Single(s => s.Name == "Stream1"), "Unexpected null");
            Assert.IsNotNull(type3.GetNamedStreams().Single(s => s.Name == "Stream2"), "Unexpected null");
            Assert.IsNotNull(type3.GetNamedStreams().Single(s => s.Name == "Stream3"), "Unexpected null");

            Assert.AreEqual(1, type3.GetNamedStreamsDeclaredOnThisType().Count(), "Wrong count");
            Assert.IsNotNull(type3.GetNamedStreamsDeclaredOnThisType().Single(s => s.Name == "Stream3"), "Unexpected null");

            type3.SetReadOnly();

            Assert.AreEqual(0, type1.GetNamedStreams().Count(), "Wrong count");
            Assert.AreEqual(0, type1.GetNamedStreamsDeclaredOnThisType().Count(), "Wrong count");

            Assert.AreEqual(2, type2.GetNamedStreams().Count(), "Wrong count");
            Assert.IsNotNull(type2.GetNamedStreams().Single(s => s.Name == "Stream1"), "Unexpected null");
            Assert.IsNotNull(type2.GetNamedStreams().Single(s => s.Name == "Stream2"), "Unexpected null");

            Assert.AreEqual(2, type2.GetNamedStreamsDeclaredOnThisType().Count(), "Wrong count");
            Assert.IsNotNull(type2.GetNamedStreamsDeclaredOnThisType().Single(s => s.Name == "Stream1"), "Unexpected null");
            Assert.IsNotNull(type2.GetNamedStreamsDeclaredOnThisType().Single(s => s.Name == "Stream2"), "Unexpected null");

            Assert.AreEqual(3, type3.GetNamedStreams().Count(), "Wrong count");
            Assert.IsNotNull(type3.GetNamedStreams().Single(s => s.Name == "Stream1"), "Unexpected null");
            Assert.IsNotNull(type3.GetNamedStreams().Single(s => s.Name == "Stream2"), "Unexpected null");
            Assert.IsNotNull(type3.GetNamedStreams().Single(s => s.Name == "Stream3"), "Unexpected null");

            Assert.AreEqual(1, type3.GetNamedStreamsDeclaredOnThisType().Count(), "Wrong count");
            Assert.IsNotNull(type3.GetNamedStreamsDeclaredOnThisType().Single(s => s.Name == "Stream3"), "Unexpected null");
        }