Add annotate rest resource

This commit is contained in:
René Pfeuffer
2020-06-11 17:21:25 +02:00
parent c16c4893ae
commit 4cb898edbb
13 changed files with 478 additions and 49 deletions

View File

@@ -0,0 +1,147 @@
/*
* MIT License
*
* Copyright (c) 2020-present Cloudogu GmbH and Contributors
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.assertj.core.api.Assertions;
import org.jboss.resteasy.mock.MockHttpRequest;
import org.jboss.resteasy.mock.MockHttpResponse;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import sonia.scm.repository.BlameLine;
import sonia.scm.repository.BlameResult;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Person;
import sonia.scm.repository.api.BlameCommandBuilder;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.web.RestDispatcher;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Iterator;
import static java.util.Arrays.asList;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
class AnnotateResourceTest extends RepositoryTestBase {
public static final NamespaceAndName NAMESPACE_AND_NAME = new NamespaceAndName("space", "X");
public static final String REVISION = "123";
public static final String PATH = "some/file";
@Mock
private RepositoryServiceFactory serviceFactory;
@Mock
private RepositoryService service;
@Mock
private BlameCommandBuilder blameCommandBuilder;
private final RestDispatcher dispatcher = new RestDispatcher();
private final MockHttpResponse response = new MockHttpResponse();
@BeforeEach
void initResource() {
BlameResultToBlameDtoMapperImpl mapper = new BlameResultToBlameDtoMapperImpl();
mapper.setResourceLinks(ResourceLinksMock.createMock(URI.create("/")));
annotateResource = new AnnotateResource(serviceFactory, mapper);
dispatcher.addSingletonResource(getRepositoryRootResource());
}
@BeforeEach
void initRepositoryService() {
when(serviceFactory.create(NAMESPACE_AND_NAME)).thenReturn(service);
when(service.getBlameCommand()).thenReturn(blameCommandBuilder);
}
@BeforeEach
void initBlameCommand() throws IOException {
BlameLine line1 = new BlameLine(
0,
"100",
System.currentTimeMillis(),
new Person("Arthur Dent", "arthur@hitchhiker.com"),
"first try",
"jump"
);
BlameLine line2 = new BlameLine(
1,
"42",
System.currentTimeMillis(),
new Person("Zaphod Beeblebrox", "zaphod@hitchhiker.com"),
"got it",
"heart of gold"
);
BlameResult result = new BlameResult(asList(line1, line2));
when(blameCommandBuilder.setRevision(REVISION)).thenReturn(blameCommandBuilder);
when(blameCommandBuilder.getBlameResult(PATH)).thenReturn(result);
}
@Test
void test() throws URISyntaxException, UnsupportedEncodingException, JsonProcessingException {
MockHttpRequest request = MockHttpRequest
.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + NAMESPACE_AND_NAME + "/annotate/" + REVISION + "/" + PATH);
dispatcher.invoke(request, response);
assertThat(response.getStatus()).isEqualTo(200);
String content = response.getContentAsString();
ObjectMapper mapper = new ObjectMapper();
JsonNode jsonNode = mapper.readTree(content);
JsonNode blameLines = jsonNode.get("blameLines");
assertThat(blameLines.isArray()).isTrue();
assertThat(jsonNode.get("_links").get("self").get("href").asText())
.isEqualTo("/v2/repositories/space/X/annotate/123/some%2Ffile");
Iterator<JsonNode> lineIterator = blameLines.iterator();
JsonNode line1 = lineIterator.next();
assertThat(line1.get("author").get("mail").asText()).isEqualTo("arthur@hitchhiker.com");
assertThat(line1.get("author").get("name").asText()).isEqualTo("Arthur Dent");
assertThat(line1.get("code").asText()).isEqualTo("jump");
assertThat(line1.get("description").asText()).isEqualTo("first try");
assertThat(line1.get("lineNumber").asInt()).isEqualTo(0);
assertThat(line1.get("revision").asText()).isEqualTo("100");
JsonNode line2 = lineIterator.next();
assertThat(line2.get("author").get("mail").asText()).isEqualTo("zaphod@hitchhiker.com");
assertThat(line2.get("author").get("name").asText()).isEqualTo("Zaphod Beeblebrox");
assertThat(line2.get("code").asText()).isEqualTo("heart of gold");
assertThat(line2.get("description").asText()).isEqualTo("got it");
assertThat(line2.get("lineNumber").asInt()).isEqualTo(1);
assertThat(line2.get("revision").asText()).isEqualTo("42");
assertThat(lineIterator.hasNext()).isFalse();
}
}

View File

@@ -45,6 +45,7 @@ abstract class RepositoryTestBase {
FileHistoryRootResource fileHistoryRootResource;
IncomingRootResource incomingRootResource;
RepositoryCollectionResource repositoryCollectionResource;
AnnotateResource annotateResource;
RepositoryRootResource getRepositoryRootResource() {
@@ -58,8 +59,8 @@ abstract class RepositoryTestBase {
of(diffRootResource),
of(modificationsRootResource),
of(fileHistoryRootResource),
of(incomingRootResource)
);
of(incomingRootResource),
of(annotateResource));
return new RepositoryRootResource(
of(new RepositoryResource(
repositoryToDtoMapper,

View File

@@ -21,11 +21,12 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import java.net.URI;
import static org.mockito.Mockito.lenient;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -33,47 +34,48 @@ public class ResourceLinksMock {
public static ResourceLinks createMock(URI baseUri) {
ResourceLinks resourceLinks = mock(ResourceLinks.class);
ScmPathInfo uriInfo = mock(ScmPathInfo.class);
when(uriInfo.getApiRestUri()).thenReturn(baseUri);
ScmPathInfo pathInfo = mock(ScmPathInfo.class);
when(pathInfo.getApiRestUri()).thenReturn(baseUri);
ResourceLinks.UserLinks userLinks = new ResourceLinks.UserLinks(uriInfo);
when(resourceLinks.user()).thenReturn(userLinks);
when(resourceLinks.me()).thenReturn(new ResourceLinks.MeLinks(uriInfo,userLinks));
when(resourceLinks.userCollection()).thenReturn(new ResourceLinks.UserCollectionLinks(uriInfo));
when(resourceLinks.userPermissions()).thenReturn(new ResourceLinks.UserPermissionLinks(uriInfo));
when(resourceLinks.autoComplete()).thenReturn(new ResourceLinks.AutoCompleteLinks(uriInfo));
when(resourceLinks.group()).thenReturn(new ResourceLinks.GroupLinks(uriInfo));
when(resourceLinks.groupCollection()).thenReturn(new ResourceLinks.GroupCollectionLinks(uriInfo));
when(resourceLinks.groupPermissions()).thenReturn(new ResourceLinks.GroupPermissionLinks(uriInfo));
when(resourceLinks.repository()).thenReturn(new ResourceLinks.RepositoryLinks(uriInfo));
when(resourceLinks.incoming()).thenReturn(new ResourceLinks.IncomingLinks(uriInfo));
when(resourceLinks.repositoryCollection()).thenReturn(new ResourceLinks.RepositoryCollectionLinks(uriInfo));
when(resourceLinks.tag()).thenReturn(new ResourceLinks.TagCollectionLinks(uriInfo));
when(resourceLinks.branchCollection()).thenReturn(new ResourceLinks.BranchCollectionLinks(uriInfo));
when(resourceLinks.changeset()).thenReturn(new ResourceLinks.ChangesetLinks(uriInfo));
when(resourceLinks.fileHistory()).thenReturn(new ResourceLinks.FileHistoryLinks(uriInfo));
when(resourceLinks.source()).thenReturn(new ResourceLinks.SourceLinks(uriInfo));
when(resourceLinks.repositoryPermission()).thenReturn(new ResourceLinks.RepositoryPermissionLinks(uriInfo));
when(resourceLinks.config()).thenReturn(new ResourceLinks.ConfigLinks(uriInfo));
when(resourceLinks.branch()).thenReturn(new ResourceLinks.BranchLinks(uriInfo));
when(resourceLinks.diff()).thenReturn(new ResourceLinks.DiffLinks(uriInfo));
when(resourceLinks.modifications()).thenReturn(new ResourceLinks.ModificationsLinks(uriInfo));
when(resourceLinks.repositoryType()).thenReturn(new ResourceLinks.RepositoryTypeLinks(uriInfo));
when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo));
when(resourceLinks.installedPluginCollection()).thenReturn(new ResourceLinks.InstalledPluginCollectionLinks(uriInfo));
when(resourceLinks.availablePluginCollection()).thenReturn(new ResourceLinks.AvailablePluginCollectionLinks(uriInfo));
when(resourceLinks.pendingPluginCollection()).thenReturn(new ResourceLinks.PendingPluginCollectionLinks(uriInfo));
when(resourceLinks.installedPlugin()).thenReturn(new ResourceLinks.InstalledPluginLinks(uriInfo));
when(resourceLinks.availablePlugin()).thenReturn(new ResourceLinks.AvailablePluginLinks(uriInfo));
when(resourceLinks.uiPluginCollection()).thenReturn(new ResourceLinks.UIPluginCollectionLinks(uriInfo));
when(resourceLinks.uiPlugin()).thenReturn(new ResourceLinks.UIPluginLinks(uriInfo));
when(resourceLinks.authentication()).thenReturn(new ResourceLinks.AuthenticationLinks(uriInfo));
when(resourceLinks.index()).thenReturn(new ResourceLinks.IndexLinks(uriInfo));
when(resourceLinks.permissions()).thenReturn(new ResourceLinks.PermissionsLinks(uriInfo));
when(resourceLinks.repositoryVerbs()).thenReturn(new ResourceLinks.RepositoryVerbLinks(uriInfo));
when(resourceLinks.repositoryRole()).thenReturn(new ResourceLinks.RepositoryRoleLinks(uriInfo));
when(resourceLinks.repositoryRoleCollection()).thenReturn(new ResourceLinks.RepositoryRoleCollectionLinks(uriInfo));
when(resourceLinks.namespaceStrategies()).thenReturn(new ResourceLinks.NamespaceStrategiesLinks(uriInfo));
ResourceLinks.UserLinks userLinks = new ResourceLinks.UserLinks(pathInfo);
lenient().when(resourceLinks.user()).thenReturn(userLinks);
lenient().when(resourceLinks.me()).thenReturn(new ResourceLinks.MeLinks(pathInfo,userLinks));
lenient().when(resourceLinks.userCollection()).thenReturn(new ResourceLinks.UserCollectionLinks(pathInfo));
lenient().when(resourceLinks.userPermissions()).thenReturn(new ResourceLinks.UserPermissionLinks(pathInfo));
lenient().when(resourceLinks.autoComplete()).thenReturn(new ResourceLinks.AutoCompleteLinks(pathInfo));
lenient().when(resourceLinks.group()).thenReturn(new ResourceLinks.GroupLinks(pathInfo));
lenient().when(resourceLinks.groupCollection()).thenReturn(new ResourceLinks.GroupCollectionLinks(pathInfo));
lenient().when(resourceLinks.groupPermissions()).thenReturn(new ResourceLinks.GroupPermissionLinks(pathInfo));
lenient().when(resourceLinks.repository()).thenReturn(new ResourceLinks.RepositoryLinks(pathInfo));
lenient().when(resourceLinks.incoming()).thenReturn(new ResourceLinks.IncomingLinks(pathInfo));
lenient().when(resourceLinks.repositoryCollection()).thenReturn(new ResourceLinks.RepositoryCollectionLinks(pathInfo));
lenient().when(resourceLinks.tag()).thenReturn(new ResourceLinks.TagCollectionLinks(pathInfo));
lenient().when(resourceLinks.branchCollection()).thenReturn(new ResourceLinks.BranchCollectionLinks(pathInfo));
lenient().when(resourceLinks.changeset()).thenReturn(new ResourceLinks.ChangesetLinks(pathInfo));
lenient().when(resourceLinks.fileHistory()).thenReturn(new ResourceLinks.FileHistoryLinks(pathInfo));
lenient().when(resourceLinks.source()).thenReturn(new ResourceLinks.SourceLinks(pathInfo));
lenient().when(resourceLinks.repositoryPermission()).thenReturn(new ResourceLinks.RepositoryPermissionLinks(pathInfo));
lenient().when(resourceLinks.config()).thenReturn(new ResourceLinks.ConfigLinks(pathInfo));
lenient().when(resourceLinks.branch()).thenReturn(new ResourceLinks.BranchLinks(pathInfo));
lenient().when(resourceLinks.diff()).thenReturn(new ResourceLinks.DiffLinks(pathInfo));
lenient().when(resourceLinks.modifications()).thenReturn(new ResourceLinks.ModificationsLinks(pathInfo));
lenient().when(resourceLinks.repositoryType()).thenReturn(new ResourceLinks.RepositoryTypeLinks(pathInfo));
lenient().when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(pathInfo));
lenient().when(resourceLinks.installedPluginCollection()).thenReturn(new ResourceLinks.InstalledPluginCollectionLinks(pathInfo));
lenient().when(resourceLinks.availablePluginCollection()).thenReturn(new ResourceLinks.AvailablePluginCollectionLinks(pathInfo));
lenient().when(resourceLinks.pendingPluginCollection()).thenReturn(new ResourceLinks.PendingPluginCollectionLinks(pathInfo));
lenient().when(resourceLinks.installedPlugin()).thenReturn(new ResourceLinks.InstalledPluginLinks(pathInfo));
lenient().when(resourceLinks.availablePlugin()).thenReturn(new ResourceLinks.AvailablePluginLinks(pathInfo));
lenient().when(resourceLinks.uiPluginCollection()).thenReturn(new ResourceLinks.UIPluginCollectionLinks(pathInfo));
lenient().when(resourceLinks.uiPlugin()).thenReturn(new ResourceLinks.UIPluginLinks(pathInfo));
lenient().when(resourceLinks.authentication()).thenReturn(new ResourceLinks.AuthenticationLinks(pathInfo));
lenient().when(resourceLinks.index()).thenReturn(new ResourceLinks.IndexLinks(pathInfo));
lenient().when(resourceLinks.permissions()).thenReturn(new ResourceLinks.PermissionsLinks(pathInfo));
lenient().when(resourceLinks.repositoryVerbs()).thenReturn(new ResourceLinks.RepositoryVerbLinks(pathInfo));
lenient().when(resourceLinks.repositoryRole()).thenReturn(new ResourceLinks.RepositoryRoleLinks(pathInfo));
lenient().when(resourceLinks.repositoryRoleCollection()).thenReturn(new ResourceLinks.RepositoryRoleCollectionLinks(pathInfo));
lenient().when(resourceLinks.namespaceStrategies()).thenReturn(new ResourceLinks.NamespaceStrategiesLinks(pathInfo));
lenient().when(resourceLinks.annotate()).thenReturn(new ResourceLinks.AnnotateLinks(pathInfo));
return resourceLinks;
}