/// <summary> /// Allows the specified functions. /// </summary> /// <param name="functions">One or more <see cref="AllowedFunctions">allowed functions</see>.</param> /// <returns>The original <see cref="ODataActionQueryOptionsConventionBuilder{T}"/>.</returns> public virtual ODataActionQueryOptionsConventionBuilder <T> Allow(AllowedFunctions functions) { Contract.Ensures(Contract.Result <ODataActionQueryOptionsConventionBuilder <T> >() != null); ValidationSettings.AllowedFunctions |= functions; return(this); }
public void describe_should_return_description_for_filter( int maxNodeCount, string[] properties, AllowedLogicalOperators logicalOperators, AllowedArithmeticOperators arithmeticOperators, AllowedFunctions functions, string expected) { // arrange var provider = new DefaultODataQueryOptionDescriptionProvider(); var context = new ODataQueryOptionDescriptionContext() { MaxNodeCount = maxNodeCount, AllowedArithmeticOperators = arithmeticOperators, AllowedLogicalOperators = logicalOperators, AllowedFunctions = functions }; for (var i = 0; i < properties.Length; i++) { context.AllowedFilterProperties.Add(properties[i]); } // act var description = provider.Describe(Filter, context); // assert description.Should().Be(expected); }
private static void ValidateFunction(string functionName, ODataValidationSettings settings) { AllowedFunctions convertedFunction = ToODataFunction(functionName); if ((settings.AllowedFunctions & convertedFunction) != convertedFunction) { // this means the given function is not allowed throw new ODataException(Error.Format(SRResources.NotAllowedFunction, functionName, "AllowedFunctions")); } }
public void AllFunctions_Contains_AllFunctionNames() { AllowedFunctions allFunctions = 0; foreach (AllowedFunctions allowedFunction in Enum.GetValues(typeof(AllowedFunctions))) { if (allowedFunction != AllowedFunctions.AllFunctions) { allFunctions = allFunctions | allowedFunction; } } Assert.Equal(AllowedFunctions.AllFunctions, allFunctions); }
public void AllDateTimeFunctions_Has_AllDateFunctions(AllowedFunctions dateFunction) { Assert.Equal(dateFunction, AllowedFunctions.AllDateTimeFunctions & dateFunction); }
public void Functions_CheckArguments_SucceedIfAllowed(AllowedFunctions outer, AllowedFunctions inner, string query, string unused) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = outer | inner, }; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void OtherFunctions_SomeSingleParameterCasts_ThrowODataException(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = "Cast or IsOf Function must have a type in its arguments."; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void AllMathFunctions_Has_AllMathFunctions(AllowedFunctions mathFunction) { Assert.Equal(mathFunction, AllowedFunctions.AllMathFunctions & mathFunction); }
public void MathFunctions_ThrowIfGroupNotAllowed(AllowedFunctions unused, string query, string functionName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.AllFunctions & ~AllowedFunctions.AllMathFunctions, }; var expectedMessage = string.Format( "Function '{0}' is not allowed. " + "To allow it, set the 'AllowedFunctions' property on EnableQueryAttribute or QueryValidationSettings.", functionName); var option = new FilterQueryOption(query, _productContext, queryTranslator: null); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void AllowedFunctions_SucceedIfAllowed(AllowedFunctions allow, string query, string unused) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = allow, }; var option = new FilterQueryOption(query, _productContext, queryTranslator: null); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
public void OtherFunctions_SomeTwoParameterCasts_ThrowODataException(AllowedFunctions unused, string query, string unusedName) { // Thrown at // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Metadata.UriEdmHelpers.CheckRelatedTo(IEdmType parentType, IEdmType childType) Line 108 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.DottedIdentifierBinder.BindDottedIdentifier(DottedIdentifierToken dottedIdentifierToken, BindingState state) Line 107 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindCast(DottedIdentifierToken dottedIdentifierToken) Line 288 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 175 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindFunctionParameter(FunctionParameterToken token) Line 223 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 184 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindFunctionCall.AnonymousMethod__8(FunctionParameterToken ar) Line 201 // System.Core.dll!System.Linq.Enumerable.WhereSelectEnumerableIterator<FunctionParameterToken,QueryNode>.MoveNext() Line 285 // mscorlib.dll!System.Collections.Generic.List<QueryNode>.List(System.Collections.Generic.IEnumerable<QueryNode> collection) Line 105 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken, BindingState state) Line 201 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindFunctionCall(FunctionCallToken functionCallToken) Line 323 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 172 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.DetermineParentNode(EndPathToken segmentToken, BindingState state) Line 188 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.BindEndPath(EndPathToken endPathToken, BindingState state) Line 138 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindEndPath(EndPathToken endPathToken) Line 312 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 169 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind operatorKind, QueryToken queryToken) Line 83 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken) Line 46 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken) Line 266 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 163 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FilterBinder.BindFilter(QueryToken filter) Line 51 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilterImplementation(string filter, ..., IEdmNavigationSource navigationSource) Line 250 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilter() Line 112 // System.Web.OData.dll!System.Web.OData.Query.FilterQueryOption.FilterClause.get() Line 99 // System.Web.OData.dll!System.Web.OData.Query.Validators.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) Line 54 // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = string.Format( "Encountered invalid type cast. '{0}' is not assignable from '{1}'.", typeof(DerivedCategory).FullName, typeof(Product).FullName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void OtherFunctions_SomeSingleParameterCasts_ThrowODataException(AllowedFunctions unused, string query, string unusedName) { // Thrown at // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.ValidateIsOfOrCast(BindingState state, ..., ref List<QueryNode> args) Line 600 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.ValidateAndBuildCastArgs(BindingState state, ref List<QueryNode> args) Line 557 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.CreateUnboundFunctionNode(FunctionCallToken functionCallToken, ..., BindingState state) Line 525 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindAsBuiltInFunction(FunctionCallToken functionCallToken, ..., List<QueryNode> argumentNodes) Line 265 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken, BindingState state) Line 202 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindFunctionCall(FunctionCallToken functionCallToken) Line 323 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 172 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.DetermineParentNode(EndPathToken segmentToken, BindingState state) Line 188 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.BindEndPath(EndPathToken endPathToken, BindingState state) Line 138 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindEndPath(EndPathToken endPathToken) Line 312 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 169 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind operatorKind, QueryToken queryToken) Line 83 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken) Line 46 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken) Line 266 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 163 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FilterBinder.BindFilter(QueryToken filter) Line 51 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilterImplementation(string filter, ..., IEdmNavigationSource navigationSource) Line 250 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilter() Line 112 // System.Web.OData.dll!System.Web.OData.Query.FilterQueryOption.FilterClause.get() Line 99 // System.Web.OData.dll!System.Web.OData.Query.Validators.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) Line 54 // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = "Cast or IsOf Function must have a type in its arguments."; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void OtherFunctions_SomeQuotedTwoParameterCasts_ThrowArgumentException(AllowedFunctions unused, string query, string unusedName) { // Thrown at: // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Semantic.SingleValueFunctionCallNode.SingleValueFunctionCallNode(string name, ..., QueryNode source) Line 92 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Semantic.SingleValueFunctionCallNode.SingleValueFunctionCallNode(string name, ..., IEdmTypeReference returnedTypeReference) Line 63 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.CreateUnboundFunctionNode(FunctionCallToken functionCallToken, ..., BindingState state) Line 546 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindAsBuiltInFunction(FunctionCallToken functionCallToken, ..., List<QueryNode> argumentNodes) Line 265 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FunctionCallBinder.BindFunctionCall(FunctionCallToken functionCallToken, BindingState state) Line 202 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindFunctionCall(FunctionCallToken functionCallToken) Line 323 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 172 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.DetermineParentNode(EndPathToken segmentToken, BindingState state) Line 188 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.EndPathBinder.BindEndPath(EndPathToken endPathToken, BindingState state) Line 138 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindEndPath(EndPathToken endPathToken) Line 312 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 169 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.GetOperandFromToken(BinaryOperatorKind operatorKind, QueryToken queryToken) Line 83 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.BinaryOperatorBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken) Line 46 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.BindBinaryOperator(BinaryOperatorToken binaryOperatorToken) Line 266 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.MetadataBinder.Bind(QueryToken token) Line 163 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.Parsers.FilterBinder.BindFilter(QueryToken filter) Line 51 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilterImplementation(string filter, ..., IEdmNavigationSource navigationSource) Line 250 // Microsoft.OData.Core.dll!Microsoft.OData.Core.UriParser.ODataQueryOptionParser.ParseFilter() Line 112 // System.Web.OData.dll!System.Web.OData.Query.FilterQueryOption.FilterClause.get() Line 99 // System.Web.OData.dll!System.Web.OData.Query.Validators.FilterQueryValidator.Validate(FilterQueryOption filterQueryOption, ODataValidationSettings settings) Line 54 // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.AllFunctions, }; var expectedMessage = "An instance of SingleValueFunctionCallNode can only be created with a primitive, " + "complex or enum type. For functions returning a single entity, use SingleEntityFunctionCallNode instead."; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ArgumentException>(() => _validator.Validate(option, settings), expectedMessage); }
public void AllMathFunctions_DoesNot_Have_NonMathFunctions(AllowedFunctions nonMathFunction) { Assert.Equal(AllowedFunctions.None, AllowedFunctions.AllMathFunctions & nonMathFunction); }
private static AllowedFunctions ToODataFunction(string functionName) { AllowedFunctions result = AllowedFunctions.None; switch (functionName) { case "any": result = AllowedFunctions.Any; break; case "all": result = AllowedFunctions.All; break; case "cast": result = AllowedFunctions.Cast; break; case ClrCanonicalFunctions.CeilingFunctionName: result = AllowedFunctions.Ceiling; break; case ClrCanonicalFunctions.ConcatFunctionName: result = AllowedFunctions.Concat; break; case ClrCanonicalFunctions.ContainsFunctionName: result = AllowedFunctions.SubstringOf; break; case ClrCanonicalFunctions.DayFunctionName: result = AllowedFunctions.Day; break; case ClrCanonicalFunctions.DaysFunctionName: result = AllowedFunctions.Days; break; case ClrCanonicalFunctions.EndswithFunctionName: result = AllowedFunctions.EndsWith; break; case ClrCanonicalFunctions.FloorFunctionName: result = AllowedFunctions.Floor; break; case ClrCanonicalFunctions.HourFunctionName: result = AllowedFunctions.Hour; break; case ClrCanonicalFunctions.HoursFunctionName: result = AllowedFunctions.Hours; break; case ClrCanonicalFunctions.IndexofFunctionName: result = AllowedFunctions.IndexOf; break; case "IsOf": result = AllowedFunctions.IsOf; break; case ClrCanonicalFunctions.LengthFunctionName: result = AllowedFunctions.Length; break; case ClrCanonicalFunctions.MinuteFunctionName: result = AllowedFunctions.Minute; break; case ClrCanonicalFunctions.MinutesFunctionName: result = AllowedFunctions.Minutes; break; case ClrCanonicalFunctions.MonthFunctionName: result = AllowedFunctions.Month; break; case ClrCanonicalFunctions.MonthsFunctionName: result = AllowedFunctions.Months; break; case ClrCanonicalFunctions.RoundFunctionName: result = AllowedFunctions.Round; break; case ClrCanonicalFunctions.SecondFunctionName: result = AllowedFunctions.Second; break; case ClrCanonicalFunctions.SecondsFunctionName: result = AllowedFunctions.Seconds; break; case ClrCanonicalFunctions.StartswithFunctionName: result = AllowedFunctions.StartsWith; break; case ClrCanonicalFunctions.SubstringFunctionName: result = AllowedFunctions.Substring; break; case ClrCanonicalFunctions.TolowerFunctionName: result = AllowedFunctions.ToLower; break; case ClrCanonicalFunctions.ToupperFunctionName: result = AllowedFunctions.ToUpper; break; case ClrCanonicalFunctions.TrimFunctionName: result = AllowedFunctions.Trim; break; case ClrCanonicalFunctions.YearFunctionName: result = AllowedFunctions.Year; break; case ClrCanonicalFunctions.YearsFunctionName: result = AllowedFunctions.Years; break; default: // should never be here Contract.Assert(true, "ToODataFunction should never be here."); break; } return(result); }
public void AllStringFunctions_Has_AllStringFunctions(AllowedFunctions stringFunction) { Assert.Equal(stringFunction, AllowedFunctions.AllStringFunctions & stringFunction); }
public void VerifyAllowedFunctions(AllowedFunctions value1, AllowedFunctions value2) { Assert.Equal(value2, value1 & value2); }
public void AllDateTimeFunctions_DoesNot_Have_NontringFunctions(AllowedFunctions nonDateTimeFunction) { Assert.Equal(AllowedFunctions.None, AllowedFunctions.AllDateTimeFunctions & nonDateTimeFunction); }
public void DateTimeFunctions_Unsupported_ThrowODataException(AllowedFunctions unused, string query, string functionName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = string.Format( "An unknown function with name '{0}' was found. " + "This may also be a key lookup on a navigation property, which is not allowed.", functionName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void StringFunctions_SucceedIfGroupAllowed(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.AllStringFunctions, }; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.DoesNotThrow(() => _validator.Validate(option, settings)); }
/// <inheritdoc/> public override int GetHashCode() => AllowedArithmeticOperators.GetHashCode() ^ AllowedFunctions.GetHashCode() ^ AllowedLogicalOperators.GetHashCode() ^ AllowedQueryOptions.GetHashCode() ^ MaxTop.GetHashCode();
public void OtherFunctions_Unsupported_ThrowNotSupported(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = "Validating OData QueryNode of kind SingleEntityFunctionCall is not supported by FilterQueryValidator."; var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<NotSupportedException>(() => _validator.Validate(option, settings), expectedMessage); }
public void OtherFunctions_SomeTwoParameterCasts_ThrowODataException(AllowedFunctions unused, string query, string unusedName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = AllowedFunctions.None, }; var expectedMessage = string.Format( "Encountered invalid type cast. '{0}' is not assignable from '{1}'.", typeof(DerivedCategory).FullName, typeof(Product).FullName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }
public void SqlQueryBuilderWithObjectHierarchy_Use_SupportedODataQueryOptions_from_parameter(AllowedArithmeticOperators allowedArithmeticOperators, AllowedFunctions allowedFunctions, AllowedLogicalOperators allowedLogicalOperators, AllowedQueryOptions allowedQueryOptions) { ODataValidationSettings dataValidationSettings = new ODataValidationSettings { AllowedArithmeticOperators = allowedArithmeticOperators, AllowedFunctions = allowedFunctions, AllowedLogicalOperators = allowedLogicalOperators, AllowedQueryOptions = allowedQueryOptions }; SqlQueryBuilderWithObjectHierarchy myClass = new SqlQueryBuilderWithObjectHierarchy('.', dataValidationSettings); var getSupportedODataQueryOptions = myClass.GetType().GetMethod("GetSupportedODataQueryOptions", BindingFlags.Static | BindingFlags.Public); var compareResult = new CompareLogic().Compare(getSupportedODataQueryOptions.Invoke(null, null), dataValidationSettings); Assert.IsTrue(compareResult.AreEqual); }
public void Functions_CheckArguments_ThrowIfNotAllowed(AllowedFunctions outer, AllowedFunctions inner, string query, string functionName) { // Arrange var settings = new ODataValidationSettings { AllowedFunctions = outer, }; var expectedMessage = string.Format( "Function '{0}' is not allowed. " + "To allow it, set the 'AllowedFunctions' property on EnableQueryAttribute or QueryValidationSettings.", functionName); var option = new FilterQueryOption(query, _productContext); // Act & Assert Assert.Throws<ODataException>(() => _validator.Validate(option, settings), expectedMessage); }