Пример #1
0
        public void ApplyTo_NewQueryReturned_GivenQueryable()
        {
            // Arrange
            ETag etagCustomer = new ETag {
                EntityType = typeof(Customer)
            };
            dynamic etag = etagCustomer;

            etag.FirstName = "Foo";

            // Act
            IQueryable queryable = etagCustomer.ApplyTo(_customers.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable <Customer> actualCustomers = Assert.IsAssignableFrom <IEnumerable <Customer> >(queryable);

            Assert.Equal(
                new[] { 1 },
                actualCustomers.Select(customer => customer.ID));
            MethodCallExpression methodCall = queryable.Expression as MethodCallExpression;

            Assert.NotNull(methodCall);
            Assert.Equal(2, methodCall.Arguments.Count);
            Assert.Equal(@"Param_0 => (Param_0.FirstName == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.String]).TypedProperty)",
                         methodCall.Arguments[1].ToString());
        }
Пример #2
0
        public void ApplyTo_NewQueryReturned_IsIfNoneMatchWithMultipleConcurrencyProperties()
        {
            // Arrange
            ETag etagCustomer = new ETag {
                EntityType = typeof(Customer), IsIfNoneMatch = true
            };
            dynamic etag = etagCustomer;

            etag.FirstName = "Def";
            etag.LastName  = "Xyz";

            // Act
            IQueryable queryable = etagCustomer.ApplyTo(_customers.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable <Customer> actualCustomers = Assert.IsAssignableFrom <IEnumerable <Customer> >(queryable);

            Assert.Equal(
                new[] { 1, 2 },
                actualCustomers.Select(customer => customer.ID));
            MethodCallExpression methodCall = queryable.Expression as MethodCallExpression;

            Assert.NotNull(methodCall);
            Assert.Equal(2, methodCall.Arguments.Count);
            Assert.Equal(
                @"Param_0 => Not(((Param_0.FirstName == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.String]).TypedProperty) "
                + "AndAlso (Param_0.LastName == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.String]).TypedProperty)))",
                methodCall.Arguments[1].ToString());
        }
Пример #3
0
        public void ApplyToNonGenericThrows_IfPassedAnIQueryableOfTheWrongType()
        {
            // Arrange
            ETag <Customer> etagCustomer = new ETag <Customer> {
                IsIfNoneMatch = true
            };
            IQueryable query = Enumerable.Empty <int>().AsQueryable();

            // Act & Assert
            Assert.Throws <ArgumentException>(
                () => etagCustomer.ApplyTo(query),
                "Cannot apply ETag of 'System.Web.OData.Formatter.Serialization.Models.Customer' to IQueryable of " +
                "'System.Int32'.\r\nParameter name: query");
        }
Пример #4
0
        public void ApplyTo_SameQueryReturned_GivenQueryableAndETagAny()
        {
            // Arrange
            var any = new ETag {
                IsAny = true
            };
            var customers = _customers.AsQueryable();

            // Act
            var queryable = any.ApplyTo(customers);

            // Assert
            Assert.NotNull(queryable);
            Assert.Same(queryable, customers);
        }
        public void ApplyTo_NewQueryReturned_GivenQueryable()
        {
            // Arrange
            ETag<Customer> etagCustomer = new ETag<Customer>();
            dynamic etag = etagCustomer;
            etag.FirstName = "Foo";

            // Act
            IQueryable queryable = etagCustomer.ApplyTo(_customers.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable<Customer> actualCustomers = Assert.IsAssignableFrom<IEnumerable<Customer>>(queryable);
            Assert.Equal(
                new[] { 1 },
                actualCustomers.Select(customer => customer.ID));
        }
        public void ApplyTo_NewQueryReturned_GivenQueryable()
        {
            // Arrange
            ETag<Customer> etagCustomer = new ETag<Customer>();
            dynamic etag = etagCustomer;
            etag.FirstName = "Foo";

            // Act
            IQueryable queryable = etagCustomer.ApplyTo(_customers.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable<Customer> actualCustomers = Assert.IsAssignableFrom<IEnumerable<Customer>>(queryable);
            Assert.Equal(
                new[] { 1 },
                actualCustomers.Select(customer => customer.ID));
            MethodCallExpression methodCall = queryable.Expression as MethodCallExpression;
            Assert.NotNull(methodCall);
            Assert.Equal(2, methodCall.Arguments.Count);
            Assert.Equal(@"Param_0 => (Param_0.FirstName == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.String]).TypedProperty)",
                methodCall.Arguments[1].ToString());
        }
Пример #7
0
        public void ApplyTo_SameQueryReturned_GivenQueryableAndETagAny()
        {
            // Arrange
            var any = new ETag { IsAny = true };
            var customers = _customers.AsQueryable();

            // Act
            var queryable = any.ApplyTo(customers);

            // Assert
            Assert.NotNull(queryable);
            Assert.Same(queryable, customers);
        }
Пример #8
0
        public void ApplyTo_NewQueryReturned_IsIfNoneMatchWithMultipleConcurrencyProperties()
        {
            // Arrange
            ETag etagCustomer = new ETag { EntityType = typeof(Customer), IsIfNoneMatch = true };
            dynamic etag = etagCustomer;
            etag.FirstName = "Def";
            etag.LastName = "Xyz";

            // Act
            IQueryable queryable = etagCustomer.ApplyTo(_customers.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable<Customer> actualCustomers = Assert.IsAssignableFrom<IEnumerable<Customer>>(queryable);
            Assert.Equal(
                new[] { 1, 2 },
                actualCustomers.Select(customer => customer.ID));
            MethodCallExpression methodCall = queryable.Expression as MethodCallExpression;
            Assert.NotNull(methodCall);
            Assert.Equal(2, methodCall.Arguments.Count);
            Assert.Equal(
                @"Param_0 => Not(((Param_0.FirstName == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.String]).TypedProperty) "
                + "AndAlso (Param_0.LastName == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.String]).TypedProperty)))",
                methodCall.Arguments[1].ToString());
        }
        public void ApplyToNonGenericThrows_IfPassedAnIQueryableOfTheWrongType()
        {
            // Arrange
            ETag<Customer> etagCustomer = new ETag<Customer> { IsIfNoneMatch = true };
            IQueryable query = Enumerable.Empty<int>().AsQueryable();

            // Act & Assert
            Assert.Throws<ArgumentException>(
                () => etagCustomer.ApplyTo(query),
                "Cannot apply ETag of 'System.Web.OData.Formatter.Serialization.Models.Customer' to IQueryable of " +
                "'System.Int32'.\r\nParameter name: query");
        }
Пример #10
0
        public void ApplyTo_NewQueryReturned_ForInteger(sbyte byteVal, short shortVal, bool ifMatch, IList <int> expect)
        {
            // Arrange
            var mycustomers = new List <MyETagOrder>
            {
                new MyETagOrder
                {
                    ID       = 1,
                    ByteVal  = 7,
                    ShortVal = 8
                },
                new MyETagOrder
                {
                    ID       = 2,
                    ByteVal  = SByte.MaxValue,
                    ShortVal = Int16.MaxValue
                },
                new MyETagOrder
                {
                    ID       = 3,
                    ByteVal  = SByte.MinValue,
                    ShortVal = Int16.MinValue
                },
            };
            IETagHandler handerl = new DefaultODataETagHandler();
            Dictionary <string, object> properties = new Dictionary <string, object>
            {
                { "ByteVal", byteVal },
                { "ShortVal", shortVal }
            };
            EntityTagHeaderValue etagHeaderValue = handerl.CreateETag(properties);

            HttpRequestMessage request      = new HttpRequestMessage();
            HttpConfiguration  cofiguration = new HttpConfiguration();

            request.SetConfiguration(cofiguration);

            var builder = new ODataConventionModelBuilder();

            builder.EntitySet <MyETagOrder>("Orders");
            IEdmModel               model       = builder.GetEdmModel();
            IEdmEntityType          order       = model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(e => e.Name == "MyETagOrder");
            IEdmEntitySet           orders      = model.FindDeclaredEntitySet("Orders");
            Mock <ODataPathSegment> mockSegment = new Mock <ODataPathSegment> {
                CallBase = true
            };

            mockSegment.Setup(s => s.GetEdmType(null)).Returns(order);
            mockSegment.Setup(s => s.GetNavigationSource(null)).Returns(orders);
            ODataPath odataPath = new ODataPath(new[] { mockSegment.Object });

            request.ODataProperties().Path  = odataPath;
            request.ODataProperties().Model = model;

            ETag etagCustomer = request.GetETag(etagHeaderValue);

            etagCustomer.EntityType    = typeof(MyETagOrder);
            etagCustomer.IsIfNoneMatch = !ifMatch;

            // Act
            IQueryable queryable = etagCustomer.ApplyTo(mycustomers.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IEnumerable <MyETagOrder> actualOrders = Assert.IsAssignableFrom <IEnumerable <MyETagOrder> >(queryable);

            Assert.Equal(expect, actualOrders.Select(c => c.ID));
            MethodCallExpression methodCall = queryable.Expression as MethodCallExpression;

            Assert.NotNull(methodCall);
            Assert.Equal(2, methodCall.Arguments.Count);

            if (ifMatch)
            {
                Assert.Equal(
                    "Param_0 => ((Param_0.ByteVal == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.SByte]).TypedProperty) " +
                    "AndAlso (Param_0.ShortVal == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.Int16]).TypedProperty))",
                    methodCall.Arguments[1].ToString());
            }
            else
            {
                Assert.Equal(
                    "Param_0 => Not(((Param_0.ByteVal == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.SByte]).TypedProperty) " +
                    "AndAlso (Param_0.ShortVal == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.Int16]).TypedProperty)))",
                    methodCall.Arguments[1].ToString());
            }
        }
Пример #11
0
        private HttpResponseMessage CreateQueryResponse(
            IQueryable query, IEdmType edmType, bool isIfNoneMatch, ETag etag)
        {
            IEdmTypeReference typeReference = GetTypeReference(edmType);
            BaseSingleResult singleResult = null;
            HttpResponseMessage response = null;

            if (typeReference.IsPrimitive())
            {
                if (this.shouldReturnCount || this.shouldWriteRawValue)
                {
                    var rawResult = new RawResult(query, typeReference, this.Api.Context);
                    singleResult = rawResult;
                    response = this.Request.CreateResponse(HttpStatusCode.OK, rawResult);
                }
                else
                {
                    var primitiveResult = new PrimitiveResult(query, typeReference, this.Api.Context);
                    singleResult = primitiveResult;
                    response = this.Request.CreateResponse(HttpStatusCode.OK, primitiveResult);
                }
            }

            if (typeReference.IsComplex())
            {
                var complexResult = new ComplexResult(query, typeReference, this.Api.Context);
                singleResult = complexResult;
                response = this.Request.CreateResponse(HttpStatusCode.OK, complexResult);
            }

            if (typeReference.IsEnum())
            {
                if (this.shouldWriteRawValue)
                {
                    var rawResult = new RawResult(query, typeReference, this.Api.Context);
                    singleResult = rawResult;
                    response = this.Request.CreateResponse(HttpStatusCode.OK, rawResult);
                }
                else
                {
                    var enumResult = new EnumResult(query, typeReference, this.Api.Context);
                    singleResult = enumResult;
                    response = this.Request.CreateResponse(HttpStatusCode.OK, enumResult);
                }
            }

            if (singleResult != null)
            {
                if (singleResult.Result == null)
                {
                    // Per specification, If the property is single-valued and has the null value,
                    // the service responds with 204 No Content.
                    return this.Request.CreateResponse(HttpStatusCode.NoContent);
                }

                return response;
            }

            if (typeReference.IsCollection())
            {
                var elementType = typeReference.AsCollection().ElementType();
                if (elementType.IsPrimitive() || elementType.IsEnum())
                {
                    return this.Request.CreateResponse(
                        HttpStatusCode.OK, new NonResourceCollectionResult(query, typeReference, this.Api.Context));
                }

                return this.Request.CreateResponse(
                    HttpStatusCode.OK, new ResourceSetResult(query, typeReference, this.Api.Context));
            }

            var entityResult = query.SingleOrDefault();
            if (entityResult == null)
            {
                return this.Request.CreateResponse(HttpStatusCode.NoContent);
            }

            // Check the ETag here
            if (etag != null)
            {
                // request with If-Match header, if match, then should return whole content
                // request with If-Match header, if not match, then should return 412
                // request with If-None-Match header, if match, then should return 304
                // request with If-None-Match header, if not match, then should return whole content
                etag.EntityType = query.ElementType;
                query = etag.ApplyTo(query);
                entityResult = query.SingleOrDefault();
                if (entityResult == null && !isIfNoneMatch)
                {
                    return this.Request.CreateResponse(HttpStatusCode.PreconditionFailed);
                }
                else if (entityResult == null)
                {
                    return this.Request.CreateResponse(HttpStatusCode.NotModified);
                }
            }

            // Using reflection to create response for single entity so passed in parameter is not object type,
            // but will be type of real entity type, then EtagMessageHandler can be used to set ETAG header
            // when response is single entity.
            // There are three HttpRequestMessageExtensions class defined in different assembles
            var genericMethod = typeof(System.Net.Http.HttpRequestMessageExtensions).GetMethods()
                .Where(m => m.Name == "CreateResponse" && m.GetParameters().Length == 3);
            var method = genericMethod.FirstOrDefault().MakeGenericMethod(query.ElementType);
            response = method.Invoke(null, new object[] { this.Request, HttpStatusCode.OK, entityResult })
                as HttpResponseMessage;
            return response;
        }
Пример #12
0
        public void ApplyTo_NewQueryReturned_ForDouble(double value, bool ifMatch, IList <int> expect)
        {
            // Arrange
            var myCustomers = new List <MyETagCustomer>
            {
                new MyETagCustomer
                {
                    ID         = 1,
                    DoubleETag = 1.0,
                },
                new MyETagCustomer
                {
                    ID         = 2,
                    DoubleETag = 1.1,
                },
                new MyETagCustomer
                {
                    ID         = 3,
                    DoubleETag = 1.0,
                },
            };

            IETagHandler handerl = new DefaultODataETagHandler();
            Dictionary <string, object> properties = new Dictionary <string, object> {
                { "DoubleETag", value }
            };
            EntityTagHeaderValue etagHeaderValue = handerl.CreateETag(properties);

            HttpRequestMessage request = new HttpRequestMessage();

            var builder = new ODataConventionModelBuilder();

            builder.EntitySet <MyETagCustomer>("Customers");
            IEdmModel      model     = builder.GetEdmModel();
            IEdmEntityType customer  = model.SchemaElements.OfType <IEdmEntityType>().FirstOrDefault(e => e.Name == "MyEtagCustomer");
            IEdmEntitySet  customers = model.FindDeclaredEntitySet("Customers");
            ODataPath      odataPath = new ODataPath(new[] { new EntitySetSegment(customers) });

            request.EnableHttpDependencyInjectionSupport(model);
            request.ODataProperties().Path = odataPath;

            ETag etagCustomer = request.GetETag(etagHeaderValue);

            etagCustomer.EntityType    = typeof(MyETagCustomer);
            etagCustomer.IsIfNoneMatch = !ifMatch;

            // Act
            IQueryable queryable = etagCustomer.ApplyTo(myCustomers.AsQueryable());

            // Assert
            Assert.NotNull(queryable);
            IList <MyETagCustomer> actualCustomers = Assert.IsAssignableFrom <IEnumerable <MyETagCustomer> >(queryable).ToList();

            if (expect != null)
            {
                Assert.Equal(expect, actualCustomers.Select(c => c.ID));
            }

            MethodCallExpression methodCall = queryable.Expression as MethodCallExpression;

            Assert.NotNull(methodCall);
            Assert.Equal(2, methodCall.Arguments.Count);
            if (ifMatch)
            {
                Assert.Equal(
                    "Param_0 => (Param_0.DoubleETag == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.Double]).TypedProperty)",
                    methodCall.Arguments[1].ToString());
            }
            else
            {
                Assert.Equal(
                    "Param_0 => Not((Param_0.DoubleETag == value(System.Web.OData.Query.Expressions.LinqParameterContainer+TypedLinqParameterContainer`1[System.Double]).TypedProperty))",
                    methodCall.Arguments[1].ToString());
            }
        }