merge with branch 2.0.0-m3

This commit is contained in:
Sebastian Sdorra
2018-09-10 14:53:59 +02:00
71 changed files with 2004 additions and 542 deletions

View File

@@ -1,9 +1,16 @@
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;
@@ -12,20 +19,35 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.repository.Branch;
import sonia.scm.repository.Branches;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Person;
import sonia.scm.repository.Repository;
import sonia.scm.repository.api.BranchesCommandBuilder;
import sonia.scm.repository.api.LogCommandBuilder;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory;
import java.net.URI;
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.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
@Slf4j
public class BranchRootResourceTest {
public static final String BRANCH_PATH = "space/repo/branches/master";
public static final String BRANCH_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + BRANCH_PATH;
private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
private final URI baseUri = URI.create("/");
@@ -38,25 +60,62 @@ public class BranchRootResourceTest {
@Mock
private BranchesCommandBuilder branchesCommandBuilder;
@Mock
private LogCommandBuilder logCommandBuilder;
@InjectMocks
private BranchToBranchDtoMapperImpl branchToDtoMapper;
private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
private BranchRootResource branchRootResource;
@Mock
private BranchCollectionToDtoMapper branchCollectionToDtoMapper;
@Mock
private ChangesetToParentDtoMapper changesetToParentDtoMapper;
@Mock
private TagCollectionToDtoMapper tagCollectionToDtoMapper;
@InjectMocks
private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@Before
public void prepareEnvironment() throws Exception {
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks);
BranchRootResource branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper);
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(new RepositoryResource(null, null, null, null, MockProvider.of(branchRootResource), null, null, null, null)), null);
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);
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"));
when(service.getBranchesCommand()).thenReturn(branchesCommandBuilder);
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 shouldHandleMissingBranch() throws Exception {
when(branchesCommandBuilder.getBranches()).thenReturn(new Branches());
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/branches/master");
MockHttpRequest request = MockHttpRequest.get(BRANCH_URL);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
@@ -68,13 +127,40 @@ public class BranchRootResourceTest {
public void shouldFindExistingBranch() throws Exception {
when(branchesCommandBuilder.getBranches()).thenReturn(new Branches(new Branch("master", "revision")));
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/branches/master");
MockHttpRequest request = MockHttpRequest.get(BRANCH_URL);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(200, response.getStatus());
System.out.println(response.getContentAsString());
log.info("Response :{}", response.getContentAsString());
assertTrue(response.getContentAsString().contains("\"revision\":\"revision\""));
}
@Test
public void shouldFindHistory() throws Exception {
String id = "revision_123";
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.setBranch(anyString())).thenReturn(logCommandBuilder);
when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult);
MockHttpRequest request = MockHttpRequest.get(BRANCH_URL + "/changesets/");
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)));
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
}
}

View File

