Skip to content

Commit 9f31f92

Browse files
committed
Fixed: on secondary endpoint, the incoming filter from query string was not applied when determining total resource count via inverse relationship
1 parent ac7d3ae commit 9f31f92

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,11 @@ public QueryLayerComposer(IEnumerable<IQueryConstraintProvider> constraintProvid
8282

8383
ExpressionInScope[] constraints = _constraintProviders.SelectMany(provider => provider.GetConstraints()).ToArray();
8484

85-
var secondaryScope = new ResourceFieldChainExpression(hasManyRelationship);
86-
8785
// @formatter:wrap_chained_method_calls chop_always
8886
// @formatter:keep_existing_linebreaks true
8987

9088
FilterExpression[] filtersInSecondaryScope = constraints
91-
.Where(constraint => secondaryScope.Equals(constraint.Scope))
89+
.Where(constraint => constraint.Scope == null)
9290
.Select(constraint => constraint.Expression)
9391
.OfType<FilterExpression>()
9492
.ToArray();

test/JsonApiDotNetCoreTests/IntegrationTests/Meta/SupportTicket.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,7 @@ public sealed class SupportTicket : Identifiable<int>
1010
{
1111
[Attr]
1212
public string Description { get; set; } = null!;
13+
14+
[HasOne]
15+
public ProductFamily? ProductFamily { get; set; }
1316
}

test/JsonApiDotNetCoreTests/IntegrationTests/Meta/TopLevelCountTests.cs

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,21 @@ public TopLevelCountTests(IntegrationTestContext<TestableStartup<MetaDbContext>,
3232
}
3333

3434
[Fact]
35-
public async Task Renders_resource_count_for_collection()
35+
public async Task Renders_resource_count_for_primary_resources_endpoint_with_filter()
3636
{
3737
// Arrange
38-
SupportTicket ticket = _fakers.SupportTicket.Generate();
38+
List<SupportTicket> tickets = _fakers.SupportTicket.Generate(2);
39+
40+
tickets[1].Description = "Update firmware version";
3941

4042
await _testContext.RunOnDatabaseAsync(async dbContext =>
4143
{
4244
await dbContext.ClearTableAsync<SupportTicket>();
43-
dbContext.SupportTickets.Add(ticket);
45+
dbContext.SupportTickets.AddRange(tickets);
4446
await dbContext.SaveChangesAsync();
4547
});
4648

47-
const string route = "/supportTickets";
49+
const string route = "/supportTickets?filter=startsWith(description,'Update ')";
4850

4951
// Act
5052
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync<Document>(route);
@@ -61,6 +63,36 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
6163
});
6264
}
6365

66+
[Fact]
67+
public async Task Renders_resource_count_for_secondary_resources_endpoint_with_filter()
68+
{
69+
// Arrange
70+
ProductFamily family = _fakers.ProductFamily.Generate();
71+
family.Tickets = _fakers.SupportTicket.Generate(2);
72+
73+
family.Tickets[1].Description = "Update firmware version";
74+
75+
await _testContext.RunOnDatabaseAsync(async dbContext =>
76+
{
77+
dbContext.ProductFamilies.Add(family);
78+
await dbContext.SaveChangesAsync();
79+
});
80+
81+
string route = $"/productFamilies/{family.StringId}/tickets?filter=contains(description,'firmware')";
82+
83+
// Act
84+
(HttpResponseMessage httpResponse, Document responseDocument) = await _testContext.ExecuteGetAsync<Document>(route);
85+
86+
// Assert
87+
httpResponse.ShouldHaveStatusCode(HttpStatusCode.OK);
88+
89+
responseDocument.Meta.ShouldContainKey("total").With(value =>
90+
{
91+
JsonElement element = value.Should().BeOfType<JsonElement>().Subject;
92+
element.GetInt32().Should().Be(1);
93+
});
94+
}
95+
6496
[Fact]
6597
public async Task Renders_resource_count_for_empty_collection()
6698
{

0 commit comments

Comments
 (0)