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
9 changes: 5 additions & 4 deletions QueryKit.UnitTests/PropertyDepthTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,7 @@ public void filter_root_property_allowed_when_max_depth_is_0()
}

[Fact]
public void filter_per_property_max_depth_applies_to_a_property_that_starts_with_its_name()
public void filter_per_property_max_depth_does_not_apply_to_a_property_that_starts_with_its_name()
{
var input = """AddressBackup.State == "x" """;
var config = new QueryKitConfiguration(settings =>
Expand All @@ -267,11 +267,12 @@ public void filter_per_property_max_depth_applies_to_a_property_that_starts_with
});

var act = () => FilterParser.ParseFilter<Owner>(input, config);
act.Should().NotThrow();
act.Should().Throw<QueryKitPropertyDepthExceededException>()
.WithMessage("*AddressBackup.State*depth of 1*maximum allowed depth of 0*");
}

[Fact]
public void sort_per_property_max_depth_applies_to_a_property_that_starts_with_its_name()
public void sort_per_property_max_depth_does_not_apply_to_a_property_that_starts_with_its_name()
{
var input = "AddressBackup.State";
var config = new QueryKitConfiguration(settings =>
Expand All @@ -281,7 +282,7 @@ public void sort_per_property_max_depth_applies_to_a_property_that_starts_with_i
});

var act = () => SortParser.ParseSort<Owner>(input, config);
act.Should().NotThrow();
act.Should().Throw<QueryKitPropertyDepthExceededException>();
}

private class Owner
Expand Down
7 changes: 4 additions & 3 deletions QueryKit/QueryKitPropertyMappings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -412,11 +412,12 @@ private static string GetOperator(ExpressionType nodeType)
if (string.IsNullOrEmpty(propertyPath))
return null;

// Check if the property path starts with any configured property that has MaxDepth
// Check if the property path is, or is under, any configured property that has MaxDepth
foreach (var mapping in _propertyMappings.Values)
{
if (mapping.MaxDepth.HasValue &&
propertyPath.StartsWith(mapping.Name ?? "", StringComparison.OrdinalIgnoreCase))
if (mapping.MaxDepth.HasValue && !string.IsNullOrEmpty(mapping.Name) &&
(propertyPath.Equals(mapping.Name, StringComparison.OrdinalIgnoreCase) ||
propertyPath.StartsWith(mapping.Name + ".", StringComparison.OrdinalIgnoreCase)))
{
return mapping.MaxDepth;
}
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,8 @@ var config = new QueryKitConfiguration(config =>
// "Publisher.Address.City" throws (depth 2, exceeds global limit of 1)
```

The override applies only to the property and the paths below it. For example, `HasMaxDepth` on `Address` does not apply to `AddressBackup.State`, so `AddressBackup.State` uses the global limit.

**Depth Calculation:**
- `Title` = depth 0 (root property)
- `Author.Name` = depth 1 (one level of nesting)
Expand Down
Loading