@@ -18,8 +18,11 @@ import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
public class BrowserResultToBrowserResultDtoMapperTest {
@@ -60,6 +63,9 @@ public class BrowserResultToBrowserResultDtoMapperTest {
fileObject2.setPath("/path/object/2");
fileObject2.setDescription("description of file object 2");
fileObject2.setDirectory(true);
when(fileObjectToFileObjectDtoMapper.map(any(FileObject.class), any(NamespaceAndName.class), anyString()))
.thenReturn(new FileObjectDto());
}
@After
@@ -71,7 +77,7 @@ public class BrowserResultToBrowserResultDtoMapperTest {
public void shouldMapAttributesCorrectly() {
BrowserResult browserResult = createBrowserResult();
BrowserResultDto dto = mapper.map(browserResult, new NamespaceAndName("foo", "bar"));
BrowserResultDto dto = mapper.map(browserResult, new NamespaceAndName("foo", "bar"), "path");
assertEqualAttributes(browserResult, dto);
}
@@ -81,17 +87,25 @@ public class BrowserResultToBrowserResultDtoMapperTest {
BrowserResult browserResult = createBrowserResult();
NamespaceAndName namespaceAndName = new NamespaceAndName("foo", "bar");
BrowserResultDto dto = mapper.map(browserResult, namespaceAndName);
BrowserResultDto dto = mapper.map(browserResult, namespaceAndName, "path");
verify(fileObjectToFileObjectDtoMapper).map(fileObject1, namespaceAndName, "Revision");
verify(fileObjectToFileObjectDtoMapper).map(fileObject2, namespaceAndName, "Revision");
}
@Test
public void shouldSetLinksCorrectly() {
BrowserResult browserResult = createBrowserResult();
NamespaceAndName namespaceAndName = new NamespaceAndName("foo", "bar");
BrowserResultDto dto = mapper.map(browserResult, namespaceAndName, "path");
assertThat(dto.getLinks().getLinkBy("self").get().getHref()).contains("path");
}
private BrowserResult createBrowserResult() {
BrowserResult browserResult = new BrowserResult();
browserResult.setTag("Tag");
browserResult.setRevision("Revision");
browserResult.setBranch("Branch");
browserResult.setFiles(createFileObjects());
return browserResult;
@@ -106,8 +120,6 @@ public class BrowserResultToBrowserResultDtoMapperTest {
}
private void assertEqualAttributes(BrowserResult browserResult, BrowserResultDto dto) {
assertThat(dto.getTag()).isEqualTo(browserResult.getTag());
assertThat(dto.getBranch()).isEqualTo(browserResult.getBranch());
assertThat(dto.getRevision()).isEqualTo(browserResult.getRevision());
}

View File

@@ -0,0 +1,161 @@
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.NamespaceAndName;
import sonia.scm.repository.Person;
import sonia.scm.repository.Repository;
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.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.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
@Slf4j
public class ChangesetRootResourceTest {
public static final String CHANGESET_PATH = "space/repo/changesets/";
public static final String CHANGESET_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + CHANGESET_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 repositoryService;
@Mock
private LogCommandBuilder logCommandBuilder;
private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
@InjectMocks
private ChangesetToChangesetDtoMapperImpl changesetToChangesetDtoMapper;
private ChangesetRootResource changesetRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@Before
public void prepareEnvironment() throws Exception {
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
changesetRootResource = new ChangesetRootResource(serviceFactory, changesetCollectionToDtoMapper, changesetToChangesetDtoMapper);
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
.of(new RepositoryResource(null, null, null, null, null,
MockProvider.of(changesetRootResource), null, null, null, null)), null);
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService);
when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService);
when(repositoryService.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo"));
dispatcher.getProviderFactory().registerProvider(NotFoundExceptionMapper.class);
dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class);
when(repositoryService.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 shouldGetChangeSets() throws Exception {
String id = "revision_123";
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.setBranch(anyString())).thenReturn(logCommandBuilder);
when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult);
MockHttpRequest request = MockHttpRequest
.get(CHANGESET_URL)
.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)));
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
}
@Test
public void shouldGetChangeSet() throws Exception {
String id = "revision_123";
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.setEndChangeset(anyString())).thenReturn(logCommandBuilder);
when(logCommandBuilder.setStartChangeset(anyString())).thenReturn(logCommandBuilder);
when(logCommandBuilder.getChangesets()).thenReturn(changesetPagingResult);
MockHttpRequest request = MockHttpRequest
.get(CHANGESET_URL + "id")
.accept(VndMediaType.CHANGESET);
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)));
assertTrue(response.getContentAsString().contains(String.format("\"description\":\"%s\"", commit)));
}
}

View File

