From cef43b8b914eca55a136ed649c302dae42338ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 14 Dec 2018 16:38:14 +0100 Subject: [PATCH 1/4] Add abstract base class to enrich repository json responses --- .../web/AbstractRepositoryJsonEnricher.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java diff --git a/scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java b/scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java new file mode 100644 index 0000000000..38f353e24b --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java @@ -0,0 +1,40 @@ +package sonia.scm.web; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import static java.util.Collections.singletonMap; +import static sonia.scm.web.VndMediaType.REPOSITORY; +import static sonia.scm.web.VndMediaType.REPOSITORY_COLLECTION; + +public abstract class AbstractRepositoryJsonEnricher extends JsonEnricherBase { + + public AbstractRepositoryJsonEnricher(ObjectMapper objectMapper) { + super(objectMapper); + } + + @Override + public void enrich(JsonEnricherContext context) { + if (resultHasMediaType(REPOSITORY, context)) { + JsonNode repositoryNode = context.getResponseEntity(); + enrichRepositoryNode(repositoryNode); + } else if (resultHasMediaType(REPOSITORY_COLLECTION, context)) { + JsonNode repositoryCollectionNode = context.getResponseEntity().get("_embedded").withArray("repositories"); + repositoryCollectionNode.elements().forEachRemaining(this::enrichRepositoryNode); + } + } + + private void enrichRepositoryNode(JsonNode repositoryNode) { + String namespace = repositoryNode.get("namespace").asText(); + String name = repositoryNode.get("name").asText(); + + enrichRepositoryNode(repositoryNode, namespace, name); + } + + protected abstract void enrichRepositoryNode(JsonNode repositoryNode, String namespace, String name); + + protected void addLink(JsonNode repositoryNode, String linkName, String link) { + JsonNode newPullRequestNode = createObject(singletonMap("href", value(link))); + addPropertyNode(repositoryNode.get("_links"), linkName, newPullRequestNode); + } +} From c0ba6984e9fa37b91266d4729cc5c7ceb0901951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 14 Dec 2018 16:51:40 +0100 Subject: [PATCH 2/4] Add unit test --- .../AbstractRepositoryJsonEnricherTest.java | 107 ++++++++++++++++++ .../sonia/scm/repository/repository-001.json | 42 +++++++ .../repository/repository-collection-001.json | 106 +++++++++++++++++ 3 files changed, 255 insertions(+) create mode 100644 scm-core/src/test/java/sonia/scm/web/AbstractRepositoryJsonEnricherTest.java create mode 100644 scm-core/src/test/resources/sonia/scm/repository/repository-001.json create mode 100644 scm-core/src/test/resources/sonia/scm/repository/repository-collection-001.json diff --git a/scm-core/src/test/java/sonia/scm/web/AbstractRepositoryJsonEnricherTest.java b/scm-core/src/test/java/sonia/scm/web/AbstractRepositoryJsonEnricherTest.java new file mode 100644 index 0000000000..2c8ef76464 --- /dev/null +++ b/scm-core/src/test/java/sonia/scm/web/AbstractRepositoryJsonEnricherTest.java @@ -0,0 +1,107 @@ +package sonia.scm.web; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.common.io.Resources; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.junit.jupiter.MockitoExtension; +import sonia.scm.api.v2.resources.ScmPathInfoStore; + +import javax.ws.rs.core.MediaType; +import java.io.IOException; +import java.net.URI; +import java.net.URL; + +import static org.assertj.core.api.Assertions.assertThat; + +@ExtendWith(MockitoExtension.class) +class AbstractRepositoryJsonEnricherTest { + + private final ObjectMapper objectMapper = new ObjectMapper(); + private AbstractRepositoryJsonEnricher linkEnricher; + private JsonNode rootNode; + + @BeforeEach + void globalSetUp() { + ScmPathInfoStore pathInfoStore = new ScmPathInfoStore(); + pathInfoStore.set(() -> URI.create("/")); + + linkEnricher = new AbstractRepositoryJsonEnricher(objectMapper) { + @Override + protected void enrichRepositoryNode(JsonNode repositoryNode, String namespace, String name) { + addLink(repositoryNode, "new-link", "/somewhere"); + } + }; + } + + @Test + void shouldEnrichRepositories() throws IOException { + URL resource = Resources.getResource("sonia/scm/repository/repository-001.json"); + rootNode = objectMapper.readTree(resource); + + JsonEnricherContext context = new JsonEnricherContext( + URI.create("/"), + MediaType.valueOf(VndMediaType.REPOSITORY), + rootNode + ); + + linkEnricher.enrich(context); + + String configLink = context.getResponseEntity() + .get("_links") + .get("new-link") + .get("href") + .asText(); + + assertThat(configLink).isEqualTo("/somewhere"); + } + + @Test + void shouldEnrichAllRepositories() throws IOException { + URL resource = Resources.getResource("sonia/scm/repository/repository-collection-001.json"); + rootNode = objectMapper.readTree(resource); + + JsonEnricherContext context = new JsonEnricherContext( + URI.create("/"), + MediaType.valueOf(VndMediaType.REPOSITORY_COLLECTION), + rootNode + ); + + linkEnricher.enrich(context); + + context.getResponseEntity() + .get("_embedded") + .withArray("repositories") + .elements() + .forEachRemaining(node -> { + String configLink = node + .get("_links") + .get("new-link") + .get("href") + .asText(); + + assertThat(configLink).isEqualTo("/somewhere"); + }); + } + + @Test + void shouldNotModifyObjectsWithUnsupportedMediaType() throws IOException { + URL resource = Resources.getResource("sonia/scm/repository/repository-001.json"); + rootNode = objectMapper.readTree(resource); + JsonEnricherContext context = new JsonEnricherContext( + URI.create("/"), + MediaType.valueOf(VndMediaType.USER), + rootNode + ); + + linkEnricher.enrich(context); + + boolean hasNewPullRequestLink = context.getResponseEntity() + .get("_links") + .has("new-link"); + + assertThat(hasNewPullRequestLink).isFalse(); + } +} diff --git a/scm-core/src/test/resources/sonia/scm/repository/repository-001.json b/scm-core/src/test/resources/sonia/scm/repository/repository-001.json new file mode 100644 index 0000000000..43ea136942 --- /dev/null +++ b/scm-core/src/test/resources/sonia/scm/repository/repository-001.json @@ -0,0 +1,42 @@ +{ + "creationDate": "2018-11-09T09:48:32.732Z", + "description": "Handling static webresources made easy", + "healthCheckFailures": [], + "lastModified": "2018-11-09T09:49:20.973Z", + "namespace": "scmadmin", + "name": "web-resources", + "archived": false, + "type": "git", + "_links": { + "self": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "delete": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "update": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "permissions": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/permissions/" + }, + "protocol": [ + { + "href": "http://localhost:8081/scm/repo/scmadmin/web-resources", + "name": "http" + } + ], + "tags": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/tags/" + }, + "branches": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/branches/" + }, + "changesets": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/changesets/" + }, + "sources": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/sources/" + } + } +} diff --git a/scm-core/src/test/resources/sonia/scm/repository/repository-collection-001.json b/scm-core/src/test/resources/sonia/scm/repository/repository-collection-001.json new file mode 100644 index 0000000000..f4eeb24bbc --- /dev/null +++ b/scm-core/src/test/resources/sonia/scm/repository/repository-collection-001.json @@ -0,0 +1,106 @@ +{ + "page": 0, + "pageTotal": 1, + "_links": { + "self": { + "href": "http://localhost:8081/scm/api/v2/repositories/?page=0&pageSize=10" + }, + "first": { + "href": "http://localhost:8081/scm/api/v2/repositories/?page=0&pageSize=10" + }, + "last": { + "href": "http://localhost:8081/scm/api/v2/repositories/?page=0&pageSize=10" + }, + "create": { + "href": "http://localhost:8081/scm/api/v2/repositories/" + } + }, + "_embedded": { + "repositories": [ + { + "creationDate": "2018-11-09T09:48:32.732Z", + "description": "Handling static webresources made easy", + "healthCheckFailures": [], + "lastModified": "2018-11-09T09:49:20.973Z", + "namespace": "scmadmin", + "name": "web-resources", + "archived": false, + "type": "git", + "_links": { + "self": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "delete": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "update": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "permissions": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/permissions/" + }, + "protocol": [ + { + "href": "http://localhost:8081/scm/repo/scmadmin/web-resources", + "name": "http" + } + ], + "tags": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/tags/" + }, + "branches": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/branches/" + }, + "changesets": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/changesets/" + }, + "sources": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/sources/" + } + } + }, + { + "creationDate": "2018-11-09T09:48:32.732Z", + "description": "Handling static webresources made easy", + "healthCheckFailures": [], + "lastModified": "2018-11-09T09:49:20.973Z", + "namespace": "scmadmin", + "name": "web-resources", + "archived": false, + "type": "git", + "_links": { + "self": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "delete": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "update": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources" + }, + "permissions": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/permissions/" + }, + "protocol": [ + { + "href": "http://localhost:8081/scm/repo/scmadmin/web-resources", + "name": "http" + } + ], + "tags": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/tags/" + }, + "branches": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/branches/" + }, + "changesets": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/changesets/" + }, + "sources": { + "href": "http://localhost:8081/scm/api/v2/repositories/scmadmin/web-resources/sources/" + } + } + } + ] + } +} From 84e27b60d4e9b1b6edc3ab9c64159803d8da3f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 14 Dec 2018 17:20:22 +0100 Subject: [PATCH 3/4] Give attribute proper name --- .../java/sonia/scm/web/AbstractRepositoryJsonEnricher.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java b/scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java index 38f353e24b..2cb4674d24 100644 --- a/scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java +++ b/scm-core/src/main/java/sonia/scm/web/AbstractRepositoryJsonEnricher.java @@ -34,7 +34,7 @@ public abstract class AbstractRepositoryJsonEnricher extends JsonEnricherBase { protected abstract void enrichRepositoryNode(JsonNode repositoryNode, String namespace, String name); protected void addLink(JsonNode repositoryNode, String linkName, String link) { - JsonNode newPullRequestNode = createObject(singletonMap("href", value(link))); - addPropertyNode(repositoryNode.get("_links"), linkName, newPullRequestNode); + JsonNode hrefNode = createObject(singletonMap("href", value(link))); + addPropertyNode(repositoryNode.get("_links"), linkName, hrefNode); } } From 01eb287bb0b2def04832733f34bc0a790cde20d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Fri, 14 Dec 2018 16:21:36 +0000 Subject: [PATCH 4/4] Close branch feature/abstract_repository_enricher