mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 00:15:44 +01:00
file history endpoint
This commit is contained in:
@@ -6,11 +6,12 @@ import sonia.scm.repository.Repository;
|
|||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public class ChangesetCollectionToDtoMapper extends BasicCollectionToDtoMapper<Changeset, ChangesetDto, ChangesetToChangesetDtoMapper> {
|
public class ChangesetCollectionToDtoMapper extends BasicCollectionToDtoMapper<Changeset, ChangesetDto, ChangesetToChangesetDtoMapper> {
|
||||||
|
|
||||||
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
|
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
|
||||||
private final ResourceLinks resourceLinks;
|
protected final ResourceLinks resourceLinks;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||||
@@ -20,10 +21,14 @@ public class ChangesetCollectionToDtoMapper extends BasicCollectionToDtoMapper<C
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository) {
|
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository) {
|
||||||
return super.map(pageNumber, pageSize, pageResult, createSelfLink(repository), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
|
return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createSelfLink(Repository repository) {
|
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, Supplier<String> selfLinkSupplier) {
|
||||||
|
return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String createSelfLink(Repository repository) {
|
||||||
return resourceLinks.changeset().all(repository.getNamespace(), repository.getName());
|
return resourceLinks.changeset().all(repository.getNamespace(), repository.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import sonia.scm.PageResult;
|
||||||
|
import sonia.scm.repository.Changeset;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMapper {
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FileHistoryCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) {
|
||||||
|
super(changesetToChangesetDtoMapper, resourceLinks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public CollectionDto map(int pageNumber, int pageSize, PageResult<Changeset> pageResult, Repository repository, String revision, String path) {
|
||||||
|
return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, revision, path));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String createSelfLink(Repository repository, String revision, String path) {
|
||||||
|
return super.resourceLinks.fileHistory().self(repository.getNamespace(), repository.getName(), revision, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import sonia.scm.PageResult;
|
||||||
|
import sonia.scm.repository.Changeset;
|
||||||
|
import sonia.scm.repository.ChangesetPagingResult;
|
||||||
|
import sonia.scm.repository.InternalRepositoryException;
|
||||||
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.RepositoryNotFoundException;
|
||||||
|
import sonia.scm.repository.RevisionNotFoundException;
|
||||||
|
import sonia.scm.repository.api.RepositoryService;
|
||||||
|
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||||
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.Produces;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FileHistoryRootResource {
|
||||||
|
|
||||||
|
private final RepositoryServiceFactory serviceFactory;
|
||||||
|
|
||||||
|
private final FileHistoryCollectionToDtoMapper fileHistoryCollectionToDtoMapper;
|
||||||
|
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
public FileHistoryRootResource(RepositoryServiceFactory serviceFactory, FileHistoryCollectionToDtoMapper fileHistoryCollectionToDtoMapper) {
|
||||||
|
this.serviceFactory = serviceFactory;
|
||||||
|
this.fileHistoryCollectionToDtoMapper = fileHistoryCollectionToDtoMapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GET
|
||||||
|
@Path("{revision}/{path: .*}")
|
||||||
|
@StatusCodes({
|
||||||
|
@ResponseCode(code = 200, condition = "success"),
|
||||||
|
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
|
||||||
|
@ResponseCode(code = 403, condition = "not authorized, the current user has no privileges to read the changeset"),
|
||||||
|
@ResponseCode(code = 404, condition = "not found, no changesets available in the repository"),
|
||||||
|
@ResponseCode(code = 500, condition = "internal server error")
|
||||||
|
})
|
||||||
|
@Produces(VndMediaType.CHANGESET_COLLECTION)
|
||||||
|
@TypeHint(CollectionDto.class)
|
||||||
|
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name,
|
||||||
|
@PathParam("revision") String revision,
|
||||||
|
@PathParam("path") String path,
|
||||||
|
@DefaultValue("0") @QueryParam("page") int page,
|
||||||
|
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException, RevisionNotFoundException, RepositoryNotFoundException {
|
||||||
|
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
|
||||||
|
log.info("Get changesets of the file {} and revision {}", path, revision);
|
||||||
|
Repository repository = repositoryService.getRepository();
|
||||||
|
ChangesetPagingResult changesets = repositoryService.getLogCommand()
|
||||||
|
.setPagingStart(page)
|
||||||
|
.setPagingLimit(pageSize)
|
||||||
|
.setPath(path)
|
||||||
|
.setStartChangeset(revision)
|
||||||
|
.getChangesets();
|
||||||
|
if (changesets != null && changesets.getChangesets() != null) {
|
||||||
|
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
|
||||||
|
return Response.ok(fileHistoryCollectionToDtoMapper.map(page, pageSize, pageResult, repository, revision, path)).build();
|
||||||
|
} else {
|
||||||
|
String message = String.format("for the revision %s and the file %s there is no changesets", revision, path);
|
||||||
|
log.error(message);
|
||||||
|
throw new InternalRepositoryException(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,8 @@ import sonia.scm.repository.SubRepository;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
|
|
||||||
|
import static de.otto.edison.hal.Link.link;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public abstract class FileObjectToFileObjectDtoMapper extends BaseMapper<FileObject, FileObjectDto> {
|
public abstract class FileObjectToFileObjectDtoMapper extends BaseMapper<FileObject, FileObjectDto> {
|
||||||
|
|
||||||
@@ -30,6 +32,7 @@ public abstract class FileObjectToFileObjectDtoMapper extends BaseMapper<FileObj
|
|||||||
links.self(addPath(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, ""), path));
|
links.self(addPath(resourceLinks.source().sourceWithPath(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, ""), path));
|
||||||
} else {
|
} else {
|
||||||
links.self(addPath(resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, ""), path));
|
links.self(addPath(resourceLinks.source().content(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, ""), path));
|
||||||
|
links.single(link("history", resourceLinks.fileHistory().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), revision, path)));
|
||||||
}
|
}
|
||||||
|
|
||||||
dto.add(links.build());
|
dto.add(links.build());
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import sonia.scm.api.rest.StatusExceptionMapper;
|
||||||
|
import sonia.scm.repository.InternalRepositoryException;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import javax.ws.rs.ext.Provider;
|
||||||
|
|
||||||
|
@Provider
|
||||||
|
public class InternalRepositoryExceptionMapper extends StatusExceptionMapper<InternalRepositoryException> {
|
||||||
|
|
||||||
|
public InternalRepositoryExceptionMapper() {
|
||||||
|
super(InternalRepositoryException.class, Response.Status.INTERNAL_SERVER_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,6 +40,7 @@ public class RepositoryResource {
|
|||||||
private final Provider<ContentResource> contentResource;
|
private final Provider<ContentResource> contentResource;
|
||||||
private final Provider<PermissionRootResource> permissionRootResource;
|
private final Provider<PermissionRootResource> permissionRootResource;
|
||||||
private final Provider<DiffRootResource> diffRootResource;
|
private final Provider<DiffRootResource> diffRootResource;
|
||||||
|
private final Provider<FileHistoryRootResource> fileHistoryRootResource;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RepositoryResource(
|
public RepositoryResource(
|
||||||
@@ -50,7 +51,8 @@ public class RepositoryResource {
|
|||||||
Provider<ChangesetRootResource> changesetRootResource,
|
Provider<ChangesetRootResource> changesetRootResource,
|
||||||
Provider<SourceRootResource> sourceRootResource, Provider<ContentResource> contentResource,
|
Provider<SourceRootResource> sourceRootResource, Provider<ContentResource> contentResource,
|
||||||
Provider<PermissionRootResource> permissionRootResource,
|
Provider<PermissionRootResource> permissionRootResource,
|
||||||
Provider<DiffRootResource> diffRootResource) {
|
Provider<DiffRootResource> diffRootResource,
|
||||||
|
Provider<FileHistoryRootResource> fileHistoryRootResource) {
|
||||||
this.dtoToRepositoryMapper = dtoToRepositoryMapper;
|
this.dtoToRepositoryMapper = dtoToRepositoryMapper;
|
||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
this.repositoryToDtoMapper = repositoryToDtoMapper;
|
this.repositoryToDtoMapper = repositoryToDtoMapper;
|
||||||
@@ -62,6 +64,7 @@ public class RepositoryResource {
|
|||||||
this.contentResource = contentResource;
|
this.contentResource = contentResource;
|
||||||
this.permissionRootResource = permissionRootResource;
|
this.permissionRootResource = permissionRootResource;
|
||||||
this.diffRootResource = diffRootResource;
|
this.diffRootResource = diffRootResource;
|
||||||
|
this.fileHistoryRootResource = fileHistoryRootResource;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -165,6 +168,11 @@ public class RepositoryResource {
|
|||||||
return changesetRootResource.get();
|
return changesetRootResource.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Path("history/")
|
||||||
|
public FileHistoryRootResource history() {
|
||||||
|
return fileHistoryRootResource.get();
|
||||||
|
}
|
||||||
|
|
||||||
@Path("sources/")
|
@Path("sources/")
|
||||||
public SourceRootResource sources() {
|
public SourceRootResource sources() {
|
||||||
return sourceRootResource.get();
|
return sourceRootResource.get();
|
||||||
|
|||||||
@@ -307,6 +307,23 @@ class ResourceLinks {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FileHistoryLinks fileHistory() {
|
||||||
|
return new FileHistoryLinks(uriInfoStore.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FileHistoryLinks {
|
||||||
|
private final LinkBuilder fileHistoryLinkBuilder;
|
||||||
|
|
||||||
|
FileHistoryLinks(UriInfo uriInfo) {
|
||||||
|
fileHistoryLinkBuilder = new LinkBuilder(uriInfo, RepositoryRootResource.class, RepositoryResource.class, FileHistoryRootResource.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
String self(String namespace, String name, String changesetId, String path) {
|
||||||
|
return fileHistoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("history").parameters().method("getAll").parameters(changesetId, path).href();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public SourceLinks source() {
|
public SourceLinks source() {
|
||||||
return new SourceLinks(uriInfoStore.get());
|
return new SourceLinks(uriInfoStore.get());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,7 +92,7 @@ public class BranchRootResourceTest {
|
|||||||
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
|
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
|
||||||
BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks);
|
BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks);
|
||||||
branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper, changesetCollectionToDtoMapper);
|
branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper, changesetCollectionToDtoMapper);
|
||||||
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(new RepositoryResource(null, null, null, null, MockProvider.of(branchRootResource), null, null, null, null, null)), null);
|
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(new RepositoryResource(null, null, null, null, MockProvider.of(branchRootResource), null, null, null, null, null, null)), null);
|
||||||
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
|
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
|
||||||
|
|
||||||
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
|
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ public class ChangesetRootResourceTest {
|
|||||||
changesetRootResource = new ChangesetRootResource(serviceFactory, changesetCollectionToDtoMapper, changesetToChangesetDtoMapper);
|
changesetRootResource = new ChangesetRootResource(serviceFactory, changesetCollectionToDtoMapper, changesetToChangesetDtoMapper);
|
||||||
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
|
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
|
||||||
.of(new RepositoryResource(null, null, null, null, null,
|
.of(new RepositoryResource(null, null, null, null, null,
|
||||||
MockProvider.of(changesetRootResource), null, null, null, null)), null);
|
MockProvider.of(changesetRootResource), null, null, null, null, null)), null);
|
||||||
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
|
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
|
||||||
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
|
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
|
||||||
when(serviceFactory.create(any(Repository.class))).thenReturn(service);
|
when(serviceFactory.create(any(Repository.class))).thenReturn(service);
|
||||||
@@ -125,7 +125,6 @@ public class ChangesetRootResourceTest {
|
|||||||
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName)));
|
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName)));
|
||||||
assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail)));
|
assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail)));
|
||||||
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
||||||
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -155,7 +154,6 @@ public class ChangesetRootResourceTest {
|
|||||||
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName)));
|
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName)));
|
||||||
assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail)));
|
assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail)));
|
||||||
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
||||||
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,203 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.shiro.subject.Subject;
|
||||||
|
import org.apache.shiro.subject.support.SubjectThreadState;
|
||||||
|
import org.apache.shiro.util.ThreadContext;
|
||||||
|
import org.apache.shiro.util.ThreadState;
|
||||||
|
import org.assertj.core.util.Lists;
|
||||||
|
import org.jboss.resteasy.core.Dispatcher;
|
||||||
|
import org.jboss.resteasy.mock.MockDispatcherFactory;
|
||||||
|
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||||
|
import org.jboss.resteasy.mock.MockHttpResponse;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
import sonia.scm.api.rest.AuthorizationExceptionMapper;
|
||||||
|
import sonia.scm.repository.Changeset;
|
||||||
|
import sonia.scm.repository.ChangesetPagingResult;
|
||||||
|
import sonia.scm.repository.InternalRepositoryException;
|
||||||
|
import sonia.scm.repository.NamespaceAndName;
|
||||||
|
import sonia.scm.repository.Person;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.RepositoryNotFoundException;
|
||||||
|
import sonia.scm.repository.RevisionNotFoundException;
|
||||||
|
import sonia.scm.repository.api.LogCommandBuilder;
|
||||||
|
import sonia.scm.repository.api.RepositoryService;
|
||||||
|
import sonia.scm.repository.api.RepositoryServiceFactory;
|
||||||
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.time.Instant;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.anyInt;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.Silent.class)
|
||||||
|
@Slf4j
|
||||||
|
public class FileHistoryResourceTest {
|
||||||
|
|
||||||
|
public static final String FILE_HISTORY_PATH = "space/repo/history/";
|
||||||
|
public static final String FILE_HISTORY_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + FILE_HISTORY_PATH;
|
||||||
|
private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
|
||||||
|
|
||||||
|
private final URI baseUri = URI.create("/");
|
||||||
|
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RepositoryServiceFactory serviceFactory;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RepositoryService service;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private LogCommandBuilder logCommandBuilder;
|
||||||
|
|
||||||
|
private FileHistoryCollectionToDtoMapper fileHistoryCollectionToDtoMapper;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
|
||||||
|
|
||||||
|
private FileHistoryRootResource fileHistoryRootResource;
|
||||||
|
|
||||||
|
|
||||||
|
private final Subject subject = mock(Subject.class);
|
||||||
|
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
|
||||||
|
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void prepareEnvironment() throws Exception {
|
||||||
|
fileHistoryCollectionToDtoMapper = new FileHistoryCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
|
||||||
|
fileHistoryRootResource = new FileHistoryRootResource(serviceFactory, fileHistoryCollectionToDtoMapper);
|
||||||
|
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
|
||||||
|
.of(new RepositoryResource(null, null, null, null, null,
|
||||||
|
null, null, null, null, null, MockProvider.of(fileHistoryRootResource))), null);
|
||||||
|
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
|
||||||
|
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(service);
|
||||||
|
when(serviceFactory.create(any(Repository.class))).thenReturn(service);
|
||||||
|
when(service.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo"));
|
||||||
|
dispatcher.getProviderFactory().registerProvider(NotFoundExceptionMapper.class);
|
||||||
|
dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class);
|
||||||
|
dispatcher.getProviderFactory().registerProvider(InternalRepositoryExceptionMapper.class);
|
||||||
|
when(service.getLogCommand()).thenReturn(logCommandBuilder);
|
||||||
|
subjectThreadState.bind();
|
||||||
|
ThreadContext.bind(subject);
|
||||||
|
when(subject.isPermitted(any(String.class))).thenReturn(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void cleanupContext() {
|
||||||
|
ThreadContext.unbindSubject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGetFileHistory() throws Exception {
|
||||||
|
String id = "revision_123";
|
||||||
|
String path = "root_dir/sub_dir/file-to-inspect.txt";
|
||||||
|
Instant creationDate = Instant.now();
|
||||||
|
String authorName = "name";
|
||||||
|
String authorEmail = "em@i.l";
|
||||||
|
String commit = "my branch commit";
|
||||||
|
ChangesetPagingResult changesetPagingResult = mock(ChangesetPagingResult.class);
|
||||||
|
List<Changeset> changesetList = Lists.newArrayList(new Changeset(id, Date.from(creationDate).getTime(), new Person(authorName, authorEmail), commit));
|
||||||
|
when(changesetPagingResult.getChangesets()).thenReturn(changesetList);
|
||||||
|
when(changesetPagingResult.getTotal()).thenReturn(1);
|
||||||
|
when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setStartChangeset(eq(id))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPath(eq(path))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult);
|
||||||
|
MockHttpRequest request = MockHttpRequest
|
||||||
|
.get(FILE_HISTORY_URL + id + "/" + path)
|
||||||
|
.accept(VndMediaType.CHANGESET_COLLECTION);
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
assertEquals(200, response.getStatus());
|
||||||
|
log.info("Response :{}", response.getContentAsString());
|
||||||
|
assertTrue(response.getContentAsString().contains(String.format("\"id\":\"%s\"", id)));
|
||||||
|
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", authorName)));
|
||||||
|
assertTrue(response.getContentAsString().contains(String.format("\"mail\":\"%s\"", authorEmail)));
|
||||||
|
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGet404OnMissingRepository() throws URISyntaxException, RepositoryNotFoundException {
|
||||||
|
when(serviceFactory.create(any(NamespaceAndName.class))).thenThrow(RepositoryNotFoundException.class);
|
||||||
|
MockHttpRequest request = MockHttpRequest
|
||||||
|
.get(FILE_HISTORY_URL + "revision/a.txt")
|
||||||
|
.accept(VndMediaType.CHANGESET_COLLECTION);
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
assertEquals(404, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGet404OnMissingRevision() throws Exception {
|
||||||
|
String id = "revision_123";
|
||||||
|
String path = "root_dir/sub_dir/file-to-inspect.txt";
|
||||||
|
|
||||||
|
when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setStartChangeset(eq(id))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPath(eq(path))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.getChangesets()).thenThrow(RevisionNotFoundException.class);
|
||||||
|
|
||||||
|
MockHttpRequest request = MockHttpRequest
|
||||||
|
.get(FILE_HISTORY_URL + id + "/" + path)
|
||||||
|
.accept(VndMediaType.CHANGESET_COLLECTION);
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
assertEquals(404, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGet500OnInternalRepositoryException() throws Exception {
|
||||||
|
String id = "revision_123";
|
||||||
|
String path = "root_dir/sub_dir/file-to-inspect.txt";
|
||||||
|
|
||||||
|
when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setStartChangeset(eq(id))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPath(eq(path))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.getChangesets()).thenThrow(InternalRepositoryException.class);
|
||||||
|
|
||||||
|
MockHttpRequest request = MockHttpRequest
|
||||||
|
.get(FILE_HISTORY_URL + id + "/" + path)
|
||||||
|
.accept(VndMediaType.CHANGESET_COLLECTION);
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
assertEquals(500, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldGet500OnNullChangesets() throws Exception {
|
||||||
|
String id = "revision_123";
|
||||||
|
String path = "root_dir/sub_dir/file-to-inspect.txt";
|
||||||
|
|
||||||
|
when(logCommandBuilder.setPagingStart(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setStartChangeset(eq(id))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.setPath(eq(path))).thenReturn(logCommandBuilder);
|
||||||
|
when(logCommandBuilder.getChangesets()).thenReturn(null);
|
||||||
|
|
||||||
|
MockHttpRequest request = MockHttpRequest
|
||||||
|
.get(FILE_HISTORY_URL + id + "/" + path)
|
||||||
|
.accept(VndMediaType.CHANGESET_COLLECTION);
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
assertEquals(500, response.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -138,7 +138,7 @@ public class PermissionRootResourceTest {
|
|||||||
permissionCollectionToDtoMapper = new PermissionCollectionToDtoMapper(permissionToPermissionDtoMapper, resourceLinks);
|
permissionCollectionToDtoMapper = new PermissionCollectionToDtoMapper(permissionToPermissionDtoMapper, resourceLinks);
|
||||||
permissionRootResource = new PermissionRootResource(permissionDtoToPermissionMapper, permissionToPermissionDtoMapper, permissionCollectionToDtoMapper, resourceLinks, repositoryManager);
|
permissionRootResource = new PermissionRootResource(permissionDtoToPermissionMapper, permissionToPermissionDtoMapper, permissionCollectionToDtoMapper, resourceLinks, repositoryManager);
|
||||||
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
|
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
|
||||||
.of(new RepositoryResource(null, null, null, null, null, null, null, null, MockProvider.of(permissionRootResource), null)), null);
|
.of(new RepositoryResource(null, null, null, null, null, null, null, null, MockProvider.of(permissionRootResource), null, null)), null);
|
||||||
dispatcher = createDispatcher(repositoryRootResource);
|
dispatcher = createDispatcher(repositoryRootResource);
|
||||||
subjectThreadState.bind();
|
subjectThreadState.bind();
|
||||||
ThreadContext.bind(subject);
|
ThreadContext.bind(subject);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ public class RepositoryRootResourceTest {
|
|||||||
@Before
|
@Before
|
||||||
public void prepareEnvironment() {
|
public void prepareEnvironment() {
|
||||||
initMocks(this);
|
initMocks(this);
|
||||||
RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, dtoToRepositoryMapper, repositoryManager, null, null, null, null, null, null, null);
|
RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, dtoToRepositoryMapper, repositoryManager, null, null, null, null, null, null, null, null);
|
||||||
RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper = new RepositoryCollectionToDtoMapper(repositoryToDtoMapper, resourceLinks);
|
RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper = new RepositoryCollectionToDtoMapper(repositoryToDtoMapper, resourceLinks);
|
||||||
RepositoryCollectionResource repositoryCollectionResource = new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper, dtoToRepositoryMapper, resourceLinks);
|
RepositoryCollectionResource repositoryCollectionResource = new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper, dtoToRepositoryMapper, resourceLinks);
|
||||||
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(repositoryResource), MockProvider.of(repositoryCollectionResource));
|
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(repositoryResource), MockProvider.of(repositoryCollectionResource));
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ public class ResourceLinksMock {
|
|||||||
when(resourceLinks.tag()).thenReturn(new ResourceLinks.TagCollectionLinks(uriInfo));
|
when(resourceLinks.tag()).thenReturn(new ResourceLinks.TagCollectionLinks(uriInfo));
|
||||||
when(resourceLinks.branchCollection()).thenReturn(new ResourceLinks.BranchCollectionLinks(uriInfo));
|
when(resourceLinks.branchCollection()).thenReturn(new ResourceLinks.BranchCollectionLinks(uriInfo));
|
||||||
when(resourceLinks.changeset()).thenReturn(new ResourceLinks.ChangesetLinks(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.source()).thenReturn(new ResourceLinks.SourceLinks(uriInfo));
|
||||||
when(resourceLinks.permission()).thenReturn(new ResourceLinks.PermissionLinks(uriInfo));
|
when(resourceLinks.permission()).thenReturn(new ResourceLinks.PermissionLinks(uriInfo));
|
||||||
when(resourceLinks.config()).thenReturn(new ResourceLinks.ConfigLinks(uriInfo));
|
when(resourceLinks.config()).thenReturn(new ResourceLinks.ConfigLinks(uriInfo));
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
import org.jboss.resteasy.core.Dispatcher;
|
import org.jboss.resteasy.core.Dispatcher;
|
||||||
import org.jboss.resteasy.mock.MockDispatcherFactory;
|
|
||||||
import org.jboss.resteasy.mock.MockHttpRequest;
|
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||||
import org.jboss.resteasy.mock.MockHttpResponse;
|
import org.jboss.resteasy.mock.MockHttpResponse;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -74,6 +73,7 @@ public class SourceRootResourceTest {
|
|||||||
MockProvider.of(sourceRootResource),
|
MockProvider.of(sourceRootResource),
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
null)),
|
null)),
|
||||||
null);
|
null);
|
||||||
dispatcher = createDispatcher(repositoryRootResource);
|
dispatcher = createDispatcher(repositoryRootResource);
|
||||||
|
|||||||
Reference in New Issue
Block a user