From 0363cab87022ad46cf47b2e403e4bf5fe24bf6f7 Mon Sep 17 00:00:00 2001 From: Tom Page Date: Wed, 11 Sep 2024 15:19:53 +0100 Subject: [PATCH] ACS-8754 Return 405 status code when calling /entity/id/relationship against a resource that only supports ReadById. --- .../webscripts/ResourceWebScriptGet.java | 4 ++ .../framework/tests/core/ExecutionTests.java | 61 +++++++++++++++++-- .../tests/core/ParamsExtractorTests.java | 13 ++-- 3 files changed, 66 insertions(+), 12 deletions(-) diff --git a/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptGet.java b/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptGet.java index 87ee84c074..f895720057 100644 --- a/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptGet.java +++ b/remote-api/src/main/java/org/alfresco/rest/framework/webscripts/ResourceWebScriptGet.java @@ -244,6 +244,10 @@ public class ResourceWebScriptGet extends AbstractResourceWebScript implements P { throw new DeletedResourceException("(GET) "+resource.getMetaData().getUniqueId()); } + if (!RelationshipResourceAction.ReadWithResponse.class.isAssignableFrom(resource.getResource().getClass())) + { + throw new UnsupportedResourceOperationException(); + } RelationshipResourceAction.ReadWithResponse relationGetter = (RelationshipResourceAction.ReadWithResponse) resource.getResource(); CollectionWithPagingInfo relations = relationGetter.readAll(params.getEntityId(),params,withResponse); return relations; diff --git a/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ExecutionTests.java b/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ExecutionTests.java index 6f20ef3040..6ac8d3aa48 100644 --- a/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ExecutionTests.java +++ b/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ExecutionTests.java @@ -26,34 +26,47 @@ package org.alfresco.rest.framework.tests.core; -import static org.junit.Assert.*; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyInt; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.alfresco.rest.framework.core.ResourceMetadata.RESOURCE_TYPE.RELATIONSHIP; + import org.alfresco.rest.framework.Api; import org.alfresco.rest.framework.core.ResourceLocator; import org.alfresco.rest.framework.core.ResourceLookupDictionary; +import org.alfresco.rest.framework.core.ResourceMetadata; import org.alfresco.rest.framework.core.ResourceWithMetadata; -import org.alfresco.rest.framework.core.exceptions.*; +import org.alfresco.rest.framework.core.exceptions.ApiException; +import org.alfresco.rest.framework.core.exceptions.DefaultExceptionResolver; +import org.alfresco.rest.framework.core.exceptions.EntityNotFoundException; +import org.alfresco.rest.framework.core.exceptions.ErrorResponse; +import org.alfresco.rest.framework.core.exceptions.SimpleMappingExceptionResolver; +import org.alfresco.rest.framework.core.exceptions.UnsupportedResourceOperationException; import org.alfresco.rest.framework.jacksonextensions.ExecutionResult; import org.alfresco.rest.framework.resource.actions.ActionExecutor; +import org.alfresco.rest.framework.resource.actions.interfaces.RelationshipResourceAction; import org.alfresco.rest.framework.resource.content.ContentInfo; import org.alfresco.rest.framework.resource.parameters.CollectionWithPagingInfo; import org.alfresco.rest.framework.resource.parameters.Params; import org.alfresco.rest.framework.tests.api.mocks.CowEntityResource; import org.alfresco.rest.framework.tests.api.mocks.Goat; import org.alfresco.rest.framework.tests.api.mocks.Grass; +import org.alfresco.rest.framework.tests.api.mocks.GrassEntityResource; import org.alfresco.rest.framework.tests.api.mocks.Sheep; import org.alfresco.rest.framework.tests.api.mocks3.FlockEntityResource; import org.alfresco.rest.framework.tools.ApiAssistant; import org.alfresco.rest.framework.tools.ResponseWriter; import org.alfresco.rest.framework.webscripts.AbstractResourceWebScript; import org.alfresco.rest.framework.webscripts.ApiWebScript; +import org.alfresco.rest.framework.webscripts.ResourceWebScriptGet; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.invocation.InvocationOnMock; @@ -337,6 +350,46 @@ public class ExecutionTests extends AbstractContextTest implements ResponseWrite assertFalse("Only 500 errors should have a logId", errorMessage.contains("\"logId\":\" \"")); } + @Test + public void testSuccessfulReadByIdRequest() throws Throwable + { + ResourceWebScriptGet extractor = new ResourceWebScriptGet(); + ResourceWithMetadata resource = mock(ResourceWithMetadata.class); + RelationshipResourceAction.ReadById readByIdEntity = mock(RelationshipResourceAction.ReadById.class); + when(resource.getResource()).thenReturn(readByIdEntity); + ResourceMetadata resourceMetadata = mock(ResourceMetadata.class); + when(resourceMetadata.getType()).thenReturn(RELATIONSHIP); + when(resource.getMetaData()).thenReturn(resourceMetadata); + + Params params = mock(Params.class); + when(params.getEntityId()).thenReturn("farms/1234/fields"); + when(params.getRelationshipId()).thenReturn("5678"); + + GrassEntityResource entity = new GrassEntityResource(); + when(readByIdEntity.readById("farms/1234/fields", "5678", params)).thenReturn(entity); + + Object response = extractor.executeAction(resource, params, null); + + assertEquals("Unexpected entity returned", entity, response); + } + + @Test(expected = UnsupportedResourceOperationException.class) + public void testReadAllAgainstResourceSupportingReadById() throws Throwable + { + ResourceWebScriptGet extractor = new ResourceWebScriptGet(); + ResourceWithMetadata resource = mock(ResourceWithMetadata.class); + RelationshipResourceAction.ReadById readByIdEntity = mock(RelationshipResourceAction.ReadById.class); + when(resource.getResource()).thenReturn(readByIdEntity); + ResourceMetadata resourceMetadata = mock(ResourceMetadata.class); + when(resourceMetadata.getType()).thenReturn(RELATIONSHIP); + when(resource.getMetaData()).thenReturn(resourceMetadata); + + Params params = mock(Params.class); + when(params.getRelationshipId()).thenReturn(null); + + extractor.executeAction(resource, params, null); + } + private WebScriptResponse mockResponse() throws IOException { return mockResponse(new ByteArrayOutputStream()); diff --git a/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ParamsExtractorTests.java b/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ParamsExtractorTests.java index 4d523319f3..38ffdfcf97 100644 --- a/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ParamsExtractorTests.java +++ b/remote-api/src/test/java/org/alfresco/rest/framework/tests/core/ParamsExtractorTests.java @@ -36,6 +36,8 @@ import static org.mockito.ArgumentMatchers.notNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; +import static org.alfresco.rest.framework.core.ResourceMetadata.RESOURCE_TYPE.RELATIONSHIP; + import java.io.File; import java.io.IOException; import java.io.PrintWriter; @@ -460,13 +462,7 @@ public class ParamsExtractorTests testExtractAddressedParams(templateVars, request, extractor); } - - @Test - public void testHeaderParsing() throws IOException - { - - } - + @Test public void testSpecialChars() throws IOException { @@ -510,6 +506,7 @@ public class ParamsExtractorTests assertTrue(pVal.equals("香 香蕉")); } + /** * Mocks a Entity Resource * @return ResourceMetadata a Entity @@ -557,7 +554,7 @@ public class ParamsExtractorTests ResourceMetadata resourceMock = mock(ResourceMetadata.class); ResourceOperation resourceOperation = mock(ResourceOperation.class); when(resourceMock.getOperation(notNull())).thenReturn(resourceOperation); - when(resourceMock.getType()).thenReturn(ResourceMetadata.RESOURCE_TYPE.RELATIONSHIP); + when(resourceMock.getType()).thenReturn(RELATIONSHIP); when(resourceMock.getObjectType(notNull())).thenReturn(Farmer.class); return resourceMock; }