diff --git a/scm-core/src/main/java/sonia/scm/NotFoundException.java b/scm-core/src/main/java/sonia/scm/NotFoundException.java index 0d8c14c61b..8a7ae642bd 100644 --- a/scm-core/src/main/java/sonia/scm/NotFoundException.java +++ b/scm-core/src/main/java/sonia/scm/NotFoundException.java @@ -7,9 +7,4 @@ public class NotFoundException extends Exception { public NotFoundException() { } - - - public NotFoundException(String message) { - super(message); - } } diff --git a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java index 4934094083..3f8832a3f5 100644 --- a/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java +++ b/scm-it/src/test/java/sonia/scm/it/RepositoryAccessITCase.java @@ -172,7 +172,7 @@ public class RepositoryAccessITCase { .isNotNull() .contains(String.format("%s/sources/%s", repositoryUrl, changeset.getId())); - assertThat(response.body().jsonPath().getString("_embedded.tags.find{it.name=='" + tagName + "'}._links.changesets.href")) + assertThat(response.body().jsonPath().getString("_embedded.tags.find{it.name=='" + tagName + "'}._links.changeset.href")) .as("assert single tag changesets link") .isNotNull() .contains(String.format("%s/changesets/%s", repositoryUrl, changeset.getId())); diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java new file mode 100644 index 0000000000..afe8ad318b --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchChangesetCollectionToDtoMapper.java @@ -0,0 +1,26 @@ +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 BranchChangesetCollectionToDtoMapper extends ChangesetCollectionToDtoMapperBase { + + private final ResourceLinks resourceLinks; + + @Inject + public BranchChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { + super(changesetToChangesetDtoMapper); + this.resourceLinks = resourceLinks; + } + + public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, String branch) { + return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository, branch)); + } + + private String createSelfLink(Repository repository, String branch) { + return resourceLinks.branch().history(repository.getNamespaceAndName(), branch); + } +} diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java index 9763f11def..7414f5c21f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/BranchRootResource.java @@ -3,6 +3,7 @@ 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 sonia.scm.NotFoundException; import sonia.scm.PageResult; import sonia.scm.repository.Branches; import sonia.scm.repository.Changeset; @@ -32,14 +33,14 @@ public class BranchRootResource { private final BranchToBranchDtoMapper branchToDtoMapper; private final BranchCollectionToDtoMapper branchCollectionToDtoMapper; - private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + private final BranchChangesetCollectionToDtoMapper branchChangesetCollectionToDtoMapper; @Inject - public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { + public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper, BranchChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { this.serviceFactory = serviceFactory; this.branchToDtoMapper = branchToDtoMapper; this.branchCollectionToDtoMapper = branchCollectionToDtoMapper; - this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper; + this.branchChangesetCollectionToDtoMapper = changesetCollectionToDtoMapper; } /** @@ -98,6 +99,14 @@ public class BranchRootResource { @DefaultValue("0") @QueryParam("page") int page, @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception { try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { + boolean branchExists = repositoryService.getBranchesCommand() + .getBranches() + .getBranches() + .stream() + .anyMatch(branch -> branchName.equals(branch.getName())); + if (!branchExists){ + throw new NotFoundException("branch", branchName); + } Repository repository = repositoryService.getRepository(); RepositoryPermissions.read(repository).check(); ChangesetPagingResult changesets = repositoryService.getLogCommand() @@ -107,7 +116,7 @@ public class BranchRootResource { .getChangesets(); if (changesets != null && changesets.getChangesets() != null) { PageResult pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); - return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); + return Response.ok(branchChangesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository, branchName)).build(); } else { return Response.ok().build(); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java index 2f7ac86e14..24ee9b0ce1 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapper.java @@ -5,31 +5,22 @@ import sonia.scm.repository.Changeset; import sonia.scm.repository.Repository; import javax.inject.Inject; -import java.util.Optional; -import java.util.function.Supplier; -public class ChangesetCollectionToDtoMapper extends PagedCollectionToDtoMapper { +public class ChangesetCollectionToDtoMapper extends ChangesetCollectionToDtoMapperBase { - private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper; - protected final ResourceLinks resourceLinks; + private final ResourceLinks resourceLinks; @Inject public ChangesetCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { - super("changesets"); - this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper; + super(changesetToChangesetDtoMapper); this.resourceLinks = resourceLinks; } public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository) { - return this.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository)); + return super.map(pageNumber, pageSize, pageResult, repository, () -> createSelfLink(repository)); } - public CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, Supplier selfLinkSupplier) { - return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository)); - } - - protected String createSelfLink(Repository repository) { + private String createSelfLink(Repository repository) { return resourceLinks.changeset().all(repository.getNamespace(), repository.getName()); } } - diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java new file mode 100644 index 0000000000..e29a0a92b2 --- /dev/null +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/ChangesetCollectionToDtoMapperBase.java @@ -0,0 +1,23 @@ +package sonia.scm.api.v2.resources; + +import sonia.scm.PageResult; +import sonia.scm.repository.Changeset; +import sonia.scm.repository.Repository; + +import java.util.Optional; +import java.util.function.Supplier; + +class ChangesetCollectionToDtoMapperBase extends PagedCollectionToDtoMapper { + + private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper; + + ChangesetCollectionToDtoMapperBase(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) { + super("changesets"); + this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper; + } + + CollectionDto map(int pageNumber, int pageSize, PageResult pageResult, Repository repository, Supplier selfLinkSupplier) { + return super.map(pageNumber, pageSize, pageResult, selfLinkSupplier.get(), Optional.empty(), changeset -> changesetToChangesetDtoMapper.map(changeset, repository)); + } +} + diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java index 692b2f57b1..af7fb2ed83 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/FileHistoryCollectionToDtoMapper.java @@ -6,19 +6,22 @@ import sonia.scm.repository.Repository; import javax.inject.Inject; -public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMapper { +public class FileHistoryCollectionToDtoMapper extends ChangesetCollectionToDtoMapperBase { + private final ResourceLinks resourceLinks; + @Inject public FileHistoryCollectionToDtoMapper(ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper, ResourceLinks resourceLinks) { - super(changesetToChangesetDtoMapper, resourceLinks); + super(changesetToChangesetDtoMapper); + this.resourceLinks = resourceLinks; } public CollectionDto map(int pageNumber, int pageSize, PageResult 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); + private String createSelfLink(Repository repository, String revision, String path) { + return resourceLinks.fileHistory().self(repository.getNamespace(), repository.getName(), revision, path); } } diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java index 2a587bc2fe..b7f6df8c2d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/PermissionRootResource.java @@ -162,7 +162,7 @@ public class PermissionRootResource { RepositoryPermissions.permissionWrite(repository).check(); String extractedPermissionName = getPermissionName(permissionName); if (!isPermissionExist(new PermissionDto(extractedPermissionName, isGroupPermission(permissionName)), repository)) { - throw new NotFoundException("the permission " + extractedPermissionName + " does not exist"); + throw new NotFoundException("permission", extractedPermissionName); } permission.setGroupPermission(isGroupPermission(permissionName)); if (!extractedPermissionName.equals(permission.getName())) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java index 917b4b7789..ee0488e037 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java +++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/TagToTagDtoMapper.java @@ -28,7 +28,7 @@ public abstract class TagToTagDtoMapper { Links.Builder linksBuilder = linkingTo() .self(resourceLinks.tag().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getName())) .single(link("sources", resourceLinks.source().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision()))) - .single(link("changesets", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision()))); + .single(link("changeset", resourceLinks.changeset().self(namespaceAndName.getNamespace(), namespaceAndName.getName(), target.getRevision()))); target.add(linksBuilder.build()); } } diff --git a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java index 13ed9cddcd..4994c11b08 100644 --- a/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java +++ b/scm-webapp/src/test/java/sonia/scm/api/v2/resources/BranchRootResourceTest.java @@ -67,7 +67,7 @@ public class BranchRootResourceTest extends RepositoryTestBase { @InjectMocks private BranchToBranchDtoMapperImpl branchToDtoMapper; - private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; + private BranchChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; private BranchRootResource branchRootResource; @@ -90,7 +90,7 @@ public class BranchRootResourceTest extends RepositoryTestBase { @Before public void prepareEnvironment() throws Exception { - changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks); + changesetCollectionToDtoMapper = new BranchChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks); BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks); branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper, changesetCollectionToDtoMapper); super.branchRootResource = Providers.of(branchRootResource); @@ -152,6 +152,10 @@ public class BranchRootResourceTest extends RepositoryTestBase { when(logCommandBuilder.setPagingLimit(anyInt())).thenReturn(logCommandBuilder); when(logCommandBuilder.setBranch(anyString())).thenReturn(logCommandBuilder); when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult); + Branches branches = mock(Branches.class); + List branchList = Lists.newArrayList(new Branch("master",id)); + when(branches.getBranches()).thenReturn(branchList); + when(branchesCommandBuilder.getBranches()).thenReturn(branches); MockHttpRequest request = MockHttpRequest.get(BRANCH_URL + "/changesets/"); MockHttpResponse response = new MockHttpResponse(); dispatcher.invoke(request, response); @@ -161,6 +165,5 @@ public class BranchRootResourceTest extends RepositoryTestBase { 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))); - assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit))); } } diff --git a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java index b7d231cf38..a67c275bc0 100644 --- a/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java +++ b/scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java @@ -38,6 +38,7 @@ import com.github.sdorra.shiro.SubjectAware; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Sets; import org.apache.shiro.authz.UnauthorizedException; +import org.apache.shiro.util.ThreadContext; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -94,6 +95,10 @@ import static org.mockito.Mockito.when; ) public class DefaultRepositoryManagerTest extends ManagerTestBase { + { + ThreadContext.unbindSubject(); + } + @Rule public ShiroRule shiro = new ShiroRule();