mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-05-07 09:57:16 +02:00
Generate repository links in dto
This commit is contained in:
@@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import de.otto.edison.hal.HalRepresentation;
|
||||
import de.otto.edison.hal.Links;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@@ -26,4 +27,10 @@ public class RepositoryDto extends HalRepresentation {
|
||||
private boolean publicReadable = false;
|
||||
private boolean archived = false;
|
||||
private String type;
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("squid:S1185") // We want to have this method available in this package
|
||||
protected HalRepresentation add(Links links) {
|
||||
return super.add(links);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import de.otto.edison.hal.Links;
|
||||
import org.mapstruct.AfterMapping;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.MappingTarget;
|
||||
import sonia.scm.repository.HealthCheckFailure;
|
||||
import sonia.scm.repository.Permission;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryPermissions;
|
||||
|
||||
import static de.otto.edison.hal.Link.link;
|
||||
import static de.otto.edison.hal.Links.linkingTo;
|
||||
|
||||
// Mapstruct does not support parameterized (i.e. non-default) constructors. Thus, we need to use field injection.
|
||||
@SuppressWarnings("squid:S3306")
|
||||
@@ -17,4 +24,16 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper<Reposit
|
||||
abstract HealthCheckFailureDto toDto(HealthCheckFailure failure);
|
||||
|
||||
abstract PermissionDto toDto(Permission permission);
|
||||
|
||||
@AfterMapping
|
||||
void appendLinks(Repository repository, @MappingTarget RepositoryDto target) {
|
||||
Links.Builder linksBuilder = linkingTo().self(resourceLinks.repository().self(target.getNamespace(), target.getName()));
|
||||
if (RepositoryPermissions.delete(repository).isPermitted()) {
|
||||
linksBuilder.single(link("delete", resourceLinks.repository().delete(target.getNamespace(), target.getName())));
|
||||
}
|
||||
if (RepositoryPermissions.modify(repository).isPermitted()) {
|
||||
linksBuilder.single(link("update", resourceLinks.repository().update(target.getNamespace(), target.getName())));
|
||||
}
|
||||
target.add(linksBuilder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -100,4 +100,28 @@ class ResourceLinks {
|
||||
return collectionLinkBuilder.method("getUserCollectionResource").parameters().method("create").parameters().href();
|
||||
}
|
||||
}
|
||||
|
||||
public RepositoryLinks repository() {
|
||||
return null;
|
||||
}
|
||||
|
||||
static class RepositoryLinks {
|
||||
private final LinkBuilder repositoryLinkBuilder;
|
||||
|
||||
private RepositoryLinks(UriInfo uriInfo) {
|
||||
repositoryLinkBuilder = new LinkBuilder(uriInfo, RepositoryRootResource.class, RepositoryResource.class);
|
||||
}
|
||||
|
||||
String self(String namespace, String name) {
|
||||
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("get").parameters().href();
|
||||
}
|
||||
|
||||
String delete(String namespace, String name) {
|
||||
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("delete").parameters().href();
|
||||
}
|
||||
|
||||
String update(String namespace, String name) {
|
||||
return repositoryLinkBuilder.method("getRepositoryResource").parameters(namespace, name).method("update").parameters().href();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.github.sdorra.shiro.ShiroRule;
|
||||
import com.github.sdorra.shiro.SubjectAware;
|
||||
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.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.InjectMocks;
|
||||
@@ -22,10 +25,18 @@ import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
@SubjectAware(
|
||||
username = "trillian",
|
||||
password = "secret",
|
||||
configuration = "classpath:sonia/scm/repository/shiro.ini"
|
||||
)
|
||||
public class RepositoryRootResourceTest {
|
||||
|
||||
private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
|
||||
|
||||
@Rule
|
||||
public ShiroRule shiro = new ShiroRule();
|
||||
|
||||
@Mock
|
||||
private RepositoryManager repositoryManager;
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
@@ -71,6 +82,7 @@ public class RepositoryRootResourceTest {
|
||||
Repository repository = new Repository();
|
||||
repository.setNamespace(namespace);
|
||||
repository.setName(name);
|
||||
repository.setId("id");
|
||||
when(repositoryManager.getByNamespace(namespace, name)).thenReturn(repository);
|
||||
return repository;
|
||||
}
|
||||
|
||||
@@ -1,48 +1,110 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
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.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Answers;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import sonia.scm.repository.HealthCheckFailure;
|
||||
import sonia.scm.repository.Permission;
|
||||
import sonia.scm.repository.PermissionType;
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
public class RepositoryToRepositoryDtoMapperTest {
|
||||
|
||||
private RepositoryToRepositoryDtoMapperImpl mapper = new RepositoryToRepositoryDtoMapperImpl();
|
||||
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||
private ResourceLinks resourceLinks;
|
||||
|
||||
@InjectMocks
|
||||
private RepositoryToRepositoryDtoMapperImpl mapper;
|
||||
|
||||
private final Subject subject = mock(Subject.class);
|
||||
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
|
||||
|
||||
private URI expectedBaseUri;
|
||||
|
||||
@Before
|
||||
public void init() throws URISyntaxException {
|
||||
initMocks(this);
|
||||
URI baseUri = new URI("http://example.com/base/");
|
||||
expectedBaseUri = baseUri.resolve(RepositoryRootResource.REPOSITORIES_PATH_V2 + "/");
|
||||
subjectThreadState.bind();
|
||||
ResourceLinksMock.initMock(resourceLinks, baseUri);
|
||||
ThreadContext.bind(subject);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMapSimpleProperties() {
|
||||
RepositoryDto dto = mapper.map(createDummyRepository());
|
||||
assertEquals("namespace", dto.getNamespace());
|
||||
assertEquals("name", dto.getName());
|
||||
RepositoryDto dto = mapper.map(createTestRepository());
|
||||
assertEquals("testspace", dto.getNamespace());
|
||||
assertEquals("test", dto.getName());
|
||||
assertEquals("description", dto.getDescription());
|
||||
assertEquals("git", dto.getType());
|
||||
assertEquals("none@example.com", dto.getContact());
|
||||
assertEquals("1", dto.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateLinksForUnprivilegedUser() {
|
||||
RepositoryDto dto = mapper.map(createTestRepository());
|
||||
assertEquals(
|
||||
"http://example.com/base/v2/groups/testspace/test",
|
||||
dto.getLinks().getLinkBy("self").get().getHref());
|
||||
assertFalse(dto.getLinks().getLinkBy("update").isPresent());
|
||||
assertFalse(dto.getLinks().getLinkBy("delete").isPresent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateDeleteLink() {
|
||||
when(subject.isPermitted("repository:delete:1")).thenReturn(true);
|
||||
RepositoryDto dto = mapper.map(createTestRepository());
|
||||
assertEquals(
|
||||
"http://example.com/base/v2/groups/testspace/test",
|
||||
dto.getLinks().getLinkBy("delete").get().getHref());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateUpdateLink() {
|
||||
when(subject.isPermitted("repository:modify:1")).thenReturn(true);
|
||||
RepositoryDto dto = mapper.map(createTestRepository());
|
||||
assertEquals(
|
||||
"http://example.com/base/v2/groups/testspace/test",
|
||||
dto.getLinks().getLinkBy("update").get().getHref());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMapHealthCheck() {
|
||||
RepositoryDto dto = mapper.map(createDummyRepository());
|
||||
RepositoryDto dto = mapper.map(createTestRepository());
|
||||
assertEquals(1, dto.getHealthCheckFailures().size());
|
||||
assertEquals("summary", dto.getHealthCheckFailures().get(0).getSummary());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMapPermissions() {
|
||||
RepositoryDto dto = mapper.map(createDummyRepository());
|
||||
RepositoryDto dto = mapper.map(createTestRepository());
|
||||
assertEquals(1, dto.getPermissions().size());
|
||||
assertEquals("permission", dto.getPermissions().get(0).getName());
|
||||
assertEquals("READ", dto.getPermissions().get(0).getType());
|
||||
}
|
||||
|
||||
private Repository createDummyRepository() {
|
||||
private Repository createTestRepository() {
|
||||
Repository repository = new Repository();
|
||||
repository.setNamespace("namespace");
|
||||
repository.setName("name");
|
||||
repository.setNamespace("testspace");
|
||||
repository.setName("test");
|
||||
repository.setDescription("description");
|
||||
repository.setType("git");
|
||||
repository.setContact("none@example.com");
|
||||
|
||||
@@ -22,5 +22,9 @@ public class ResourceLinksMock {
|
||||
|
||||
when(resourceLinks.groupCollection().self()).thenAnswer(invocation -> baseUri + GROUPS_PATH_V2);
|
||||
when(resourceLinks.groupCollection().create()).thenAnswer(invocation -> baseUri + GROUPS_PATH_V2);
|
||||
|
||||
when(resourceLinks.repository().self(anyString(), anyString())).thenAnswer(invocation -> baseUri + GROUPS_PATH_V2 + invocation.getArguments()[0] + "/" + invocation.getArguments()[1]);
|
||||
when(resourceLinks.repository().update(anyString(), anyString())).thenAnswer(invocation -> baseUri + GROUPS_PATH_V2 + invocation.getArguments()[0] + "/" + invocation.getArguments()[1]);
|
||||
when(resourceLinks.repository().delete(anyString(), anyString())).thenAnswer(invocation -> baseUri + GROUPS_PATH_V2 + invocation.getArguments()[0] + "/" + invocation.getArguments()[1]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user