Skip to content

Commit 7888704

Browse files
committed
fix: hooks for cyclic relations and self multiple relations to same type
1 parent 1d3a947 commit 7888704

File tree

2 files changed

+62
-73
lines changed

2 files changed

+62
-73
lines changed

src/JsonApiDotNetCore/Hooks/TreeTraversal/EntityTreeLayer.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,15 +253,12 @@ public bool Any()
253253
return _uniqueEntities.Any();
254254
}
255255

256-
257-
258-
259256
public IEnumerator<NodeInLayer> GetEnumerator()
260257
{
261258
List<DependentType> types = null;
262259
if (_currentEntitiesByRelationship != null && _currentEntitiesByRelationship.Any())
263260
{
264-
types = _currentEntitiesByRelationship.Select(kvp => kvp.Key.DependentType).ToList();
261+
types = _currentEntitiesByRelationship.Select(kvp => kvp.Key.DependentType).Distinct().ToList();
265262
} else
266263
{
267264
types = _uniqueEntities.Keys.ToList();
Lines changed: 61 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,81 @@
1-
using JsonApiDotNetCore.Builders;
2-
using JsonApiDotNetCore.Internal;
3-
using JsonApiDotNetCore.Models;
4-
using JsonApiDotNetCore.Services;
1+
using JsonApiDotNetCore.Services;
52
using JsonApiDotNetCoreExample.Models;
63
using Moq;
74
using System.Collections.Generic;
8-
using System.Linq;
95
using Xunit;
106

117
namespace UnitTests.ResourceHooks
128
{
13-
public class ScenarioTests : HooksTestsSetup
9+
public class SameEntityTypeTests : HooksTestsSetup
1410
{
15-
//[Fact]
16-
//public void Entity_Has_Multiple_Relations_To_Same_Type()
17-
//{
18-
// // arrange
19-
// var todoDiscovery = SetDiscoverableHooks<TodoItem>(targetHooksNoImplicit, NoHooks);
20-
// var personDiscovery = SetDiscoverableHooks<Person>(targetHooksNoImplicit, NoHooks);
11+
private readonly ResourceHook[] targetHooks = { ResourceHook.OnReturn };
2112

22-
// (var contextMock, var hookExecutor, var todoResourceMock,
23-
// var ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery);
24-
// var person1 = new Person();
25-
// var todo = new TodoItem { Owner = person1 };
26-
// var person2 = new Person { AssignedTodoItems = new List<TodoItem>() { todo } };
27-
// todo.Assignee = person2;
28-
// var person3 = new Person { StakeHolderTodo = todo };
29-
// todo.StakeHolders = new List<Person> { person3 };
13+
[Fact]
14+
public void Entity_Has_Multiple_Relations_To_Same_Type()
15+
{
16+
// arrange
17+
var todoDiscovery = SetDiscoverableHooks<TodoItem>(targetHooks, DisableDbValues);
18+
var personDiscovery = SetDiscoverableHooks<Person>(targetHooks, DisableDbValues);
19+
(var contextMock, var hookExecutor, var todoResourceMock,
20+
var ownerResourceMock) = CreateTestObjects(todoDiscovery, personDiscovery);
21+
var person1 = new Person();
22+
var todo = new TodoItem { Owner = person1 };
23+
var person2 = new Person { AssignedTodoItems = new List<TodoItem>() { todo } };
24+
todo.Assignee = person2;
25+
var person3 = new Person { StakeHolderTodo = todo };
26+
todo.StakeHolders = new List<Person> { person3 };
27+
var todoList = new List<TodoItem>() { todo };
3028

31-
// var todoList = new List<TodoItem>() { todo };
32-
33-
// // act
34-
// hookExecutor.AfterCreate(todoList, ResourceAction.Create);
35-
// // assert
36-
// todoResourceMock.Verify(rd => rd.AfterCreate(It.IsAny<IEnumerable<TodoItem>>(), It.IsAny<HookExecutionContext<TodoItem>>()), Times.Once());
37-
// ownerResourceMock.Verify(rd => rd.AfterUpdate(It.IsAny<IEnumerable<Person>>(), It.IsAny<HookExecutionContext<Person>>()), Times.Once());
29+
// act
30+
hookExecutor.OnReturn(todoList, ResourceAction.Create);
3831

39-
// todoResourceMock.VerifyNoOtherCalls();
40-
// ownerResourceMock.VerifyNoOtherCalls();
41-
//}
32+
// assert
33+
todoResourceMock.Verify(rd => rd.OnReturn(It.IsAny<IEnumerable<TodoItem>>(), ResourceAction.Create), Times.Once());
34+
ownerResourceMock.Verify(rd => rd.OnReturn(It.IsAny<IEnumerable<Person>>(), ResourceAction.Create), Times.Once());
35+
VerifyNoOtherCalls(todoResourceMock, ownerResourceMock);
36+
}
4237

43-
//[Fact]
44-
//public void Entity_Has_Cyclic_Relations()
45-
//{
46-
// // arrange
47-
// var todoDiscovery = SetDiscoverableHooks<TodoItem>(targetHooksNoImplicit, NoHooks);
38+
[Fact]
39+
public void Entity_Has_Cyclic_Relations()
40+
{
41+
// arrange
42+
var todoDiscovery = SetDiscoverableHooks<TodoItem>(targetHooks, DisableDbValues);
43+
(var contextMock, var hookExecutor, var todoResourceMock) = CreateTestObjects(todoDiscovery);
44+
var todo = new TodoItem();
45+
todo.ParentTodoItem = todo;
46+
todo.ChildrenTodoItems = new List<TodoItem> { todo };
47+
var todoList = new List<TodoItem>() { todo };
4848

49-
// (var contextMock, var hookExecutor, var todoResourceMock) = CreateTestObjects(todoDiscovery);
50-
// var todo = new TodoItem();
51-
// todo.ParentTodoItem = todo;
52-
// todo.ChildrenTodoItems = new List<TodoItem> { todo };
53-
// var todoList = new List<TodoItem>() { todo };
54-
// // act
55-
// hookExecutor.AfterCreate(todoList, ResourceAction.Create);
56-
// // assert
57-
// todoResourceMock.Verify(rd => rd.AfterCreate(It.IsAny<IEnumerable<TodoItem>>(), It.IsAny<HookExecutionContext<TodoItem>>()), Times.Once());
58-
// todoResourceMock.VerifyNoOtherCalls();
59-
//}
49+
// act
50+
hookExecutor.OnReturn(todoList, ResourceAction.Create);
6051

61-
//[Fact]
62-
//public void Entity_Has_Nested_Cyclic_Relations()
63-
//{
64-
// // arrange
65-
// var todoDiscovery = SetDiscoverableHooks<TodoItem>(targetHooksNoImplicit, NoHooks);
66-
67-
// (var contextMock, var hookExecutor, var todoResourceMock) = CreateTestObjects(todoDiscovery);
68-
// var rootTodo = new TodoItem();
69-
// var child = new TodoItem { ParentTodoItem = rootTodo };
70-
// rootTodo.ChildrenTodoItems = new List<TodoItem> { child };
71-
// var grandChild = new TodoItem() { ParentTodoItem = child };
72-
// child.ChildrenTodoItems = new List<TodoItem> { grandChild };
73-
// var greatGrandChild = new TodoItem() { ParentTodoItem = grandChild };
74-
// greatGrandChild.ChildrenTodoItems = new List<TodoItem> { rootTodo }; ;
75-
76-
// var todoList = new List<TodoItem>() { rootTodo };
77-
// // act
78-
// hookExecutor.AfterCreate(todoList, ResourceAction.Create);
79-
// // assert
80-
// todoResourceMock.Verify(rd => rd.AfterCreate(It.IsAny<IEnumerable<TodoItem>>(), It.IsAny<HookExecutionContext<TodoItem>>()), Times.Once());
81-
// todoResourceMock.Verify(rd => rd.AfterUpdate(It.IsAny<IEnumerable<TodoItem>>(), It.IsAny<HookExecutionContext<TodoItem>>()), Times.Exactly(2));
82-
// todoResourceMock.VerifyNoOtherCalls();
83-
//}
52+
// assert
53+
todoResourceMock.Verify(rd => rd.OnReturn(It.IsAny<IEnumerable<TodoItem>>(), ResourceAction.Create), Times.Once());
54+
VerifyNoOtherCalls(todoResourceMock);
55+
}
8456

57+
[Fact]
58+
public void Entity_Has_Nested_Cyclic_Relations()
59+
{
60+
// arrange
61+
var todoDiscovery = SetDiscoverableHooks<TodoItem>(targetHooks, DisableDbValues);
62+
(var contextMock, var hookExecutor, var todoResourceMock) = CreateTestObjects(todoDiscovery);
63+
var rootTodo = new TodoItem();
64+
var child = new TodoItem { ParentTodoItem = rootTodo };
65+
rootTodo.ChildrenTodoItems = new List<TodoItem> { child };
66+
var grandChild = new TodoItem() { ParentTodoItem = child };
67+
child.ChildrenTodoItems = new List<TodoItem> { grandChild };
68+
var greatGrandChild = new TodoItem() { ParentTodoItem = grandChild };
69+
greatGrandChild.ChildrenTodoItems = new List<TodoItem> { rootTodo }; ;
70+
var todoList = new List<TodoItem>() { rootTodo };
8571

72+
// act
73+
hookExecutor.OnReturn(todoList, ResourceAction.Create);
8674

75+
// assert
76+
todoResourceMock.Verify(rd => rd.OnReturn(It.IsAny<IEnumerable<TodoItem>>(), ResourceAction.Create), Times.Once);
77+
VerifyNoOtherCalls(todoResourceMock);
78+
}
8779
}
8880
}
8981

0 commit comments

Comments
 (0)