diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs index 405634c8fd..ecd62c521e 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutor.cs @@ -118,7 +118,7 @@ public IEnumerable BeforeDelete(IEnumerable res /// public IEnumerable OnReturn(IEnumerable resources, ResourcePipeline pipeline) where TResource : class, IIdentifiable { - if (GetHook(ResourceHook.OnReturn, resources, out var container, out var node) && pipeline != ResourcePipeline.GetRelationship) + if (GetHook(ResourceHook.OnReturn, resources, out var container, out var node)) { IEnumerable updated = container.OnReturn((HashSet)node.UniqueResources, pipeline); ValidateHookResponse(updated); diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs index 91d0ccf0d3..e6e642e564 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs @@ -119,9 +119,9 @@ public IReadOnlyCollection OnReturnMany(IReadOnlyCollectio public object OnReturnRelationship(object resourceOrResources) { - if (resourceOrResources is IEnumerable enumerable) + if (resourceOrResources is IEnumerable) { - var resources = enumerable.Cast(); + dynamic resources = resourceOrResources; return _resourceHookExecutor.OnReturn(resources, ResourcePipeline.GetRelationship).ToArray(); } diff --git a/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs b/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs index d3929c6a6c..ac589aa0a8 100644 --- a/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs +++ b/test/JsonApiDotNetCoreExampleTests/Acceptance/ResourceDefinitions/ResourceDefinitionTests.cs @@ -217,6 +217,30 @@ public async Task Article_Is_Hidden() Assert.DoesNotContain(toBeExcluded, body); } + [Fact] + public async Task Article_Through_Secondary_Endpoint_Is_Hidden() + { + // Arrange + var articles = _articleFaker.Generate(3); + string toBeExcluded = "This should not be included"; + articles[0].Caption = toBeExcluded; + var author = _authorFaker.Generate(); + author.Articles = articles; + + _dbContext.AuthorDifferentDbContextName.Add(author); + await _dbContext.SaveChangesAsync(); + + var route = $"/api/v1/authors/{author.Id}/articles"; + + // 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 Tag_Is_Hidden() { diff --git a/test/UnitTests/ResourceHooks/ResourceHookExecutor/IdentifiableManyToMany_OnReturnTests.cs b/test/UnitTests/ResourceHooks/ResourceHookExecutor/IdentifiableManyToMany_OnReturnTests.cs index 02b0e6a12d..0b3c0aa874 100644 --- a/test/UnitTests/ResourceHooks/ResourceHookExecutor/IdentifiableManyToMany_OnReturnTests.cs +++ b/test/UnitTests/ResourceHooks/ResourceHookExecutor/IdentifiableManyToMany_OnReturnTests.cs @@ -45,6 +45,7 @@ public void OnReturn_GetRelationship() hookExecutor.OnReturn(articles, ResourcePipeline.GetRelationship); // Assert + articleResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(articles).Any()), ResourcePipeline.GetRelationship), Times.Once()); joinResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(joins).Any()), ResourcePipeline.GetRelationship), Times.Once()); tagResourceMock.Verify(rd => rd.OnReturn(It.Is>((collection) => !collection.Except(tags).Any()), ResourcePipeline.GetRelationship), Times.Once()); VerifyNoOtherCalls(articleResourceMock, joinResourceMock, tagResourceMock);