Skip to content
Merged
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 @@ -443,6 +443,35 @@ public async Task query_name_in_arithmetic_is_filtered()
people.Should().ContainSingle(x => x.Id == 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
27 changes: 27 additions & 0 deletions QueryKit.UnitTests/PropertyResolverTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -770,6 +770,33 @@ public void property_prevented_for_filter_and_sort_is_removed_by_its_query_name_
filterExpression.ToDisplayString().Should().Be("x => (x.Age > 100)");
}

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

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

filterExpression.ToDisplayString().Should().Be("""x => (x.Title == "name == x")""");
}

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

var input = config.PropertyMappings.ReplaceAliasesWithPropertyPaths("""name == "x" """);

input.Should().Be("""Title == "x" """);
}

[Theory]
[InlineData("==")]
[InlineData("_=")]
Expand Down
5 changes: 0 additions & 5 deletions QueryKit/QueryKitPropertyMappings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,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