Skip to content

Commit d089461

Browse files
committed
test: inheritance
1 parent b5a27c4 commit d089461

File tree

8 files changed

+71
-49
lines changed

8 files changed

+71
-49
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace JsonApiDotNetCoreExample.Models
2+
{
3+
public interface IIsLockable
4+
{
5+
bool IsLocked { get; set; }
6+
}
7+
}

src/Examples/JsonApiDotNetCoreExample/Models/Person.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ public class PersonRole : Identifiable
1111
public Person Person { get; set; }
1212
}
1313

14-
public class Person : Identifiable, IHasMeta
14+
public class Person : Identifiable, IHasMeta, IIsLockable
1515
{
1616
public bool IsLocked { get; set; }
1717

src/Examples/JsonApiDotNetCoreExample/Models/TodoItem.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
namespace JsonApiDotNetCoreExample.Models
66
{
7-
public class TodoItem : Identifiable
7+
public class TodoItem : Identifiable, IIsLockable
88
{
99
public TodoItem()
1010
{
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using JsonApiDotNetCore.Internal;
5+
using JsonApiDotNetCore.Models;
6+
using JsonApiDotNetCoreExample.Models;
7+
8+
namespace JsonApiDotNetCoreExample.Resources
9+
{
10+
public abstract class LockableResourceBase<T> : ResourceDefinition<T> where T : class, IIsLockable, IIdentifiable
11+
{
12+
protected LockableResourceBase(IResourceGraph graph) : base(graph) { }
13+
14+
protected void DisallowLocked(IEnumerable<T> entities)
15+
{
16+
foreach (var e in entities ?? Enumerable.Empty<T>())
17+
{
18+
if (e.IsLocked)
19+
{
20+
throw new JsonApiException(403, "Not allowed to update fields or relations of locked todo item", new UnauthorizedAccessException());
21+
}
22+
}
23+
}
24+
}
25+
}
Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
1-
using System;
21
using System.Collections.Generic;
32
using System.Linq;
43
using JsonApiDotNetCore.Internal;
5-
using JsonApiDotNetCore.Models;
64
using JsonApiDotNetCore.Hooks;
75
using JsonApiDotNetCoreExample.Models;
86

97
namespace JsonApiDotNetCoreExample.Resources
108
{
11-
public class PersonResource : ResourceDefinition<Person>
9+
public class PersonResource : LockableResourceBase<Person>
1210
{
13-
public PersonResource(IResourceGraph graph) : base(graph)
14-
{
15-
}
11+
public PersonResource(IResourceGraph graph) : base(graph) { }
1612

1713
public override IEnumerable<string> BeforeUpdateRelationship(HashSet<string> ids, IAffectedRelationships<Person> resourcesByRelationship, ResourcePipeline pipeline)
1814
{
@@ -22,18 +18,7 @@ public override IEnumerable<string> BeforeUpdateRelationship(HashSet<string> ids
2218

2319
public override void BeforeImplicitUpdateRelationship(IAffectedRelationships<Person> resourcesByRelationship, ResourcePipeline pipeline)
2420
{
25-
resourcesByRelationship.GetByRelationship<Passport>().ToList().ForEach(kvp => DoesNotTouchLockedPeople(kvp.Value));
26-
}
27-
28-
private void DoesNotTouchLockedPeople(IEnumerable<Person> entities)
29-
{
30-
foreach (var person in entities ?? Enumerable.Empty<Person>())
31-
{
32-
if (person.IsLocked)
33-
{
34-
throw new JsonApiException(403, "Not allowed to update fields or relations of locked persons", new UnauthorizedAccessException());
35-
}
36-
}
21+
resourcesByRelationship.GetByRelationship<Passport>().ToList().ForEach(kvp => DisallowLocked(kvp.Value));
3722
}
3823
}
3924
}

src/Examples/JsonApiDotNetCoreExample/Resources/TodoResource.cs

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,14 @@
22
using System.Collections.Generic;
33
using System.Linq;
44
using JsonApiDotNetCore.Internal;
5-
using JsonApiDotNetCore.Models;
65
using JsonApiDotNetCore.Hooks;
76
using JsonApiDotNetCoreExample.Models;
87

98
namespace JsonApiDotNetCoreExample.Resources
109
{
11-
public class TodoResource : ResourceDefinition<TodoItem>
10+
public class TodoResource : LockableResourceBase<TodoItem>
1211
{
13-
public TodoResource(IResourceGraph graph) : base(graph)
14-
{
15-
}
12+
public TodoResource(IResourceGraph graph) : base(graph) { }
1613

1714
public override void BeforeRead(ResourcePipeline pipeline, bool isIncluded = false, string stringId = null)
1815
{
@@ -25,19 +22,7 @@ public override void BeforeRead(ResourcePipeline pipeline, bool isIncluded = fal
2522
public override void BeforeImplicitUpdateRelationship(IAffectedRelationships<TodoItem> resourcesByRelationship, ResourcePipeline pipeline)
2623
{
2724
List<TodoItem> todos = resourcesByRelationship.GetByRelationship<Person>().SelectMany(kvp => kvp.Value).ToList();
28-
DoesNotTouchLocked(todos);
29-
}
30-
31-
32-
private void DoesNotTouchLocked(IEnumerable<TodoItem> entities)
33-
{
34-
foreach (var person in entities ?? Enumerable.Empty<TodoItem>())
35-
{
36-
if (person.IsLocked)
37-
{
38-
throw new JsonApiException(403, "Not allowed to update fields or relations of locked todo item", new UnauthorizedAccessException());
39-
}
40-
}
25+
DisallowLocked(todos);
4126
}
4227
}
4328
}

src/Examples/JsonApiDotNetCoreExample/Resources/UserResource.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,7 @@ namespace JsonApiDotNetCoreExample.Resources
99
{
1010
public class UserResource : ResourceDefinition<User>
1111
{
12-
public UserResource(IResourceGraph graph) : base(graph)
13-
{
14-
}
12+
public UserResource(IResourceGraph graph) : base(graph) { }
1513

1614
protected override List<AttrAttribute> OutputAttrs()
1715
=> Remove(user => user.Password);
@@ -24,7 +22,6 @@ public override QueryFilters GetQueryFilters()
2422
};
2523
}
2624

27-
2825
private IQueryable<User> FirstCharacterFilter(IQueryable<User> users, FilterQuery filterQuery)
2926
{
3027
switch(filterQuery.Operation)

test/UnitTests/ResourceHooks/DiscoveryTests.cs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,20 @@
33
using System.Collections.Generic;
44
using Xunit;
55
using JsonApiDotNetCore.Builders;
6+
using JsonApiDotNetCore.Internal;
67

78
namespace UnitTests.ResourceHooks
89
{
910
public class DiscoveryTests
1011
{
12+
public class Dummy : Identifiable { }
13+
public class DummyResourceDefinition : ResourceDefinition<Dummy>
14+
{
15+
public DummyResourceDefinition() : base(new ResourceGraphBuilder().AddResource<Dummy>().Build()) { }
16+
17+
public override IEnumerable<Dummy> BeforeDelete(HashSet<Dummy> entities, ResourcePipeline pipeline) { return entities; }
18+
public override void AfterDelete(HashSet<Dummy> entities, ResourcePipeline pipeline, bool succeeded) { }
19+
}
1120

1221
[Fact]
1322
public void Hook_Discovery()
@@ -19,15 +28,29 @@ public void Hook_Discovery()
1928
Assert.Contains(ResourceHook.AfterDelete, hookConfig.ImplementedHooks);
2029

2130
}
22-
public class Dummy : Identifiable { }
23-
public class DummyResourceDefinition : ResourceDefinition<Dummy>
31+
32+
33+
public class AnotherDummy : Identifiable { }
34+
public abstract class ResourceDefintionBase<T> : ResourceDefinition<T> where T : class, IIdentifiable
2435
{
25-
public DummyResourceDefinition() : base(new ResourceGraphBuilder().AddResource<Dummy>().Build())
26-
{
27-
}
36+
protected ResourceDefintionBase(IResourceGraph graph) : base(graph) { }
37+
}
2838

29-
public override IEnumerable<Dummy> BeforeDelete(HashSet<Dummy> entities, ResourcePipeline pipeline) { return entities; }
30-
public override void AfterDelete(HashSet<Dummy> entities, ResourcePipeline pipeline, bool succeeded) { }
39+
public class AnotherDummyResourceDefinition : ResourceDefintionBase<AnotherDummy>
40+
{
41+
public AnotherDummyResourceDefinition() : base(new ResourceGraphBuilder().AddResource<Dummy>().Build()) { }
42+
43+
public override IEnumerable<AnotherDummy> BeforeDelete(HashSet<AnotherDummy> entities, ResourcePipeline pipeline) { return entities; }
44+
public override void AfterDelete(HashSet<AnotherDummy> entities, ResourcePipeline pipeline, bool succeeded) { }
45+
}
46+
[Fact]
47+
public void Hook_Discovery_With_Inheritance()
48+
{
49+
// arrange & act
50+
var hookConfig = new HooksDiscovery<AnotherDummy>();
51+
// assert
52+
Assert.Contains(ResourceHook.BeforeDelete, hookConfig.ImplementedHooks);
53+
Assert.Contains(ResourceHook.AfterDelete, hookConfig.ImplementedHooks);
3154
}
3255
}
3356
}

0 commit comments

Comments
 (0)