Append import link to repository type

This commit is contained in:
Eduard Heimbuch
2020-11-27 14:25:23 +01:00
parent 3265d1cefb
commit 599639bc48
5 changed files with 94 additions and 6 deletions

View File

@@ -21,17 +21,20 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package sonia.scm.api.v2.resources;
import de.otto.edison.hal.Links;
import org.mapstruct.AfterMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.repository.RepositoryType;
import sonia.scm.repository.api.Command;
import javax.inject.Inject;
import static de.otto.edison.hal.Link.link;
import static de.otto.edison.hal.Links.linkingTo;
@Mapper
@@ -43,6 +46,11 @@ public abstract class RepositoryTypeToRepositoryTypeDtoMapper extends BaseMapper
@AfterMapping
void appendLinks(RepositoryType repositoryType, @MappingTarget RepositoryTypeDto target) {
Links.Builder linksBuilder = linkingTo().self(resourceLinks.repositoryType().self(repositoryType.getName()));
if (RepositoryPermissions.create().isPermitted() && repositoryType.getSupportedCommands().contains(Command.PULL)) {
linksBuilder.single(link("importFromUrl", resourceLinks.repository().importFromUrl(repositoryType.getName())));
}
target.add(linksBuilder.build());
}

View File

@@ -334,9 +334,11 @@ class ResourceLinks {
static class RepositoryLinks {
private final LinkBuilder repositoryLinkBuilder;
private final LinkBuilder repositoryImportLinkBuilder;
RepositoryLinks(ScmPathInfo pathInfo) {
repositoryLinkBuilder = new LinkBuilder(pathInfo, RepositoryRootResource.class, RepositoryResource.class);
repositoryImportLinkBuilder = new LinkBuilder(pathInfo, RepositoryRootResource.class, RepositoryImportResource.class);
}
String self(String namespace, String name) {
@@ -354,6 +356,10 @@ class ResourceLinks {
String rename(String namespace, String name) {
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("rename").parameters().href();
}
String importFromUrl(String type) {
return repositoryImportLinkBuilder.method("getRepositoryImportResource").parameters().method("importFromUrl").parameters(type).href();
}
}
RepositoryCollectionLinks repositoryCollection() {

View File

@@ -29,10 +29,14 @@ import com.google.common.collect.Sets;
import de.otto.edison.hal.Embedded;
import de.otto.edison.hal.HalRepresentation;
import de.otto.edison.hal.Link;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
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.repository.RepositoryType;
@@ -50,10 +54,13 @@ public class RepositoryTypeCollectionToDtoMapperTest {
@SuppressWarnings("unused") // Is injected
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
@Mock
private Subject subject;
@InjectMocks
private RepositoryTypeToRepositoryTypeDtoMapperImpl mapper;
private List<RepositoryType> types = Lists.newArrayList(
private final List<RepositoryType> types = Lists.newArrayList(
new RepositoryType("hk", "Hitchhiker", Sets.newHashSet()),
new RepositoryType("hog", "Heart of Gold", Sets.newHashSet())
);
@@ -63,6 +70,12 @@ public class RepositoryTypeCollectionToDtoMapperTest {
@Before
public void setUpEnvironment() {
collectionMapper = new RepositoryTypeCollectionToDtoMapper(mapper, resourceLinks);
ThreadContext.bind(subject);
}
@After
public void tearDown() {
ThreadContext.unbindSubject();
}
@Test

View File

@@ -27,8 +27,11 @@ package sonia.scm.api.v2.resources;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.inject.util.Providers;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
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;
@@ -55,10 +58,12 @@ import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
public class RepositoryTypeRootResourceTest {
private RestDispatcher dispatcher = new RestDispatcher();
private final RestDispatcher dispatcher = new RestDispatcher();
@Mock
private RepositoryManager repositoryManager;
@Mock
private Subject subject;
private final URI baseUri = URI.create("/");
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
@@ -66,13 +71,15 @@ public class RepositoryTypeRootResourceTest {
@InjectMocks
private RepositoryTypeToRepositoryTypeDtoMapperImpl mapper;
private List<RepositoryType> types = Lists.newArrayList(
private final List<RepositoryType> types = Lists.newArrayList(
new RepositoryType("hk", "Hitchhiker", Sets.newHashSet()),
new RepositoryType("hog", "Heart of Gold", Sets.newHashSet())
);
@Before
public void prepareEnvironment() {
ThreadContext.bind(subject);
when(repositoryManager.getConfiguredTypes()).thenReturn(types);
RepositoryTypeCollectionToDtoMapper collectionMapper = new RepositoryTypeCollectionToDtoMapper(mapper, resourceLinks);
@@ -82,6 +89,11 @@ public class RepositoryTypeRootResourceTest {
dispatcher.addSingletonResource(rootResource);
}
@After
public void tearDown() {
ThreadContext.unbindSubject();
}
@Test
public void shouldHaveCollectionVndMediaType() throws URISyntaxException {
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryTypeRootResource.PATH);

View File

@@ -21,19 +21,28 @@
* 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.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ThreadContext;
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.repository.RepositoryType;
import sonia.scm.repository.api.Command;
import java.net.URI;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
public class RepositoryTypeToRepositoryTypeDtoMapperTest {
@@ -43,10 +52,23 @@ public class RepositoryTypeToRepositoryTypeDtoMapperTest {
@SuppressWarnings("unused") // Is injected
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
@Mock
private Subject subject;
@InjectMocks
private RepositoryTypeToRepositoryTypeDtoMapperImpl mapper;
private RepositoryType type = new RepositoryType("hk", "Hitchhiker", Sets.newHashSet());
private final RepositoryType type = new RepositoryType("hk", "Hitchhiker", Sets.newHashSet());
@Before
public void init() {
ThreadContext.bind(subject);
}
@After
public void tearDown() {
ThreadContext.unbindSubject();
}
@Test
public void shouldMapSimpleProperties() {
@@ -63,4 +85,31 @@ public class RepositoryTypeToRepositoryTypeDtoMapperTest {
dto.getLinks().getLinkBy("self").get().getHref()
);
}
@Test
public void shouldAppendImportFromUrlLink() {
RepositoryType type = new RepositoryType("hk", "Hitchhiker", ImmutableSet.of(Command.PULL));
when(subject.isPermitted("repository:create")).thenReturn(true);
RepositoryTypeDto dto = mapper.map(type);
assertEquals(
"https://scm-manager.org/scm/v2/repositories/import/hk/url",
dto.getLinks().getLinkBy("importFromUrl").get().getHref()
);
}
@Test
public void shouldNotAppendImportFromUrlLinkIfCommandNotSupported() {
when(subject.isPermitted("repository:create")).thenReturn(true);
RepositoryTypeDto dto = mapper.map(type);
assertFalse(dto.getLinks().getLinkBy("importFromUrl").isPresent());
}
@Test
public void shouldNotAppendImportFromUrlLinkIfNotPermitted() {
RepositoryType type = new RepositoryType("hk", "Hitchhiker", ImmutableSet.of(Command.PULL));
RepositoryTypeDto dto = mapper.map(type);
assertFalse(dto.getLinks().getLinkBy("importFromUrl").isPresent());
}
}