From 281f3b1fb9ae091a1832169c061921acd8e948e7 Mon Sep 17 00:00:00 2001 From: maurei Date: Wed, 3 Feb 2021 07:49:26 +0100 Subject: [PATCH 1/2] Additional fix OnReturn hook --- .../Definitions/BlogsHooksDefintion.cs | 21 ++++++++++++++ .../JsonApiDotNetCoreExample/Models/Author.cs | 3 ++ .../Internal/ResourceHookExecutorFacade.cs | 2 +- .../ResourceDefinitionTests.cs | 29 +++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/Examples/JsonApiDotNetCoreExample/Definitions/BlogsHooksDefintion.cs diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/BlogsHooksDefintion.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/BlogsHooksDefintion.cs new file mode 100644 index 0000000000..77ac087e63 --- /dev/null +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/BlogsHooksDefintion.cs @@ -0,0 +1,21 @@ +using System.Collections.Generic; +using System.Linq; +using JsonApiDotNetCore.Configuration; +using JsonApiDotNetCore.Hooks.Internal.Execution; +using JsonApiDotNetCore.Resources; +using JsonApiDotNetCoreExample.Models; + +namespace JsonApiDotNetCoreExample.Definitions +{ + public class BlogsHooksDefintion : ResourceHooksDefinition + { + public BlogsHooksDefintion(IResourceGraph resourceGraph) : base(resourceGraph) + { + } + + public override IEnumerable OnReturn(HashSet resources, ResourcePipeline pipeline) + { + return resources.Where(t => t.Title != "This should not be included"); + } + } +} diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs index 7280263468..58b28fc237 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs @@ -24,5 +24,8 @@ public sealed class Author : Identifiable [HasMany] public IList
Articles { get; set; } + + [HasMany] + public ISet Blogs { get; set; } } } diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs index 5b0cd4bccc..2f41667a97 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs @@ -122,7 +122,7 @@ public object OnReturnRelationship(object resourceOrResources) if (resourceOrResources is IEnumerable) { dynamic resources = resourceOrResources; - return _resourceHookExecutor.OnReturn(resources, ResourcePipeline.GetRelationship).ToArray(); + return Enumerable.ToArray(_resourceHookExecutor.OnReturn(resources, ResourcePipeline.GetRelationship)); } if (resourceOrResources is IIdentifiable) diff --git a/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs b/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs index fa7b5a36f1..365f328c3c 100644 --- a/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs @@ -24,6 +24,7 @@ public sealed class ResourceDefinitionTests : FunctionalTestCollection _todoItemFaker; private readonly Faker _personFaker; private readonly Faker
_articleFaker; + private readonly Faker _blogFaker; private readonly Faker _authorFaker; private readonly Faker _tagFaker; @@ -36,6 +37,10 @@ public ResourceDefinitionTests(ResourceHooksApplicationFactory factory) : base(f .RuleFor(a => a.Caption, f => f.Random.AlphaNumeric(10)) .RuleFor(a => a.Author, f => _authorFaker.Generate()); + _blogFaker = new Faker() + .RuleFor(a => a.Title, f => f.Lorem.Word()) + .RuleFor(a => a.CompanyName, f => f.Company.CompanyName()); + _userFaker = new Faker() .CustomInstantiator(f => new User(_dbContext)) .RuleFor(u => u.UserName, f => f.Internet.UserName()) @@ -241,6 +246,30 @@ public async Task Article_Through_Secondary_Endpoint_Is_Hidden() Assert.DoesNotContain(toBeExcluded, body); } + [Fact] + public async Task Blog_Through_Secondary_Endpoint_Is_Hidden() + { + // Arrange + var blogs = _blogFaker.Generate(3).ToHashSet(); + string toBeExcluded = "This should not be included"; + blogs.First().Title = toBeExcluded; + var author = _authorFaker.Generate(); + author.Blogs = blogs; + + _dbContext.AuthorDifferentDbContextName.Add(author); + await _dbContext.SaveChangesAsync(); + + var route = $"/api/v1/authors/{author.Id}/blogs"; + + // Act + var response = await _client.GetAsync(route); + + // Assert + var body = await response.Content.ReadAsStringAsync(); + Assert.True(HttpStatusCode.OK == response.StatusCode, $"{route} returned {response.StatusCode} status code with body: {body}"); + Assert.DoesNotContain(toBeExcluded, body); + } + [Fact] public async Task Passport_Through_Secondary_Endpoint_Is_Hidden() { From c241460436d8d6f94576743c8b93803bf09ad783 Mon Sep 17 00:00:00 2001 From: maurei Date: Tue, 9 Feb 2021 17:55:46 +0100 Subject: [PATCH 2/2] fix: alternative model used for ISet testcase{ --- .../Definitions/TodoItemHooksDefinition.cs | 5 +++++ src/Examples/JsonApiDotNetCoreExample/Models/Author.cs | 3 --- .../ResourceHooks/ResourceHookTests.cs | 10 +++++----- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs index 33fa998337..f9e15f6547 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Definitions/TodoItemHooksDefinition.cs @@ -29,5 +29,10 @@ public override void BeforeImplicitUpdateRelationship(IRelationshipsDictionary todos = resourcesByRelationship.GetByRelationship().SelectMany(kvp => kvp.Value).ToList(); DisallowLocked(todos); } + + public override IEnumerable OnReturn(HashSet resources, ResourcePipeline pipeline) + { + return resources.Where(t => t.Description != "This should not be included"); + } } } diff --git a/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs b/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs index 688a3fcd4c..cd023ba729 100644 --- a/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs +++ b/src/Examples/JsonApiDotNetCoreExample/Models/Author.cs @@ -14,8 +14,5 @@ public sealed class Author : Identifiable [HasMany] public IList
Articles { get; set; } - - [HasMany] - public ISet
Revisions { get; set; } } } diff --git a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs index e668131659..62bd8491e3 100644 --- a/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/IntegrationTests/ResourceHooks/ResourceHookTests.cs @@ -260,17 +260,17 @@ public async Task Can_hide_secondary_resource_from_ToMany_Set_relationship_using // Arrange string toBeExcluded = "This should not be included"; - var author = _fakers.Author.Generate(); - author.Revisions = _fakers.Article.Generate(3).ToHashSet(); - author.Articles[0].Caption = toBeExcluded; + var person = _fakers.Person.Generate(); + person.TodoItems = _fakers.TodoItem.Generate(3).ToHashSet(); + person.TodoItems.First().Description = toBeExcluded; await _testContext.RunOnDatabaseAsync(async dbContext => { - dbContext.AuthorDifferentDbContextName.Add(author); + dbContext.People.Add(person); await dbContext.SaveChangesAsync(); }); - var route = $"/api/v1/authors/{author.Id}/revisions"; + var route = $"/api/v1/people/{person.Id}/todoItems"; // Act var (httpResponse, responseDocument) = await _testContext.ExecuteGetAsync(route);