public virtual void QueryableUsesConfiguredAssembliesResolver_For_MappingDerivedTypes() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpActionExecutedContext actionExecutedContext = GetActionExecutedContext( "http://localhost:8080/QueryCompositionCustomer/?$filter=Id eq 2", QueryCompositionCustomerController.CustomerList.AsQueryable()); ODataModelBuilder modelBuilder = new ODataConventionModelBuilder(); modelBuilder.EntitySet <QueryCompositionCustomer>(typeof(QueryCompositionCustomer).Name); IEdmModel model = modelBuilder.GetEdmModel(); model.SetAnnotationValue <ClrTypeAnnotation>(model.FindType("System.Web.Http.OData.Query.QueryCompositionCustomer"), null); bool called = false; Mock <IAssembliesResolver> assembliesResolver = new Mock <IAssembliesResolver>(); assembliesResolver .Setup(r => r.GetAssemblies()) .Returns(new DefaultAssembliesResolver().GetAssemblies()) .Callback(() => { called = true; }) .Verifiable(); actionExecutedContext.Request.GetConfiguration().Services.Replace(typeof(IAssembliesResolver), assembliesResolver.Object); // Act attribute.OnActionExecuted(actionExecutedContext); // Assert Assert.True(called); }
public void InvalidActionReturnType_Throws(string actionName) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer?$skip=1"); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod(actionName)); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); Type returnType = actionDescriptor.ReturnType; object instance = returnType.IsArray ? Array.CreateInstance(returnType.GetElementType(), 5) : Activator.CreateInstance(returnType); context.Response.Content = new ObjectContent(returnType, instance, new JsonMediaTypeFormatter()); // Act & Assert Assert.Throws <InvalidOperationException>( () => attribute.OnActionExecuted(context), String.Format( "The action '{0}' on controller '{1}' with return type '{2}' cannot support querying. Ensure the type of the returned content is IEnumerable, IQueryable, or a generic form of either interface.", actionName, controllerDescriptor.ControllerName, actionDescriptor.ReturnType.FullName)); }
public static void Register(HttpConfiguration config) { config.Routes.MapODataRoute("Nephos", "sdata", GetImplicitEDM()); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); // Uncomment the following line of code to enable query support for actions with an IQueryable or IQueryable<T> return type. // To avoid processing unexpected or malicious queries, use the validation settings on QueryableAttribute to validate incoming queries. // For more information, visit http://go.microsoft.com/fwlink/?LinkId=279712. var queryAttribute = new QueryableAttribute() { AllowedQueryOptions = AllowedQueryOptions.All, // or just some: AllowedQueryOptions.Top | AllowedQueryOptions.Skip, MaxTop = 100, PageSize = 100, }; //config.EnableQuerySupport(queryAttribute); // no argument also allowed and then specify queryable attribute on controller config.EnableQuerySupport(); // To disable tracing in your application, please comment out or remove the following line of code // For more information, refer to: http://www.asp.net/web-api config.EnableSystemDiagnosticsTracing(); SDataMessageHandler sdataHandler = new SDataMessageHandler(); // optionally add mapper that's a work around for web api odata not supporting property name aiasing sdataHandler.AddContentMap(new DefaultMetadataMap()); sdataHandler.SetErrorResponseBuilder(new DefaultErrorResponseBuilder()); GlobalConfiguration.Configuration.MessageHandlers.Add(sdataHandler); }
public void Primitives_Cannot_Be_Used_By_Filter_And_OrderBy(string filter) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Primitive/?" + filter); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "Primitive", typeof(PrimitiveController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(PrimitiveController).GetMethod("GetIEnumerableOfInt")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new ObjectContent(typeof(object), new List <int>(), new JsonMediaTypeFormatter()); // Act and Assert attribute.OnActionExecuted(context); HttpResponseMessage response = context.Response; Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); Assert.IsAssignableFrom(typeof(ObjectContent), response.Content); Assert.IsType(typeof(HttpError), ((ObjectContent)response.Content).Value); Assert.Equal("Only $skip and $top OData query options are supported for this type.", ((HttpError)((ObjectContent)response.Content).Value).Message); }
public void Primitives_Can_Be_Used_For_Top_And_Skip(string filter) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Primitive/?" + filter); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "Primitive", typeof(PrimitiveController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(PrimitiveController).GetMethod("GetIEnumerableOfInt")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); HttpContent expectedResponse = new ObjectContent(typeof(object), new List <int>(), new JsonMediaTypeFormatter()); context.Response.Content = expectedResponse; // Act and Assert attribute.OnActionExecuted(context); HttpResponseMessage response = context.Response; Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(expectedResponse, response.Content); }
public void ApplyQuery_SingleEntity_ThrowsArgumentNull_QueryOptions() { QueryableAttribute attribute = new QueryableAttribute(); Assert.ThrowsArgumentNull( () => attribute.ApplyQuery(entity: 42, queryOptions: null), "queryOptions"); }
public void ApplyQuery_Throws_WithNullQueryOptions() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); // Act & Assert Assert.ThrowsArgumentNull(() => attribute.ApplyQuery(CustomerList.AsQueryable(), null), "queryOptions"); }
public void ValidateQuery_Throws_With_Null_Request() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); // Act & Assert Assert.ThrowsArgumentNull(() => attribute.ValidateQuery(null), "request"); }
public void ValidateQuery_Throws_WithNullQueryOptions() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); // Act & Assert Assert.ThrowsArgumentNull(() => attribute.ValidateQuery(new HttpRequestMessage(), null), "queryOptions"); }
public void ValidateQuery_Accepts_All_Supported_QueryNames(string queryName) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?" + queryName); // Act & Assert attribute.ValidateQuery(request); }
public void Ctor_Initializes_Properties() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); // Act & Assert Assert.Equal(HandleNullPropagationOption.Default, attribute.HandleNullPropagation); Assert.True(attribute.EnsureStableOrdering); }
public void OnActionExecuted_SingleResult_Returns400_IfQueryContainsNonSelectExpand() { HttpActionExecutedContext actionExecutedContext = GetActionExecutedContext("http://localhost/?$top=10", new Customer()); QueryableAttribute attribute = new QueryableAttribute(); attribute.OnActionExecuted(actionExecutedContext); Assert.Equal(HttpStatusCode.BadRequest, actionExecutedContext.Response.StatusCode); }
public void SingleOrDefault_IQueryableOfT_ZeroElementsInSequence_ReturnsNull() { IQueryable <Customer> queryable = Enumerable.Empty <Customer>().AsQueryable(); HttpActionDescriptor actionDescriptor = new Mock <HttpActionDescriptor>().Object; var result = QueryableAttribute.SingleOrDefault(queryable, actionDescriptor); Assert.Null(result); }
public void ApplyQuery_SingleEntity_ThrowsArgumentNull_Entity() { QueryableAttribute attribute = new QueryableAttribute(); ODataQueryOptions options = new ODataQueryOptions(new ODataQueryContext(EdmCoreModel.Instance, typeof(int)), new HttpRequestMessage()); Assert.ThrowsArgumentNull( () => attribute.ApplyQuery(entity: null, queryOptions: options), "entity"); }
public void SingleOrDefault_IQueryableOfT_OneElementInSequence_ReturnsElement() { Customer customer = new Customer(); IQueryable <Customer> queryable = new[] { customer }.AsQueryable(); HttpActionDescriptor actionDescriptor = new Mock <HttpActionDescriptor>().Object; var result = QueryableAttribute.SingleOrDefault(queryable, actionDescriptor); Assert.Same(customer, result); }
public void ValidateQuery_Throws_With_Null_Request() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(System.Web.Http.OData.Builder.TestModels.Customer), "Customers"), new HttpRequestMessage()); // Act & Assert Assert.ThrowsArgumentNull(() => attribute.ValidateQuery(null, options), "request"); }
public void OrderByAllowedPropertiesWithSpaces(string allowedProperties) { QueryableAttribute attribute = new QueryableAttribute(); attribute.AllowedOrderByProperties = allowedProperties; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customers/?$orderby=Id,Name"); ODataQueryOptions queryOptions = new ODataQueryOptions(ValidationTestHelper.CreateCustomerContext(), request); Assert.DoesNotThrow(() => attribute.ValidateQuery(request, queryOptions)); }
public void OrderByDisllowedPropertiesWithSpaces(string allowedProperties) { QueryableAttribute attribute = new QueryableAttribute(); attribute.AllowedOrderByProperties = allowedProperties; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customers/?$orderby=Id,Name"); ODataQueryOptions queryOptions = new ODataQueryOptions(ValidationTestHelper.CreateCustomerContext(), request); Assert.Throws <ODataException>(() => attribute.ValidateQuery(request, queryOptions), "Order by 'Name' is not allowed. To allow it, set the 'AllowedOrderByProperties' property on QueryableAttribute or QueryValidationSettings."); }
public void ApplyQuery_Accepts_All_Supported_QueryNames(string query) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?" + query); var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(System.Web.Http.OData.Builder.TestModels.Customer)), request); // Act & Assert Assert.DoesNotThrow(() => attribute.ApplyQuery(new List <System.Web.Http.OData.Builder.TestModels.Customer>().AsQueryable(), options)); }
public void OnActionExecuted_SingleResult_WithMoreThanASingleQueryResult_ThrowsInvalidOperationException() { // Arrange var customers = CustomerList.AsQueryable(); SingleResult result = SingleResult.Create(customers); HttpActionExecutedContext actionExecutedContext = GetActionExecutedContext("http://localhost/", result); QueryableAttribute attribute = new QueryableAttribute(); // Act and Assert Assert.Throws <InvalidOperationException>(() => attribute.OnActionExecuted(actionExecutedContext)); }
public void ValidateQuery_Accepts_All_Supported_QueryNames(string queryName) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?" + queryName + "=x"); var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(System.Web.Http.OData.Builder.TestModels.Customer), "Customers"), request); // Act & Assert attribute.ValidateQuery(request, options); }
public void GetFilters_ReturnsQueryableFilter_ForQueryableActions(string actionName) { HttpConfiguration config = new HttpConfiguration(); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(config, "FilterProviderTest", typeof(FilterProviderTestController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(FilterProviderTestController).GetMethod(actionName)); FilterInfo[] filters = new QueryFilterProvider(new QueryableAttribute()).GetFilters(config, actionDescriptor).ToArray(); Assert.Equal(1, filters.Length); Assert.Equal(FilterScope.Global, filters[0].Scope); QueryableAttribute filter = Assert.IsType <QueryableAttribute>(filters[0].Instance); }
public void QueryableOnActionUnknownOperatorStartingDollarSignThrows() { QueryableAttribute attribute = new QueryableAttribute(); HttpActionExecutedContext actionExecutedContext = GetActionExecutedContext( "http://localhost:8080/QueryCompositionCustomer?$orderby=Name desc&$unknown=12", QueryCompositionCustomerController.CustomerList.AsQueryable()); var exception = Assert.Throws <HttpResponseException>(() => attribute.OnActionExecuted(actionExecutedContext)); // QueryableAttribute will validate and throws Assert.Equal(HttpStatusCode.BadRequest, exception.Response.StatusCode); }
public void ApplyQuery_CallsApplyOnODataQueryOptions() { object entity = new object(); QueryableAttribute attribute = new QueryableAttribute(); ODataQueryContext context = new ODataQueryContext(EdmCoreModel.Instance, typeof(int)); HttpRequestMessage request = new HttpRequestMessage(); Mock <ODataQueryOptions> queryOptions = new Mock <ODataQueryOptions>(context, request); attribute.ApplyQuery(entity, queryOptions.Object); queryOptions.Verify(q => q.ApplyTo(entity, It.IsAny <ODataQuerySettings>()), Times.Once()); }
public void OnActionExecuted_SingleResult_ReturnsSingleItemEvenIfThereIsNoSelectExpand() { Customer customer = new Customer(); SingleResult singleResult = new SingleResult <Customer>(new Customer[] { customer }.AsQueryable()); HttpActionExecutedContext actionExecutedContext = GetActionExecutedContext("http://localhost/", singleResult); QueryableAttribute attribute = new QueryableAttribute(); attribute.OnActionExecuted(actionExecutedContext); Assert.Equal(HttpStatusCode.OK, actionExecutedContext.Response.StatusCode); Assert.Equal(customer, (actionExecutedContext.Response.Content as ObjectContent).Value); }
public void ValidateQuery_Sends_BadRequest_For_Unrecognized_QueryNames() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?$xxx"); // Act & Assert HttpResponseException responseException = Assert.Throws <HttpResponseException>( () => attribute.ValidateQuery(request)); Assert.Equal(HttpStatusCode.BadRequest, responseException.Response.StatusCode); }
public void ValidateSelectExpandOnly_ThrowsODataException_IfODataQueryOptionsHasNonSelectExpand(string parameter) { CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer))); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost?" + parameter); ODataQueryContext context = new ODataQueryContext(model.Model, typeof(Customer)); ODataQueryOptions queryOptions = new ODataQueryOptions(context, request); Assert.Throws <ODataException>( () => QueryableAttribute.ValidateSelectExpandOnly(queryOptions), "The requested resource is not a collection. Query options $filter, $orderby, $inlinecount, $skip, and $top can be applied only on collections."); }
public void ValidateQuery_Can_Override_Base() { // Arrange Mock <QueryableAttribute> mockAttribute = new Mock <QueryableAttribute>(); mockAttribute.Setup(m => m.ValidateQuery(It.IsAny <HttpRequestMessage>())).Callback(() => { }).Verifiable(); QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?$xxx"); // Act & Assert mockAttribute.Object.ValidateQuery(null); mockAttribute.Verify(); }
public void ValidateQuery_Sends_BadRequest_For_Unrecognized_QueryNames() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?$xxx"); var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(System.Web.Http.OData.Builder.TestModels.Customer), "Customers"), request); // Act & Assert HttpResponseException responseException = Assert.Throws <HttpResponseException>( () => attribute.ValidateQuery(request, options)); Assert.Equal(HttpStatusCode.BadRequest, responseException.Response.StatusCode); }
/// <summary> /// Initializes a new instance of the <see cref="TableFilterProvider"/> using the provided <see cref="QueryableAttribute"/> /// implementation for executing the query. /// </summary> public TableFilterProvider(IActionFilter queryFilter) { if (queryFilter == null) { throw new ArgumentNullException("queryFilter"); } this.queryFilter = new QueryableAttribute() { PageSize = TableUtils.PageSize }; this.queryFilterProvider = new QueryFilterProvider(queryFilter); this.tableFilter = new FilterInfo(new TableQueryFilter(), FilterScope.Global); }
public void UnknownQueryNotStartingWithDollarSignWorks() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer/?select"); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod("Get")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new ObjectContent(typeof(object), new List<Customer>(), new JsonMediaTypeFormatter()); // Act and Assert attribute.OnActionExecuted(context); Assert.Equal(HttpStatusCode.OK, context.Response.StatusCode); }
public void DifferentReturnTypeWorks(string methodName, object responseObject, bool isNoOp) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer/?$orderby=Name"); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod(methodName)); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new ObjectContent(typeof(object), responseObject, new JsonMediaTypeFormatter()); // Act and Assert attribute.OnActionExecuted(context); Assert.Equal(HttpStatusCode.OK, context.Response.StatusCode); Assert.True(context.Response.Content is ObjectContent); Assert.Equal(isNoOp, ((ObjectContent)context.Response.Content).Value == responseObject); }
public void OnActionExecuted_Throws_Null_Configuration() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer/?$orderby=Name"); HttpConfiguration config = new HttpConfiguration(); HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod("Get")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); Assert.ThrowsArgument( () => new QueryableAttribute().OnActionExecuted(context), "actionExecutedContext", String.Format("Request message does not contain an HttpConfiguration object.{0}Parameter name: actionExecutedContext", Environment.NewLine)); }
public void ValidateQuery_Sends_BadRequest_For_Unrecognized_QueryNames() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?$xxx"); var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(System.Web.Http.OData.Builder.TestModels.Customer), "Customers"), request); // Act & Assert HttpResponseException responseException = Assert.Throws<HttpResponseException>( () => attribute.ValidateQuery(request, options)); Assert.Equal(HttpStatusCode.BadRequest, responseException.Response.StatusCode); }
public void ValidateQuery_Can_Override_Base() { // Arrange Mock<QueryableAttribute> mockAttribute = new Mock<QueryableAttribute>(); mockAttribute.Setup(m => m.ValidateQuery(It.IsAny<HttpRequestMessage>())).Callback(() => { }).Verifiable(); QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?$xxx"); // Act & Assert mockAttribute.Object.ValidateQuery(null); mockAttribute.Verify(); }
public void Primitives_Cannot_Be_Used_By_Filter_And_OrderBy(string filter) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Primitive/?" + filter); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "Primitive", typeof(PrimitiveController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(PrimitiveController).GetMethod("GetIEnumerableOfInt")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new ObjectContent(typeof(object), new List<int>(), new JsonMediaTypeFormatter()); // Act and Assert attribute.OnActionExecuted(context); HttpResponseMessage response = context.Response; Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); Assert.IsAssignableFrom(typeof(ObjectContent), response.Content); Assert.IsType(typeof(HttpError), ((ObjectContent)response.Content).Value); Assert.Equal("Only $skip and $top OData query options are supported for this type.", ((HttpError)((ObjectContent)response.Content).Value).Message); }
public void NonGenericEnumerableReturnTypeThrows() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer/?$skip=1"); HttpConfiguration config = new HttpConfiguration(); config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod("GetNonGenericEnumerable")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new ObjectContent(typeof(IEnumerable), new NonGenericEnumerable(), new JsonMediaTypeFormatter()); // Act & Assert Assert.Throws<InvalidOperationException>( () => attribute.OnActionExecuted(context), "Cannot create an EDM model as the action 'QueryableAttribute' on controller 'GetNonGenericEnumerable' has a return type 'CustomerHighLevel' that does not implement IEnumerable<T>."); }
public void CreateQueryContext_ReturnsQueryContext_ForMatchingModelOnRequest() { var builder = new ODataConventionModelBuilder(); builder.EntitySet<QueryCompositionCustomer>("customers"); var model = builder.GetEdmModel(); var entityClrType = typeof(QueryCompositionCustomer); var config = new HttpConfiguration(); var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/"); request.SetEdmModel(model); var descriptor = new ReflectedHttpActionDescriptor(); descriptor.Configuration = config; var queryModel = new QueryableAttribute().GetModel(entityClrType, request, descriptor); Assert.NotNull(queryModel); Assert.Same(model, queryModel); Assert.False(descriptor.Properties.ContainsKey("MS_EdmModelSystem.Web.Http.OData.Query.QueryCompositionCustomer")); }
public void ApplyQuery_Accepts_All_Supported_QueryNames(string query) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?" + query); var model = new ODataModelBuilder().Add_Customer_EntityType().Add_Customers_EntitySet().GetEdmModel(); var options = new ODataQueryOptions(new ODataQueryContext(model, typeof(System.Web.Http.OData.Builder.TestModels.Customer)), request); // Act & Assert Assert.DoesNotThrow(() => attribute.ApplyQuery(new List<System.Web.Http.OData.Builder.TestModels.Customer>().AsQueryable(), options)); }
public void GetModel_ReturnsModel_ForNoModelOnRequest() { var entityClrType = typeof(QueryCompositionCustomer); var config = new HttpConfiguration(); var request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/"); var descriptor = new ReflectedHttpActionDescriptor(); descriptor.Configuration = config; var queryModel = new QueryableAttribute().GetModel(entityClrType, request, descriptor); Assert.NotNull(queryModel); Assert.Same(descriptor.Properties["MS_EdmModelSystem.Web.Http.OData.Query.QueryCompositionCustomer"], queryModel); }
public void NonGenericEnumerableReturnTypeThrows() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer/?$skip=1"); HttpConfiguration config = new HttpConfiguration(); config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always; request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod("GetNonGenericEnumerable")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new ObjectContent(typeof(object), new NonGenericEnumerable(), new JsonMediaTypeFormatter()); // Act & Assert Assert.Throws<InvalidOperationException>( () => attribute.OnActionExecuted(context), "The 'QueryableAttribute' type cannot be used with action 'GetNonGenericEnumerable' on controller 'CustomerHighLevel' because the return type 'System.Web.Http.OData.TestCommon.Models.NonGenericEnumerable' does not specify the type of the collection."); }
public void NonObjectContentResponse_ThrowsInvalidOperationException() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer?$skip=1"); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod("GetIEnumerableOfCustomer")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new StreamContent(new MemoryStream()); // Act & Assert Assert.Throws<InvalidOperationException>( () => attribute.OnActionExecuted(context), "Queries can not be applied to a response content of type 'System.Net.Http.StreamContent'. The response content must be an ObjectContent."); }
public void Primitives_Can_Be_Used_For_Top_And_Skip(string filter) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Primitive/?" + filter); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "Primitive", typeof(PrimitiveController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(PrimitiveController).GetMethod("GetIEnumerableOfInt")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); HttpContent expectedResponse = new ObjectContent(typeof(object), new List<int>(), new JsonMediaTypeFormatter()); context.Response.Content = expectedResponse; // Act and Assert attribute.OnActionExecuted(context); HttpResponseMessage response = context.Response; Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(expectedResponse, response.Content); }
public void InvalidActionReturnType_Throws(string actionName) { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer?$skip=1"); HttpConfiguration config = new HttpConfiguration(); request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config; HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod(actionName)); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); Type returnType = actionDescriptor.ReturnType; object instance = returnType.IsArray ? Array.CreateInstance(returnType.GetElementType(), 5) : Activator.CreateInstance(returnType); context.Response.Content = new ObjectContent(returnType, instance, new JsonMediaTypeFormatter()); // Act & Assert Assert.Throws<InvalidOperationException>( () => attribute.OnActionExecuted(context), String.Format( "The action '{0}' on controller '{1}' with return type '{2}' cannot support querying. Ensure the type of the returned content is IEnumerable, IQueryable, or a generic form of either interface.", actionName, controllerDescriptor.ControllerName, actionDescriptor.ReturnType.FullName)); }
public void ValidateQuery_Sends_BadRequest_For_Unrecognized_QueryNames() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/?$xxx"); // Act & Assert HttpResponseException responseException = Assert.Throws<HttpResponseException>( () => attribute.ValidateQuery(request)); Assert.Equal(HttpStatusCode.BadRequest, responseException.Response.StatusCode); }
public void UnknownQueryStartingWithDollarSignThrows() { // Arrange QueryableAttribute attribute = new QueryableAttribute(); HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customer/?$custom"); HttpConfiguration config = new HttpConfiguration(); request.SetConfiguration(config); HttpControllerContext controllerContext = new HttpControllerContext(config, new HttpRouteData(new HttpRoute()), request); HttpControllerDescriptor controllerDescriptor = new HttpControllerDescriptor(new HttpConfiguration(), "CustomerHighLevel", typeof(CustomerHighLevelController)); HttpActionDescriptor actionDescriptor = new ReflectedHttpActionDescriptor(controllerDescriptor, typeof(CustomerHighLevelController).GetMethod("Get")); HttpActionContext actionContext = new HttpActionContext(controllerContext, actionDescriptor); HttpActionExecutedContext context = new HttpActionExecutedContext(actionContext, null); context.Response = new HttpResponseMessage(HttpStatusCode.OK); context.Response.Content = new ObjectContent(typeof(IEnumerable<Customer>), new List<Customer>(), new JsonMediaTypeFormatter()); // Act and Assert HttpResponseException errorResponse = Assert.Throws<HttpResponseException>(() => attribute.OnActionExecuted(context)); Assert.Equal(HttpStatusCode.BadRequest, errorResponse.Response.StatusCode); }
public void OrderByDisllowedPropertiesWithSpaces(string allowedProperties) { QueryableAttribute attribute = new QueryableAttribute(); attribute.AllowedOrderByProperties = allowedProperties; HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, "http://localhost/Customers/?$orderby=Id,Name"); ODataQueryOptions queryOptions = new ODataQueryOptions(ValidationTestHelper.CreateCustomerContext(), request); Assert.Throws<ODataException>(() => attribute.ValidateQuery(request, queryOptions), "Order by 'Name' is not allowed. To allow it, set the 'AllowedOrderByProperties' property on QueryableAttribute or QueryValidationSettings."); }