@@ -0,0 +1,149 @@
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.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.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.api.rest.AuthorizationExceptionMapper;
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.DiffCommandBuilder;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.web.VndMediaType;
import java.net.URISyntaxException;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class)
@Slf4j
public class DiffResourceTest {
public static final String DIFF_PATH = "space/repo/diff/";
public static final String DIFF_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + DIFF_PATH;
private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
@Mock
private RepositoryServiceFactory serviceFactory;
@Mock
private RepositoryService service;
@Mock
private DiffCommandBuilder diffCommandBuilder;
private DiffRootResource diffRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@Before
public void prepareEnvironment() throws Exception {
diffRootResource = new DiffRootResource(serviceFactory);
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
.of(new RepositoryResource(null, null, null, null, null,
null, null, null, null, MockProvider.of(diffRootResource))), 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(CRLFInjectionExceptionMapper.class);
when(service.getDiffCommand()).thenReturn(diffCommandBuilder);
subjectThreadState.bind();
ThreadContext.bind(subject);
when(subject.isPermitted(any(String.class))).thenReturn(true);
}
@After
public void cleanupContext() {
ThreadContext.unbindSubject();
}
@Test
public void shouldGetDiffs() throws Exception {
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
when(diffCommandBuilder.retriveContent(any())).thenReturn(diffCommandBuilder);
MockHttpRequest request = MockHttpRequest
.get(DIFF_URL + "revision")
.accept(VndMediaType.DIFF);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(200, response.getStatus());
log.info("Response :{}", response.getContentAsString());
assertThat(response.getStatus())
.isEqualTo(200);
assertThat(response.getContentAsString())
.isNotNull();
String expectedHeader = "Content-Disposition";
String expectedValue = "attachment; filename=\"repo-revision.diff\"; filename*=utf-8''repo-revision.diff";
assertThat(response.getOutputHeaders().containsKey(expectedHeader)).isTrue();
assertThat((String) response.getOutputHeaders().get("Content-Disposition").get(0))
.contains(expectedValue);
}
@Test
public void shouldGet404OnMissingRepository() throws URISyntaxException, RepositoryNotFoundException {
when(serviceFactory.create(any(NamespaceAndName.class))).thenThrow(RepositoryNotFoundException.class);
MockHttpRequest request = MockHttpRequest
.get(DIFF_URL + "revision")
.accept(VndMediaType.DIFF);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(404, response.getStatus());
}
@Test
public void shouldGet404OnMissingRevision() throws Exception {
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
when(diffCommandBuilder.retriveContent(any())).thenThrow(RevisionNotFoundException.class);
MockHttpRequest request = MockHttpRequest
.get(DIFF_URL + "revision")
.accept(VndMediaType.DIFF);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(404, response.getStatus());
}
@Test
public void shouldGet400OnCrlfInjection() throws Exception {
when(diffCommandBuilder.setRevision(anyString())).thenReturn(diffCommandBuilder);
when(diffCommandBuilder.retriveContent(any())).thenThrow(RevisionNotFoundException.class);
MockHttpRequest request = MockHttpRequest
.get(DIFF_URL + "ny%0D%0ASet-cookie:%20Tamper=3079675143472450634")
.accept(VndMediaType.DIFF);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(400, response.getStatus());
}
}

View File

