From f7f47007482cb118d4c8f316faaa963dbb6df32c Mon Sep 17 00:00:00 2001 From: maurei Date: Tue, 19 Jan 2021 14:16:38 +0100 Subject: [PATCH 1/2] fix invalid casting issue for get secondary resource on return hook --- .../Hooks/Internal/ResourceHookExecutor.cs | 2 +- .../Internal/ResourceHookExecutorFacade.cs | 2 +- .../ResourceDefinitionTests.cs | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) 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..2ac7f0f1f8 100644 --- a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs +++ b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs @@ -121,7 +121,7 @@ public object OnReturnRelationship(object resourceOrResources) { if (resourceOrResources is IEnumerable enumerable) { - var resources = enumerable.Cast(); + dynamic resources = enumerable; 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() { From 8ede13cc28fdb4efc1be36aff1228c5a01837860 Mon Sep 17 00:00:00 2001 From: maurei Date: Tue, 19 Jan 2021 14:25:43 +0100 Subject: [PATCH 2/2] unit test and simplified usage of dynamic --- .../Hooks/Internal/ResourceHookExecutorFacade.cs | 4 ++-- .../IdentifiableManyToMany_OnReturnTests.cs | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs b/src/JsonApiDotNetCore/Hooks/Internal/ResourceHookExecutorFacade.cs index 2ac7f0f1f8..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) { - dynamic resources = enumerable; + dynamic resources = resourceOrResources; return _resourceHookExecutor.OnReturn(resources, ResourcePipeline.GetRelationship).ToArray(); } 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);