Skip to content

Commit a74f013

Browse files
author
Bart Koelman
authored
Fixed: When determining total resource count, ResourceDefinition.OnApplyFilter needs to be called, so that user-defined filters are taken into account. (#902)
1 parent 22b91ad commit a74f013

File tree

4 files changed

+21
-11
lines changed

4 files changed

+21
-11
lines changed

src/JsonApiDotNetCore/Queries/IQueryLayerComposer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public interface IQueryLayerComposer
1414
/// <summary>
1515
/// Builds a top-level filter from constraints, used to determine total resource count.
1616
/// </summary>
17-
FilterExpression GetTopFilterFromConstraints();
17+
FilterExpression GetTopFilterFromConstraints(ResourceContext resourceContext);
1818

1919
/// <summary>
2020
/// Collects constraints and builds a <see cref="QueryLayer"/> out of them, used to retrieve the actual resources.

src/JsonApiDotNetCore/Queries/Internal/QueryLayerComposer.cs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,17 @@ public QueryLayerComposer(
3535
}
3636

3737
/// <inheritdoc />
38-
public FilterExpression GetTopFilterFromConstraints()
38+
public FilterExpression GetTopFilterFromConstraints(ResourceContext resourceContext)
3939
{
4040
var constraints = _constraintProviders.SelectMany(provider => provider.GetConstraints()).ToArray();
4141

42-
var topFilters = constraints
42+
var filtersInTopScope = constraints
4343
.Where(constraint => constraint.Scope == null)
4444
.Select(constraint => constraint.Expression)
4545
.OfType<FilterExpression>()
4646
.ToArray();
4747

48-
if (topFilters.Length > 1)
49-
{
50-
return new LogicalExpression(LogicalOperator.And, topFilters);
51-
}
52-
53-
return topFilters.Length == 1 ? topFilters[0] : null;
48+
return GetFilter(filtersInTopScope, resourceContext);
5449
}
5550

5651
/// <inheritdoc />

src/JsonApiDotNetCore/Services/JsonApiResourceService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public virtual async Task<IReadOnlyCollection<TResource>> GetAsync(CancellationT
6666

6767
if (_options.IncludeTotalResourceCount)
6868
{
69-
var topFilter = _queryLayerComposer.GetTopFilterFromConstraints();
69+
var topFilter = _queryLayerComposer.GetTopFilterFromConstraints(_request.PrimaryResource);
7070
_paginationContext.TotalResourceCount = await _repositoryAccessor.CountAsync<TResource>(topFilter, cancellationToken);
7171

7272
if (_paginationContext.TotalResourceCount == 0)

test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceDefinitions/ResourceDefinitionQueryCallbackTests.cs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
using System.Threading.Tasks;
44
using FluentAssertions;
55
using FluentAssertions.Extensions;
6+
using JsonApiDotNetCore.Configuration;
67
using JsonApiDotNetCore.Resources;
78
using JsonApiDotNetCore.Serialization.Objects;
89
using Microsoft.Extensions.DependencyInjection;
@@ -23,6 +24,9 @@ public ResourceDefinitionQueryCallbackTests(IntegrationTestContext<TestableStart
2324
services.AddScoped<IResourceDefinition<CallableResource>, CallableResourceDefinition>();
2425
services.AddSingleton<IUserRolesService, FakeUserRolesService>();
2526
});
27+
28+
var options = (JsonApiOptions) testContext.Factory.Services.GetRequiredService<IJsonApiOptions>();
29+
options.IncludeTotalResourceCount = true;
2630
}
2731

2832
[Fact]
@@ -32,9 +36,16 @@ public async Task Include_from_resource_definition_has_blocked_capability()
3236
var userRolesService = (FakeUserRolesService) _testContext.Factory.Services.GetRequiredService<IUserRolesService>();
3337
userRolesService.AllowIncludeOwner = false;
3438

39+
var resource = new CallableResource
40+
{
41+
Label = "A",
42+
IsDeleted = false
43+
};
44+
3545
await _testContext.RunOnDatabaseAsync(async dbContext =>
3646
{
37-
dbContext.RemoveRange(dbContext.CallableResources);
47+
await dbContext.ClearTableAsync<CallableResource>();
48+
dbContext.CallableResources.Add(resource);
3849

3950
await dbContext.SaveChangesAsync();
4051
});
@@ -99,6 +110,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
99110
responseDocument.ManyData.Should().HaveCount(2);
100111
responseDocument.ManyData[0].Id.Should().Be(resources[1].StringId);
101112
responseDocument.ManyData[1].Id.Should().Be(resources[3].StringId);
113+
114+
responseDocument.Meta["totalResources"].Should().Be(2);
102115
}
103116

104117
[Fact]
@@ -147,6 +160,8 @@ await _testContext.RunOnDatabaseAsync(async dbContext =>
147160

148161
responseDocument.ManyData.Should().HaveCount(1);
149162
responseDocument.ManyData[0].Id.Should().Be(resources[3].StringId);
163+
164+
responseDocument.Meta["totalResources"].Should().Be(1);
150165
}
151166

152167
[Fact]

0 commit comments

Comments
 (0)