Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions QueryKit.IntegrationTests/Tests/PropertyResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,35 @@ public async Task property_is_not_prevented_by_another_property_whose_query_name
people[0].Id.Should().Be(fakePerson.Id);
}

[Fact]
public async Task prevented_property_clause_by_its_query_name_under_or_does_not_return_every_row()
{
// Arrange
var testingServiceScope = new TestingServiceScope();
var title = new Faker().Lorem.Sentence();
var fakePerson = new FakeTestingPersonBuilder()
.WithTitle(title)
.WithFirstName("Paul")
.WithAge(30)
.Build();
await testingServiceScope.InsertAsync(fakePerson);

var input = $"""Title == "{title}" && (first == "Paul" || Age > 100)""";
var config = new QueryKitConfiguration(config =>
{
config.IgnoredClauseBehavior = IgnoredClauseBehavior.Remove;
config.Property<TestingPerson>(x => x.FirstName!).HasQueryName("first").PreventFilter().PreventSort();
});

// Act
var people = await testingServiceScope.DbContext().People
.ApplyQueryKitFilter(input, config)
.ToListAsync();

// Assert
people.Should().BeEmpty();
}

[Theory]
[InlineData("first-name")]
[InlineData("_first")]
Expand Down
23 changes: 3 additions & 20 deletions QueryKit.UnitTests/PropertyResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -628,7 +628,7 @@ public void query_name_in_a_value_is_replaced()
}

[Fact]
public void property_prevented_for_filter_and_sort_throws_by_its_query_name()
public void property_prevented_for_filter_and_sort_is_removed_by_its_query_name()
{
var input = """name == "x" || Age > 100""";
var config = new QueryKitConfiguration(config =>
Expand All @@ -637,26 +637,9 @@ public void property_prevented_for_filter_and_sort_throws_by_its_query_name()
config.Property<TestingPerson>(x => x.Title!).HasQueryName("name").PreventFilter().PreventSort();
});

var act = () => FilterParser.ParseFilter<TestingPerson>(input, config);

act.Should().ThrowExactly<InvalidOperationException>()
.WithMessage("'Title' is not allowed for filtering or sorting.");
}

[Fact]
public void property_prevented_for_filter_and_sort_throws_by_its_query_name_before_an_operator_alias()
{
var input = """name eq "x" """;
var config = new QueryKitConfiguration(config =>
{
config.EqualsOperator = "eq";
config.Property<TestingPerson>(x => x.Title!).HasQueryName("name").PreventFilter().PreventSort();
});

var act = () => FilterParser.ParseFilter<TestingPerson>(input, config);
var filterExpression = FilterParser.ParseFilter<TestingPerson>(input, config);

act.Should().ThrowExactly<InvalidOperationException>()
.WithMessage("'Title' is not allowed for filtering or sorting.");
filterExpression.ToDisplayString().Should().Be("x => (x.Age > 100)");
}

[Fact]
Expand Down
5 changes: 0 additions & 5 deletions QueryKit/QueryKitPropertyMappings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,6 @@ public string ReplaceAliasesWithPropertyPaths(string input)
// (e.g. the `^` in `^^` would otherwise be read as a start-of-line anchor).
var regex = AliasRegexCache.Get($@"\b{Regex.Escape(queryKitPropertyInfo.QueryName!)}\b(?=\s*{Regex.Escape(op)})");

if (queryKitPropertyInfo is { CanSort: false, CanFilter: false} && regex.IsMatch(input))
{
throw new InvalidOperationException($"'{queryKitPropertyInfo.Name}' is not allowed for filtering or sorting.");
}

input = regex.Replace(input, propertyPath);
}
}
Expand Down
Loading