Skip to content

Commit e1e5785

Browse files
fix: 🚑️ bracket nested filtering without the nessesary includes breaking main filtering
1 parent 634abff commit e1e5785

2 files changed

Lines changed: 60 additions & 8 deletions

File tree

JsonApiToolkit.Tests/Extensions/IncludeFilterParserTests.cs

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,9 +254,9 @@ public void SeparateIncludeFilters_WithComplexOrFilter_HandlesCorrectly()
254254
}
255255

256256
[Fact]
257-
public void SeparateIncludeFilters_WithFilterOnNonIncludedRelationship_ReturnsAsMainFilter()
257+
public void SeparateIncludeFilters_WithFilterOnNonIncludedRelationship_DropsFilter()
258258
{
259-
// Arrange - Even with IsIncludeFilter=true, if relationship is not included, it becomes main filter
259+
// Arrange - Bracket syntax filter targeting non-included relationship should be dropped
260260
var filters = new FilterGroup
261261
{
262262
Filters = new List<FilterParameter>
@@ -266,7 +266,7 @@ public void SeparateIncludeFilters_WithFilterOnNonIncludedRelationship_ReturnsAs
266266
Field = "comments.status",
267267
Operator = FilterOperator.Eq,
268268
Value = "approved",
269-
IsIncludeFilter = true, // Marked as include filter but relationship not in includes
269+
IsIncludeFilter = true, // Bracket syntax filter but "comments" not in includes
270270
},
271271
},
272272
};
@@ -278,12 +278,58 @@ public void SeparateIncludeFilters_WithFilterOnNonIncludedRelationship_ReturnsAs
278278
includePaths
279279
);
280280

281-
// Assert
282-
// When the relationship is not included, the filter should be treated as a main filter
281+
// Assert - Filter should be dropped, not converted to main filter
282+
Assert.Null(mainFilters);
283+
Assert.Empty(includeFilters);
284+
}
285+
286+
[Fact]
287+
public void SeparateIncludeFilters_WithMixedIncludedAndNonIncludedRelationships_DropsOnlyNonIncluded()
288+
{
289+
// Arrange - Mix of valid and invalid bracket syntax filters
290+
var filters = new FilterGroup
291+
{
292+
Filters = new List<FilterParameter>
293+
{
294+
new()
295+
{
296+
Field = "author.name",
297+
Operator = FilterOperator.Eq,
298+
Value = "John",
299+
IsIncludeFilter = true, // Valid - author IS in includes
300+
},
301+
new()
302+
{
303+
Field = "comments.status",
304+
Operator = FilterOperator.Eq,
305+
Value = "approved",
306+
IsIncludeFilter = true, // Invalid - comments NOT in includes (dropped)
307+
},
308+
new()
309+
{
310+
Field = "title",
311+
Operator = FilterOperator.Eq,
312+
Value = "Test",
313+
// Main filter (IsIncludeFilter defaults to false)
314+
},
315+
},
316+
};
317+
var includePaths = new List<string> { "author" };
318+
319+
// Act
320+
var (mainFilters, includeFilters) = IncludeFilterParser.SeparateIncludeFilters(
321+
filters,
322+
includePaths
323+
);
324+
325+
// Assert - Main filter only has "title", comments.status was dropped
283326
Assert.NotNull(mainFilters);
284327
Assert.Single(mainFilters.Filters);
285-
Assert.Equal("comments.status", mainFilters.Filters[0].Field);
286-
Assert.Empty(includeFilters);
328+
Assert.Equal("title", mainFilters.Filters[0].Field);
329+
330+
// Include filter only has author
331+
Assert.Single(includeFilters);
332+
Assert.Equal("author", includeFilters[0].RelationshipPath);
287333
}
288334

289335
[Fact]

JsonApiToolkit/Extensions/Querying/Filtering/IncludeFilterParser.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,13 @@ out var fieldPath
9595
}
9696
else
9797
{
98-
newGroup.Filters.Add(filter);
98+
// Only add to main filters if it's NOT a bracket syntax filter.
99+
// Bracket syntax filters targeting non-included relationships should be silently dropped.
100+
if (!filter.IsIncludeFilter)
101+
{
102+
newGroup.Filters.Add(filter);
103+
}
104+
// else: silently ignore bracket syntax filters for non-included relationships
99105
}
100106
}
101107

0 commit comments

Comments
 (0)