@@ -39,6 +39,7 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -55,6 +56,7 @@ import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher;
import static sonia.scm.api.v2.resources.PermissionDto.GROUP_PREFIX;
@Slf4j
@SubjectAware(
@@ -136,7 +138,7 @@ public class PermissionRootResourceTest {
permissionCollectionToDtoMapper = new PermissionCollectionToDtoMapper(permissionToPermissionDtoMapper, resourceLinks);
permissionRootResource = new PermissionRootResource(permissionDtoToPermissionMapper, permissionToPermissionDtoMapper, permissionCollectionToDtoMapper, resourceLinks, repositoryManager);
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
.of(new RepositoryResource(null, null, null, null, null, null, null, null, MockProvider.of(permissionRootResource))), null);
.of(new RepositoryResource(null, null, null, null, null, null, null, null, MockProvider.of(permissionRootResource), null)), null);
dispatcher = createDispatcher(repositoryRootResource);
subjectThreadState.bind();
ThreadContext.bind(subject);
@@ -253,7 +255,7 @@ public class PermissionRootResourceTest {
createUserWithRepositoryAndPermissions(TEST_PERMISSIONS, PERMISSION_WRITE);
Permission newPermission = TEST_PERMISSIONS.get(0);
assertExpectedRequest(requestPOSTPermission
.content("{\"name\" : \"" + newPermission.getName() + "\" , \"type\" : \"WRITE\" , \"groupPermission\" : true}")
.content("{\"name\" : \"" + newPermission.getName() + "\" , \"type\" : \"WRITE\" , \"groupPermission\" : false}")
.expectedResponseStatus(409)
);
}
@@ -358,7 +360,10 @@ public class PermissionRootResourceTest {
result.setName(permission.getName());
result.setGroupPermission(permission.isGroupPermission());
result.setType(permission.getType().name());
String permissionHref = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS + permission.getName();
String permissionName = Optional.of(permission.getName())
.filter(p -> !permission.isGroupPermission())
.orElse(GROUP_PREFIX + permission.getName());
String permissionHref = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + PATH_OF_ALL_PERMISSIONS + permissionName;
if (PERMISSION_READ.equals(userPermission)) {
result.add(linkingTo()
.self(permissionHref)

View File

@@ -0,0 +1,63 @@
package sonia.scm.api.v2.resources;
import com.github.sdorra.shiro.ShiroRule;
import com.github.sdorra.shiro.SubjectAware;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.repository.Permission;
import sonia.scm.repository.PermissionType;
import sonia.scm.repository.Repository;
import java.net.URI;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(MockitoJUnitRunner.Silent.class)
@SubjectAware(
configuration = "classpath:sonia/scm/repository/shiro.ini"
)
public class PermissionToPermissionDtoMapperTest {
@Rule
public ShiroRule shiro = new ShiroRule();
private final URI baseUri = URI.create("http://example.com/base/");
@SuppressWarnings("unused") // Is injected
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
@InjectMocks
PermissionToPermissionDtoMapperImpl mapper;
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldMapGroupPermissionCorrectly() {
Repository repository = getDummyRepository();
Permission permission = new Permission("42", PermissionType.OWNER, true);
PermissionDto permissionDto = mapper.map(permission, repository);
assertThat(permissionDto.getLinks().getLinkBy("self").isPresent()).isTrue();
assertThat(permissionDto.getLinks().getLinkBy("self").get().getHref()).contains("@42");
}
@Test
@SubjectAware(username = "trillian", password = "secret")
public void shouldMapNonGroupPermissionCorrectly() {
Repository repository = getDummyRepository();
Permission permission = new Permission("42", PermissionType.OWNER, false);
PermissionDto permissionDto = mapper.map(permission, repository);
assertThat(permissionDto.getLinks().getLinkBy("self").isPresent()).isTrue();
assertThat(permissionDto.getLinks().getLinkBy("self").get().getHref()).contains("42");
assertThat(permissionDto.getLinks().getLinkBy("self").get().getHref()).doesNotContain("@");
}
private Repository getDummyRepository() {
return new Repository("repo", "git", "foo", "bar");
}
}

View File

@@ -79,7 +79,7 @@ public class RepositoryRootResourceTest {
@Before
public void prepareEnvironment() {
initMocks(this);
RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, dtoToRepositoryMapper, repositoryManager, null, null, null, null, null, null);
RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, dtoToRepositoryMapper, repositoryManager, null, null, null, null, null, null, null);
RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper = new RepositoryCollectionToDtoMapper(repositoryToDtoMapper, resourceLinks);
RepositoryCollectionResource repositoryCollectionResource = new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper, dtoToRepositoryMapper, resourceLinks);
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(repositoryResource), MockProvider.of(repositoryCollectionResource));

View File

@@ -19,13 +19,14 @@ public class ResourceLinksMock {
when(resourceLinks.groupCollection()).thenReturn(new ResourceLinks.GroupCollectionLinks(uriInfo));
when(resourceLinks.repository()).thenReturn(new ResourceLinks.RepositoryLinks(uriInfo));
when(resourceLinks.repositoryCollection()).thenReturn(new ResourceLinks.RepositoryCollectionLinks(uriInfo));
when(resourceLinks.tagCollection()).thenReturn(new ResourceLinks.TagCollectionLinks(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.source()).thenReturn(new ResourceLinks.SourceLinks(uriInfo));
when(resourceLinks.permission()).thenReturn(new ResourceLinks.PermissionLinks(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.repositoryType()).thenReturn(new ResourceLinks.RepositoryTypeLinks(uriInfo));
when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo));
when(resourceLinks.uiPluginCollection()).thenReturn(new ResourceLinks.UIPluginCollectionLinks(uriInfo));

View File

@@ -105,7 +105,7 @@ public class ResourceLinksTest {
@Test
public void shouldCreateCorrectTagCollectionUrl() {
String url = resourceLinks.tagCollection().self("space", "repo");
String url = resourceLinks.tag().all("space", "repo");
assertEquals(BASE_URL + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/tags/", url);
}
@@ -141,7 +141,7 @@ public class ResourceLinksTest {
@Test
public void shouldCreateCorrectChangesetCollectionUrl() {
String url = resourceLinks.changeset().self("space", "repo");
String url = resourceLinks.changeset().all("space", "repo");
assertEquals(BASE_URL + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo/changesets/", url);
}

View File

@@ -1,7 +1,6 @@
package sonia.scm.api.v2.resources;
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;
@@ -29,12 +28,13 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.when;
import static sonia.scm.api.v2.resources.DispatcherMock.createDispatcher;
@RunWith(MockitoJUnitRunner.Silent.class)
public class SourceRootResourceTest {
private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
private Dispatcher dispatcher;
private final URI baseUri = URI.create("/");
private final ResourceLinks resourceLinks = ResourceLinksMock.createMock(baseUri);
@@ -72,10 +72,10 @@ public class SourceRootResourceTest {
null,
MockProvider.of(sourceRootResource),
null,
null,
null)),
null);
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
dispatcher = createDispatcher(repositoryRootResource);
}
@Test
@@ -88,8 +88,6 @@ public class SourceRootResourceTest {
dispatcher.invoke(request, response);
assertThat(response.getStatus()).isEqualTo(200);
assertThat(response.getContentAsString()).contains("\"revision\":\"revision\"");
assertThat(response.getContentAsString()).contains("\"tag\":\"tag\"");
assertThat(response.getContentAsString()).contains("\"branch\":\"branch\"");
assertThat(response.getContentAsString()).contains("\"files\":");
}
@@ -106,9 +104,7 @@ public class SourceRootResourceTest {
@Test
public void shouldGetResultForSingleFile() throws URISyntaxException, IOException, RevisionNotFoundException {
BrowserResult browserResult = new BrowserResult();
browserResult.setBranch("abc");
browserResult.setRevision("revision");
browserResult.setTag("tag");
FileObject fileObject = new FileObject();
fileObject.setName("File Object!");

View File

@@ -0,0 +1,199 @@
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.NamespaceAndName;
import sonia.scm.repository.Repository;
import sonia.scm.repository.Tag;
import sonia.scm.repository.Tags;
import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.repository.api.TagsCommandBuilder;
import sonia.scm.web.VndMediaType;
import java.net.URI;
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@Slf4j
@RunWith(MockitoJUnitRunner.Silent.class)
public class TagRootResourceTest {
public static final String TAG_PATH = "space/repo/tags/";
public static final String TAG_URL = "/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + TAG_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 repositoryService;
@Mock
private TagsCommandBuilder tagsCommandBuilder;
private TagCollectionToDtoMapper tagCollectionToDtoMapper;
@InjectMocks
private TagToTagDtoMapperImpl tagToTagDtoMapper;
private TagRootResource tagRootResource;
private final Subject subject = mock(Subject.class);
private final ThreadState subjectThreadState = new SubjectThreadState(subject);
@Before
public void prepareEnvironment() throws Exception {
tagCollectionToDtoMapper = new TagCollectionToDtoMapper(resourceLinks, tagToTagDtoMapper);
tagRootResource = new TagRootResource(serviceFactory, tagCollectionToDtoMapper, tagToTagDtoMapper);
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider
.of(new RepositoryResource(null, null, null, MockProvider.of(tagRootResource), null,
null, null, null, null, null)), null);
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
when(serviceFactory.create(new NamespaceAndName("space", "repo"))).thenReturn(repositoryService);
when(serviceFactory.create(any(Repository.class))).thenReturn(repositoryService);
when(repositoryService.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo"));
dispatcher.getProviderFactory().registerProvider(NotFoundExceptionMapper.class);
dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class);
when(repositoryService.getTagsCommand()).thenReturn(tagsCommandBuilder);
subjectThreadState.bind();
ThreadContext.bind(subject);
when(subject.isPermitted(any(String.class))).thenReturn(true);
}
@After
public void cleanupContext() {
ThreadContext.unbindSubject();
}
@Test
public void shouldGet404OnMissingTag() throws Exception {
Tags tags = new Tags();
tags.setTags(Lists.emptyList());
when(tagsCommandBuilder.getTags()).thenReturn(tags);
MockHttpRequest request = MockHttpRequest
.get(TAG_URL + "not_existing_tag")
.accept(VndMediaType.TAG);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(404, response.getStatus());
}
@Test
public void shouldGetEmptyTagListOnMissingTags() throws Exception {
Tags tags = new Tags();
tags.setTags(Lists.emptyList());
when(tagsCommandBuilder.getTags()).thenReturn(tags);
MockHttpRequest request = MockHttpRequest
.get(TAG_URL)
.accept(VndMediaType.TAG_COLLECTION);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(200, response.getStatus());
assertThat(response).isNotNull();
assertThat(response.getContentAsString())
.isNotBlank()
.contains("_links");
}
@Test
public void shouldGet500OnTagCommandError() throws Exception {
when(tagsCommandBuilder.getTags()).thenReturn(null);
MockHttpRequest request = MockHttpRequest
.get(TAG_URL + "not_existing_tag")
.accept(VndMediaType.TAG);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(500, response.getStatus());
request = MockHttpRequest
.get(TAG_URL)
.accept(VndMediaType.TAG_COLLECTION);
response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(500, response.getStatus());
}
@Test
public void shouldGetTags() throws Exception {
Tags tags = new Tags();
String tag1 = "v1.0";
String revision1 = "revision_1234";
String tag2 = "v2.0";
String revision2 = "revision_12345";
tags.setTags(Lists.newArrayList(new Tag(tag1, revision1), new Tag(tag2, revision2)));
when(tagsCommandBuilder.getTags()).thenReturn(tags);
MockHttpRequest request = MockHttpRequest
.get(TAG_URL)
.accept(VndMediaType.TAG_COLLECTION);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(200, response.getStatus());
log.info("the content: ", response.getContentAsString());
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", tag1)));
assertTrue(response.getContentAsString().contains(String.format("\"revision\":\"%s\"", revision1)));
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", tag2)));
assertTrue(response.getContentAsString().contains(String.format("\"revision\":\"%s\"", revision2)));
}
@Test
public void shouldGetTag() throws Exception {
Tags tags = new Tags();
String tag1 = "v1.0";
String revision1 = "revision_1234";
String tag2 = "v2.0";
String revision2 = "revision_12345";
tags.setTags(Lists.newArrayList(new Tag(tag1, revision1), new Tag(tag2, revision2)));
when(tagsCommandBuilder.getTags()).thenReturn(tags);
MockHttpRequest request = MockHttpRequest
.get(TAG_URL + tag1)
.accept(VndMediaType.TAG);
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(200, response.getStatus());
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", tag1)));
assertTrue(response.getContentAsString().contains(String.format("\"revision\":\"%s\"", revision1)));
request = MockHttpRequest
.get(TAG_URL + tag2)
.accept(VndMediaType.TAG);
response = new MockHttpResponse();
dispatcher.invoke(request, response);
assertEquals(200, response.getStatus());
log.info("the content: ", response.getContentAsString());
assertTrue(response.getContentAsString().contains(String.format("\"name\":\"%s\"", tag2)));
assertTrue(response.getContentAsString().contains(String.format("\"revision\":\"%s\"", revision2)));
}
}