public void ValidateSelectExpandQueryValidator_DepthChecks_DollarLevels(string expand, int maxExpansionDepth) { // Arrange SelectExpandQueryValidator validator = new SelectExpandQueryValidator(); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet <ODataLevelsTest.LevelsEntity>("Entities"); IEdmModel model = builder.GetEdmModel(); var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity)); context.DefaultQuerySettings.EnableExpand = true; context.RequestContainer = new MockServiceProvider(); var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context); selectExpandQueryOption.LevelsMaxLiteralExpansionDepth = 1; // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth }), string.Format( CultureInfo.CurrentCulture, MaxExpandDepthExceededErrorString, maxExpansionDepth)); ExceptionAssert.DoesNotThrow( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth + 1 })); }
public void Validate_Throws_LevelsMaxLiteralExpansionDepthGreaterThanMaxExpansionDepth() { // Arrange string expand = "Parent($levels=2)"; var validator = new SelectExpandQueryValidator(new DefaultQuerySettings { EnableExpand = true }); var builder = ODataConventionModelBuilderFactory.Create(); builder.EntitySet <ODataLevelsTest.LevelsEntity>("Entities"); IEdmModel model = builder.GetEdmModel(); var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity)); context.RequestContainer = new MockContainer(); var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context); selectExpandQueryOption.LevelsMaxLiteralExpansionDepth = 4; // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = 3 }), "'LevelsMaxLiteralExpansionDepth' should be less than or equal to 'MaxExpansionDepth'."); }
// This constructor is intended for unit testing only. internal SelectExpandQueryOption(string select, string expand, ODataQueryContext context) { if (context == null) { throw Error.ArgumentNull("context"); } if (String.IsNullOrEmpty(select) && String.IsNullOrEmpty(expand)) { throw Error.Argument(SRResources.SelectExpandEmptyOrNull); } IEdmEntityType entityType = context.ElementType as IEdmEntityType; if (entityType == null) { throw Error.Argument("context", SRResources.SelectNonEntity, context.ElementType.ToTraceString()); } Context = context; RawSelect = select; RawExpand = expand; Validator = new SelectExpandQueryValidator(); _queryOptionParser = new ODataQueryOptionParser( context.Model, context.ElementType, context.NavigationSource, new Dictionary <string, string> { { "$select", select }, { "$expand", expand } }); }
public void Validate_Throw_WithInvalidMaxExpansionDepth() { int maxExpansionDepth = -1; // Arrange string expand = "Parent($levels=1)"; var builder = ODataConventionModelBuilderFactory.Create(); builder.EntitySet <ODataLevelsTest.LevelsEntity>("Entities"); IEdmModel model = builder.GetEdmModel(); var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity)); context.RequestContainer = new MockContainer(); var validator = SelectExpandQueryValidator.GetSelectExpandQueryValidator(context); var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context); // Act & Assert #if NETCOREAPP3_1 ExceptionAssert.Throws <ArgumentOutOfRangeException>( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth }), "Value must be greater than or equal to 0. (Parameter 'value')\r\nActual value was -1."); #else ExceptionAssert.Throws <ArgumentOutOfRangeException>( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth }), "Value must be greater than or equal to 0.\r\nParameter name: value\r\nActual value was -1."); #endif }
public void Validate_DepthChecks_QuerySettings(string expand, int maxExpansionDepth) { // Arrange SelectExpandQueryValidator validator = new SelectExpandQueryValidator(new DefaultQuerySettings { EnableExpand = true }); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer))); ODataQueryContext queryContext = new ODataQueryContext(model.Model, typeof(Customer)); queryContext.RequestContainer = new MockContainer(); SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, queryContext); selectExpandQueryOption.LevelsMaxLiteralExpansionDepth = 1; IEdmStructuredType customerType = model.Model.SchemaElements.First(e => e.Name.Equals("Customer")) as IEdmStructuredType; ModelBoundQuerySettings querySettings = new ModelBoundQuerySettings(); querySettings.ExpandConfigurations.Add("Orders", new ExpandConfiguration { ExpandType = SelectExpandType.Allowed, MaxDepth = maxExpansionDepth }); model.Model.SetAnnotationValue(customerType, querySettings); // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth + 1 }), String.Format(CultureInfo.CurrentCulture, MaxExpandDepthExceededErrorString, maxExpansionDepth)); }
public void Validate_Throws_IfMaxDepthLessThanLevels(int level) { // Arrange string expand = string.Format("Parent($levels={0})", level + 1); var validator = new SelectExpandQueryValidator(new DefaultQuerySettings { EnableExpand = true }); var builder = new ODataConventionModelBuilder(); builder.EntitySet <ODataLevelsTest.LevelsEntity>("Entities"); IEdmModel model = builder.GetEdmModel(); var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity)); context.RequestContainer = new MockContainer(); var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context); IEdmStructuredType customerType = model.SchemaElements.First(e => e.Name.Equals("LevelsEntity")) as IEdmStructuredType; ModelBoundQuerySettings querySettings = new ModelBoundQuerySettings(); querySettings.ExpandConfigurations.Add("Parent", new ExpandConfiguration { ExpandType = SelectExpandType.Allowed, MaxDepth = level }); model.SetAnnotationValue(customerType, querySettings); // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = 0 }), String.Format(CultureInfo.CurrentCulture, MaxExpandDepthExceededErrorString, level)); }
/// <summary> /// Initializes a new instance of the <see cref="SelectExpandQueryOption"/> class. /// </summary> /// <param name="select">The $select query parameter value.</param> /// <param name="expand">The $select query parameter value.</param> /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information.</param> /// <param name="queryOptionParser">The <see cref="ODataQueryOptionParser"/> which is used to parse the query option.</param> public SelectExpandQueryOption(string select, string expand, ODataQueryContext context, ODataQueryOptionParser queryOptionParser) { if (context == null) { throw Error.ArgumentNull("context"); } if (String.IsNullOrEmpty(select) && String.IsNullOrEmpty(expand)) { throw Error.Argument(SRResources.SelectExpandEmptyOrNull); } if (queryOptionParser == null) { throw Error.ArgumentNull("queryOptionParser"); } IEdmEntityType entityType = context.ElementType as IEdmEntityType; if (entityType == null) { throw Error.Argument("context", SRResources.SelectNonEntity, context.ElementType.ToTraceString()); } Context = context; RawSelect = select; RawExpand = expand; Validator = new SelectExpandQueryValidator(); _queryOptionParser = queryOptionParser; }
/// <summary> /// Initializes a new instance of the <see cref="SelectExpandQueryOption"/> class. /// </summary> /// <param name="select">The $select query parameter value.</param> /// <param name="expand">The $expand query parameter value.</param> /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information.</param> /// <param name="queryOptionParser">The <see cref="ODataQueryOptionParser"/> which is used to parse the query option.</param> public SelectExpandQueryOption(string select, string expand, ODataQueryContext context, ODataQueryOptionParser queryOptionParser) { if (context == null) { throw Error.ArgumentNull("context"); } if (String.IsNullOrEmpty(select) && String.IsNullOrEmpty(expand)) { throw Error.Argument(SRResources.SelectExpandEmptyOrNull); } if (queryOptionParser == null) { throw Error.ArgumentNull("queryOptionParser"); } if (!(context.ElementType is IEdmStructuredType)) { throw Error.Argument(SRResources.SelectNonStructured, context.ElementType); } Context = context; RawSelect = select; RawExpand = expand; Validator = SelectExpandQueryValidator.GetSelectExpandQueryValidator(context); _queryOptionParser = queryOptionParser; }
// This constructor is intended for unit testing only. internal SelectExpandQueryOption(string select, string expand, ODataQueryContext context) { if (context == null) { throw Error.ArgumentNull("context"); } if (String.IsNullOrEmpty(select) && String.IsNullOrEmpty(expand)) { throw Error.Argument(SRResources.SelectExpandEmptyOrNull); } if (!(context.ElementType is IEdmStructuredType)) { throw Error.Argument("context", SRResources.SelectNonStructured, context.ElementType.ToTraceString()); } Context = context; RawSelect = select; RawExpand = expand; Validator = SelectExpandQueryValidator.GetSelectExpandQueryValidator(context); _queryOptionParser = new ODataQueryOptionParser( context.Model, context.ElementType, context.NavigationSource, new Dictionary <string, string> { { "$select", select }, { "$expand", expand } }, context.RequestContainer); }
public void ValidateThrowException_IfNotExpandable_QuerySettings() { // Arrange CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer))); ODataQueryContext queryContext = new ODataQueryContext(model.Model, typeof(Customer)); queryContext.RequestContainer = new MockContainer(); SelectExpandQueryValidator validator = SelectExpandQueryValidator.GetSelectExpandQueryValidator(queryContext); SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, "Orders", queryContext); IEdmStructuredType customerType = model.Model.SchemaElements.First(e => e.Name.Equals("Customer")) as IEdmStructuredType; ModelBoundQuerySettings querySettings = new ModelBoundQuerySettings(); querySettings.ExpandConfigurations.Add("Orders", new ExpandConfiguration { ExpandType = SelectExpandType.Disabled, MaxDepth = 0 }); model.Model.SetAnnotationValue(customerType, querySettings); // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()), "The property 'Orders' cannot be used in the $expand query option."); }
public void ValidateSelectExpandQueryValidator_Throws_NullOption() { // Arrange & Act & Assert SelectExpandQueryValidator validator = new SelectExpandQueryValidator(); ExceptionAssert.ThrowsArgumentNull(() => validator.Validate(null, new ODataValidationSettings()), "selectExpandQueryOption"); }
public void ValidateDoesNotThrow_IfExpansionDepthIsZero_QuerySettings() { // Arrange string expand = "Orders($expand=Customer($expand=Orders($expand=Customer($expand=Orders($expand=Customer)))))"; SelectExpandQueryValidator validator = new SelectExpandQueryValidator(new DefaultQuerySettings { EnableExpand = true }); CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer))); ODataQueryContext queryContext = new ODataQueryContext(model.Model, typeof(Customer)); queryContext.RequestContainer = new MockContainer(); SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, queryContext); IEdmStructuredType customerType = model.Model.SchemaElements.First(e => e.Name.Equals("Customer")) as IEdmStructuredType; ModelBoundQuerySettings querySettings = new ModelBoundQuerySettings(); querySettings.ExpandConfigurations.Add("Orders", new ExpandConfiguration { ExpandType = SelectExpandType.Allowed, MaxDepth = 0 }); model.Model.SetAnnotationValue(customerType, querySettings); // Act & Assert ExceptionAssert.DoesNotThrow( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = 0 })); }
public void ValidateDoesNotThrow_LevelsMaxLiteralExpansionDepthAndMaxExpansionDepth( int levelsMaxLiteralExpansionDepth, int maxExpansionDepth) { // Arrange string expand = "Parent($levels=2)"; var validator = new SelectExpandQueryValidator(new DefaultQuerySettings { EnableExpand = true }); var builder = ODataConventionModelBuilderFactory.Create(); builder.EntitySet <ODataLevelsTest.LevelsEntity>("Entities"); IEdmModel model = builder.GetEdmModel(); var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity)); context.RequestContainer = new MockContainer(); var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context); selectExpandQueryOption.LevelsMaxLiteralExpansionDepth = levelsMaxLiteralExpansionDepth; // Act & Assert ExceptionAssert.DoesNotThrow( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth })); }
public void ValidateSelectExpandQueryValidator_Throws_NullSettings() { // Arrange SelectExpandQueryValidator validator = new SelectExpandQueryValidator(); ODataQueryContext context = new ODataQueryContext(EdmCoreModel.Instance, typeof(int)); SelectExpandQueryOption option = new SelectExpandQueryOption("any", null, _queryContext); // Act & Assert ExceptionAssert.ThrowsArgumentNull(() => validator.Validate(option, null), "validationSettings"); }
public void ValidateDoesNotThrow_IfExpansionDepthIsZero() { string expand = "Orders($expand=Customer($expand=Orders($expand=Customer($expand=Orders($expand=Customer)))))"; SelectExpandQueryValidator validator = new SelectExpandQueryValidator(new DefaultQuerySettings { EnableExpand = true }); SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, _queryContext); ExceptionAssert.DoesNotThrow( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = 0 })); }
public void ValidateSelectExpandQueryValidator_Throws_IfNotAllowFilter() { // Arrange string expand = "Orders($filter=Amount eq 42)"; SelectExpandQueryValidator validator = new SelectExpandQueryValidator(); _queryContext.DefaultQuerySettings.EnableExpand = true; _queryContext.DefaultQuerySettings.EnableFilter = false; SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, _queryContext); // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()), "The property 'Amount' cannot be used in the $filter query option."); }
public void ValidateSelectExpandQueryValidator_Throws_IfNotAllowTop() { // Arrange string expand = "Orders($top=4)"; SelectExpandQueryValidator validator = new SelectExpandQueryValidator(); _queryContext.DefaultQuerySettings.EnableExpand = true; _queryContext.DefaultQuerySettings.MaxTop = 2; SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, _queryContext); // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()), "The limit of '2' for Top query has been exceeded. The value from the incoming request is '4'."); }
public void ValidateSelectExpandQueryValidator_Throws_IfNotAllowCount() { // Arrange string expand = "Orders($count=true)"; SelectExpandQueryValidator validator = new SelectExpandQueryValidator(); _queryContext.DefaultQuerySettings.EnableExpand = true; _queryContext.DefaultQuerySettings.EnableCount = false; SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, _queryContext); // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()), "The property 'Orders' cannot be used for $count."); }
public void GetSelectExpandQueryValidator_Returns_Validator() { // Arrange & Act & Assert Assert.NotNull(SelectExpandQueryValidator.GetSelectExpandQueryValidator(null)); // Arrange & Act & Assert ODataQueryContext context = new ODataQueryContext(EdmCoreModel.Instance, typeof(int)); Assert.NotNull(SelectExpandQueryValidator.GetSelectExpandQueryValidator(context)); // Arrange & Act & Assert IServiceProvider services = new ServiceCollection() .AddSingleton <SelectExpandQueryValidator>() .AddSingleton <DefaultQuerySettings>().BuildServiceProvider(); context.RequestContainer = services; Assert.NotNull(SelectExpandQueryValidator.GetSelectExpandQueryValidator(context)); }
public void ValidateThrowException_IfNotExpandable() { CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.Customer, new ClrTypeAnnotation(typeof(Customer))); ODataQueryContext queryContext = new ODataQueryContext(model.Model, typeof(Customer)); queryContext.RequestContainer = new MockContainer(); model.Model.SetAnnotationValue(model.Customer.FindProperty("Orders"), new QueryableRestrictionsAnnotation(new QueryableRestrictions { NotExpandable = true })); string expand = "Orders"; SelectExpandQueryValidator validator = SelectExpandQueryValidator.GetSelectExpandQueryValidator(queryContext); SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, queryContext); ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()), "The property 'Orders' cannot be used in the $expand query option."); }
public void Validate_DepthChecks(string expand, int maxExpansionDepth) { // Arrange SelectExpandQueryValidator validator = new SelectExpandQueryValidator(_queryContext.DefaultQuerySettings); SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, _queryContext); selectExpandQueryOption.LevelsMaxLiteralExpansionDepth = 1; // Act & Assert ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth }), String.Format(CultureInfo.CurrentCulture, MaxExpandDepthExceededErrorString, maxExpansionDepth)); ExceptionAssert.DoesNotThrow( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth + 1 })); }
public void ValidateThrowException_IfBaseOrDerivedClassPropertyNotExpandable(string className, string propertyName) { CustomersModelWithInheritance model = new CustomersModelWithInheritance(); model.Model.SetAnnotationValue(model.SpecialCustomer, new ClrTypeAnnotation(typeof(Customer))); ODataQueryContext queryContext = new ODataQueryContext(model.Model, typeof(Customer)); queryContext.RequestContainer = new MockContainer(); EdmEntityType classType = (className == "Customer") ? model.Customer : model.SpecialCustomer; model.Model.SetAnnotationValue(classType.FindProperty(propertyName), new QueryableRestrictionsAnnotation(new QueryableRestrictions { NotExpandable = true })); string expand = "NS.SpecialCustomer/" + propertyName; SelectExpandQueryValidator validator = SelectExpandQueryValidator.GetSelectExpandQueryValidator(queryContext); SelectExpandQueryOption selectExpandQueryOption = new SelectExpandQueryOption(null, expand, queryContext); ExceptionAssert.Throws <ODataException>( () => validator.Validate(selectExpandQueryOption, new ODataValidationSettings()), String.Format(CultureInfo.InvariantCulture, "The property '{0}' cannot be used in the $expand query option.", propertyName)); }
/// <summary> /// Initializes a new instance of the <see cref="SelectExpandQueryOption"/> class. /// </summary> /// <param name="select">The $select query parameter value.</param> /// <param name="expand">The $expand query parameter value.</param> /// <param name="context">The <see cref="ODataQueryContext"/> which contains the <see cref="IEdmModel"/> and some type information.</param> /// <param name="queryOptionParser">The <see cref="ODataQueryOptionParser"/> which is used to parse the query option.</param> public SelectExpandQueryOption(string select, string expand, ODataQueryContext context, ODataQueryOptionParser queryOptionParser, HttpRequest request, IServiceProvider serviceProvider) { if (context == null) { throw Error.ArgumentNull("context"); } if (String.IsNullOrEmpty(select) && String.IsNullOrEmpty(expand)) { throw Error.Argument(SRResources.SelectExpandEmptyOrNull); } if (queryOptionParser == null) { throw Error.ArgumentNull("queryOptionParser"); } if (serviceProvider == null) { throw new ArgumentNullException(nameof(serviceProvider)); } IEdmEntityType entityType = context.ElementType as IEdmEntityType; if (entityType == null) { throw Error.Argument("context", SRResources.SelectNonEntity, context.ElementType.ToTraceString()); } Context = context; RawSelect = select; RawExpand = expand; Validator = new SelectExpandQueryValidator(); _queryOptionParser = queryOptionParser; _serviceProvider = serviceProvider; _assemblyProvider = request.AssemblyProvider(); }
public void ValidateSelectExpandQueryValidator_DoesNotThrow_DefaultLevelsMaxLiteralExpansionDepth(int maxExpansionDepth) { // Arrange string expand = "Parent($levels=1)"; SelectExpandQueryValidator validator = new SelectExpandQueryValidator(); ODataConventionModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet <ODataLevelsTest.LevelsEntity>("Entities"); IEdmModel model = builder.GetEdmModel(); var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity)); context.DefaultQuerySettings.EnableExpand = true; context.RequestContainer = new MockServiceProvider(); var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context); // Act & Assert ExceptionAssert.DoesNotThrow( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = maxExpansionDepth })); }
public void ValidateSelectExpandQueryValidator_DoesNotThrow_IfExpansionDepthIsZero_DollarLevels() { // Arrange string expand = "Parent($expand=Parent($expand=Parent($levels=10)))"; var validator = new SelectExpandQueryValidator(new DefaultQuerySettings { EnableExpand = true }); var builder = ODataConventionModelBuilderFactory.Create(); builder.EntitySet <ODataLevelsTest.LevelsEntity>("Entities"); IEdmModel model = builder.GetEdmModel(); var context = new ODataQueryContext(model, typeof(ODataLevelsTest.LevelsEntity)); context.RequestContainer = new MockServiceProvider(); var selectExpandQueryOption = new SelectExpandQueryOption(null, expand, context); // Act & Assert ExceptionAssert.DoesNotThrow( () => validator.Validate( selectExpandQueryOption, new ODataValidationSettings { MaxExpansionDepth = 0 })); }