Skip to content

Commit daab069

Browse files
committed
test: add nested resource filter test
1 parent f530d37 commit daab069

File tree

3 files changed

+55
-11
lines changed

3 files changed

+55
-11
lines changed

src/JsonApiDotNetCore/Services/DefaultResourceService.cs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,20 @@ public virtual async Task<TResource> GetRelationshipsAsync(TId id, string relati
135135
// TODO: it would be better if we could distinguish whether or not the relationship was not found,
136136
// vs the relationship not being set on the instance of T
137137

138-
var query = _repository.Get(id);
139-
query = ApplyInclude(query, chainPrefix: new List<RelationshipAttribute> { relationship });
140-
var entity = await _repository.FirstOrDefaultAsync(query);
141-
if (entity == null) // this does not make sense. If the parent entity is not found, this error is thrown?
138+
var entityQuery = _repository.Get(id);
139+
140+
entityQuery = ApplyFilter(entityQuery);
141+
entityQuery = ApplySort(entityQuery);
142+
entityQuery = ApplyInclude(entityQuery, chainPrefix: new List<RelationshipAttribute> { relationship });
143+
entityQuery = ApplySelect(entityQuery);
144+
145+
var entity = await _repository.FirstOrDefaultAsync(entityQuery);
146+
if (entity == null)
147+
{
148+
/// TODO: this does not make sense. If the **parent** entity is not found, this error is thrown?
149+
/// this error should be thrown when the relationship is not found.
142150
throw new JsonApiException(404, $"Relationship '{relationshipName}' not found.");
151+
}
143152

144153
if (!IsNull(_hookExecutor, entity))
145154
{ // AfterRead and OnReturn resource hook execution.

test/JsonApiDotNetCoreExampleTests/Acceptance/Spec/NestedResourceTests.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
using System.Collections.Generic;
2-
using System.Linq;
1+
using System.Linq;
32
using System.Net;
43
using System.Threading.Tasks;
54
using Bogus;
65
using JsonApiDotNetCoreExample.Models;
76
using JsonApiDotNetCoreExampleTests.Helpers.Models;
8-
using Microsoft.EntityFrameworkCore;
97
using Xunit;
108
using Person = JsonApiDotNetCoreExample.Models.Person;
119

@@ -31,7 +29,7 @@ public NestedResourceTests(StandardApplicationFactory factory) : base(factory)
3129
}
3230

3331
[Fact]
34-
public async Task Include_NestedResource_CanInclude()
32+
public async Task NestedResourceRoute_IncludeDeeplyNestedRelationship_ReturnsRequestedRelationships()
3533
{
3634
// Arrange
3735
var assignee = _dbContext.Add(_personFaker.Generate()).Entity;
@@ -54,5 +52,26 @@ public async Task Include_NestedResource_CanInclude()
5452
Assert.Equal(todo.Owner.Id, resultTodoItem.Owner.Id);
5553
Assert.Equal(todo.Owner.Passport.Id, resultTodoItem.Owner.Passport.Id);
5654
}
55+
56+
[Fact]
57+
public async Task NestedResourceRoute_Filter_ReturnsFilteredResources()
58+
{
59+
// Arrange
60+
var assignee = _personFaker.Generate();
61+
//var assignee = _dbContext.Add(_personFaker.Generate()).Entity;
62+
//var todos = _todoItemFaker.Generate(10).ToList();
63+
assignee.AssignedTodoItems = _todoItemFaker.Generate(10).ToList();
64+
//assignee.AssignedTodoItems = todos;
65+
_dbContext.Add(assignee);
66+
var ordinal = assignee.AssignedTodoItems.First().Ordinal;
67+
68+
// Act
69+
var (body, response) = await Get($"/api/v1/people/{assignee.Id}/assignedTodoItems?filter[ordinal]={ordinal}");
70+
71+
// Assert
72+
AssertEqualStatusCode(HttpStatusCode.OK, response);
73+
var resultTodoItem = _deserializer.DeserializeList<TodoItemClient>(body).Data.SingleOrDefault();
74+
Assert.Equal(assignee.AssignedTodoItems.First().Id, resultTodoItem.Id);
75+
}
5776
}
5877
}

test/UnitTests/Services/EntityResourceService_Tests.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,21 @@ public class EntityResourceService_Tests
1919
{
2020
private readonly Mock<IResourceRepository<TodoItem>> _repositoryMock = new Mock<IResourceRepository<TodoItem>>();
2121
private readonly IResourceGraph _resourceGraph;
22+
private readonly Mock<IIncludeService> _includeService;
23+
private readonly Mock<ISparseFieldsService> _sparseFieldsService;
24+
private readonly Mock<IPageService> _pageService;
25+
26+
public Mock<ISortService> _sortService { get; }
27+
public Mock<IFilterService> _filterService { get; }
2228

2329
public EntityResourceService_Tests()
2430
{
31+
_includeService = new Mock<IIncludeService>();
32+
_includeService.Setup(m => m.Get()).Returns(new List<List<RelationshipAttribute>>());
33+
_sparseFieldsService = new Mock<ISparseFieldsService>();
34+
_pageService = new Mock<IPageService>();
35+
_sortService = new Mock<ISortService>();
36+
_filterService = new Mock<IFilterService>();
2537
_resourceGraph = new ResourceGraphBuilder()
2638
.AddResource<TodoItem>()
2739
.AddResource<TodoItemCollection, Guid>()
@@ -87,9 +99,13 @@ public async Task GetRelationshipAsync_Returns_Relationship_Value()
8799

88100
private DefaultResourceService<TodoItem> GetService()
89101
{
90-
var includeService = new Mock<IIncludeService>();
91-
includeService.Setup(m => m.Get()).Returns(new List<List<RelationshipAttribute>>());
92-
return new DefaultResourceService<TodoItem>(new List<IQueryParameterService>() { includeService.Object }, new JsonApiOptions(), _repositoryMock.Object, _resourceGraph);
102+
var queryParamServices = new List<IQueryParameterService>
103+
{
104+
_includeService.Object, _pageService.Object, _filterService.Object,
105+
_sortService.Object, _sparseFieldsService.Object
106+
};
107+
108+
return new DefaultResourceService<TodoItem>(queryParamServices, new JsonApiOptions(), _repositoryMock.Object, _resourceGraph);
93109
}
94110
}
95111
}

0 commit comments

Comments
 (0)