#8630 implement the get changeset endpoint

This commit is contained in:
Mohamed Karray
2018-08-30 12:11:24 +02:00
parent c6203082e3
commit 2bd3fb5a4f
5 changed files with 335 additions and 38 deletions

View File

@@ -3,34 +3,44 @@ package sonia.scm.api.v2.resources;
import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseCode;
import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.StatusCodes;
import com.webcohesion.enunciate.metadata.rs.TypeHint; import com.webcohesion.enunciate.metadata.rs.TypeHint;
import sonia.scm.PageResult;
import sonia.scm.repository.Branches; import sonia.scm.repository.Branches;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryException;
import sonia.scm.repository.RepositoryNotFoundException; import sonia.scm.repository.RepositoryNotFoundException;
import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.repository.api.CommandNotSupportedException; import sonia.scm.repository.api.CommandNotSupportedException;
import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
import javax.inject.Inject; import javax.inject.Inject;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET; import javax.ws.rs.GET;
import javax.ws.rs.Path; import javax.ws.rs.Path;
import javax.ws.rs.PathParam; import javax.ws.rs.PathParam;
import javax.ws.rs.Produces; import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Response; import javax.ws.rs.core.Response;
import java.io.IOException; import java.io.IOException;
public class BranchRootResource { public class BranchRootResource {
private final RepositoryServiceFactory servicefactory; private final RepositoryServiceFactory serviceFactory;
private final BranchToBranchDtoMapper branchToDtoMapper; private final BranchToBranchDtoMapper branchToDtoMapper;
private final BranchCollectionToDtoMapper branchCollectionToDtoMapper; private final BranchCollectionToDtoMapper branchCollectionToDtoMapper;
private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
@Inject @Inject
public BranchRootResource(RepositoryServiceFactory servicefactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper) { public BranchRootResource(RepositoryServiceFactory serviceFactory, BranchToBranchDtoMapper branchToDtoMapper, BranchCollectionToDtoMapper branchCollectionToDtoMapper, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) {
this.servicefactory = servicefactory; this.serviceFactory = serviceFactory;
this.branchToDtoMapper = branchToDtoMapper; this.branchToDtoMapper = branchToDtoMapper;
this.branchCollectionToDtoMapper = branchCollectionToDtoMapper; this.branchCollectionToDtoMapper = branchCollectionToDtoMapper;
this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper;
} }
/** /**
@@ -56,7 +66,7 @@ public class BranchRootResource {
@ResponseCode(code = 500, condition = "internal server error") @ResponseCode(code = 500, condition = "internal server error")
}) })
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("branch") String branchName) throws IOException, RepositoryException { public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("branch") String branchName) throws IOException, RepositoryException {
try (RepositoryService repositoryService = servicefactory.create(new NamespaceAndName(namespace, name))) { try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
Branches branches = repositoryService.getBranchesCommand().getBranches(); Branches branches = repositoryService.getBranchesCommand().getBranches();
return branches.getBranches() return branches.getBranches()
.stream() .stream()
@@ -75,8 +85,34 @@ public class BranchRootResource {
@Path("{branch}/changesets/") @Path("{branch}/changesets/")
@GET @GET
public Response history(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("branch") String branchName) { @StatusCodes({
throw new UnsupportedOperationException(); @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 history(@PathParam("namespace") String namespace,
@PathParam("name") String name,
@PathParam("branch") String branchName,
@DefaultValue("0") @QueryParam("page") int page,
@DefaultValue("10") @QueryParam("pageSize") int pageSize) throws Exception {
RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name));
Repository repository = repositoryService.getRepository();
RepositoryPermissions.read(repository).check();
ChangesetPagingResult changesets = repositoryService.getLogCommand()
.setPagingStart(page)
.setPagingLimit(pageSize)
.setBranch(branchName)
.getChangesets();
if (changesets != null && changesets.getChangesets() != null) {
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build();
} else {
return Response.ok().build();
}
} }
/** /**
@@ -101,7 +137,7 @@ public class BranchRootResource {
@ResponseCode(code = 500, condition = "internal server error") @ResponseCode(code = 500, condition = "internal server error")
}) })
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name) throws IOException, RepositoryException { public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name) throws IOException, RepositoryException {
try (RepositoryService repositoryService = servicefactory.create(new NamespaceAndName(namespace, name))) { try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) {
Branches branches = repositoryService.getBranchesCommand().getBranches(); Branches branches = repositoryService.getBranchesCommand().getBranches();
return Response.ok(branchCollectionToDtoMapper.map(namespace, name, branches.getBranches())).build(); return Response.ok(branchCollectionToDtoMapper.map(namespace, name, branches.getBranches())).build();
} catch (CommandNotSupportedException ex) { } catch (CommandNotSupportedException ex) {

View File

@@ -10,7 +10,7 @@ import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.NamespaceAndName; import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.Repository; import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryException;
import sonia.scm.repository.RepositoryNotFoundException; import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.repository.api.RepositoryServiceFactory;
import sonia.scm.web.VndMediaType; import sonia.scm.web.VndMediaType;
@@ -33,10 +33,13 @@ public class ChangesetRootResource {
private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper; private final ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
private final ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper;
@Inject @Inject
public ChangesetRootResource(RepositoryServiceFactory serviceFactory, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper) { public ChangesetRootResource(RepositoryServiceFactory serviceFactory, ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper, ChangesetToChangesetDtoMapper changesetToChangesetDtoMapper) {
this.serviceFactory = serviceFactory; this.serviceFactory = serviceFactory;
this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper; this.changesetCollectionToDtoMapper = changesetCollectionToDtoMapper;
this.changesetToChangesetDtoMapper = changesetToChangesetDtoMapper;
} }
@GET @GET
@@ -45,40 +48,52 @@ public class ChangesetRootResource {
@ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 200, condition = "success"),
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"), @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 = 403, condition = "not authorized, the current user has no privileges to read the changeset"),
@ResponseCode(code = 404, condition = "not found, no changeset with the specified name available in the repository"), @ResponseCode(code = 404, condition = "not found, no changesets available in the repository"),
@ResponseCode(code = 500, condition = "internal server error") @ResponseCode(code = 500, condition = "internal server error")
}) })
@Produces(VndMediaType.CHANGESET_COLLECTION) @Produces(VndMediaType.CHANGESET_COLLECTION)
@TypeHint(CollectionDto.class) @TypeHint(CollectionDto.class)
public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @DefaultValue("0") @QueryParam("page") int page, public Response getAll(@PathParam("namespace") String namespace, @PathParam("name") String name, @DefaultValue("0") @QueryParam("page") int page,
@DefaultValue("10") @QueryParam("pageSize") int pageSize) { @DefaultValue("10") @QueryParam("pageSize") int pageSize) throws IOException, RepositoryException {
try (RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name))) { RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name));
ChangesetPagingResult changesets; Repository repository = repositoryService.getRepository();
Repository repository = repositoryService.getRepository(); RepositoryPermissions.read(repository).check();
changesets = repositoryService.getLogCommand() ChangesetPagingResult changesets = repositoryService.getLogCommand()
.setPagingStart(page) .setPagingStart(page)
.setPagingLimit(pageSize) .setPagingLimit(pageSize)
.getChangesets(); .getChangesets();
if (changesets != null) { if (changesets != null && changesets.getChangesets() != null) {
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal()); PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build(); return Response.ok(changesetCollectionToDtoMapper.map(page, pageSize, pageResult, repository)).build();
} else { } else {
return Response.ok().build(); return Response.ok().build();
}
} catch (RepositoryNotFoundException e) {
log.debug("Not found in repository {}/{}", namespace, name, e);
return Response.status(Response.Status.NOT_FOUND).build();
} catch (RepositoryException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
return Response.ok().build();
} }
@GET @GET
@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 changeset with the specified id is available in the repository"),
@ResponseCode(code = 500, condition = "internal server error")
})
@Produces(VndMediaType.CHANGESET)
@TypeHint(ChangesetDto.class)
@Path("{id}") @Path("{id}")
public Response get(@PathParam("id") String id) { public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name, @PathParam("id") String id) throws RepositoryException, IOException {
throw new UnsupportedOperationException(); RepositoryService repositoryService = serviceFactory.create(new NamespaceAndName(namespace, name));
Repository repository = repositoryService.getRepository();
RepositoryPermissions.read(repository).check();
ChangesetPagingResult changesets = repositoryService.getLogCommand()
.setStartChangeset(id)
.setEndChangeset(id)
.getChangesets();
if (changesets != null && changesets.getChangesets() != null && changesets.getChangesets().size() == 1) {
PageResult<Changeset> pageResult = new PageResult<>(changesets.getChangesets(), changesets.getTotal());
return Response.ok(changesetToChangesetDtoMapper.map(changesets.getChangesets().get(0), repository)).build();
} else {
return Response.status(Response.Status.NOT_FOUND).build();
}
} }
} }

View File

@@ -1,5 +1,11 @@
package sonia.scm.api.v2.resources; 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.core.Dispatcher;
import org.jboss.resteasy.mock.MockDispatcherFactory; import org.jboss.resteasy.mock.MockDispatcherFactory;
import org.jboss.resteasy.mock.MockHttpRequest; import org.jboss.resteasy.mock.MockHttpRequest;
@@ -12,20 +18,35 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner; import org.mockito.junit.MockitoJUnitRunner;
import sonia.scm.repository.Branch; import sonia.scm.repository.Branch;
import sonia.scm.repository.Branches; import sonia.scm.repository.Branches;
import sonia.scm.repository.Changeset;
import sonia.scm.repository.ChangesetPagingResult;
import sonia.scm.repository.NamespaceAndName; 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.BranchesCommandBuilder;
import sonia.scm.repository.api.LogCommandBuilder;
import sonia.scm.repository.api.RepositoryService; import sonia.scm.repository.api.RepositoryService;
import sonia.scm.repository.api.RepositoryServiceFactory; import sonia.scm.repository.api.RepositoryServiceFactory;
import java.net.URI; 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.assertEquals;
import static org.junit.Assert.assertTrue; 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; import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.Silent.class) @RunWith(MockitoJUnitRunner.Silent.class)
@Slf4j
public class BranchRootResourceTest { 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 Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
private final URI baseUri = URI.create("/"); private final URI baseUri = URI.create("/");
@@ -38,25 +59,57 @@ public class BranchRootResourceTest {
@Mock @Mock
private BranchesCommandBuilder branchesCommandBuilder; private BranchesCommandBuilder branchesCommandBuilder;
@Mock
private LogCommandBuilder logCommandBuilder;
@InjectMocks @InjectMocks
private BranchToBranchDtoMapperImpl branchToDtoMapper; 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 @Before
public void prepareEnvironment() throws Exception { public void prepareEnvironment() throws Exception {
changesetCollectionToDtoMapper = new ChangesetCollectionToDtoMapper(changesetToChangesetDtoMapper, resourceLinks);
BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks); BranchCollectionToDtoMapper branchCollectionToDtoMapper = new BranchCollectionToDtoMapper(branchToDtoMapper, resourceLinks);
BranchRootResource branchRootResource = new BranchRootResource(serviceFactory, branchToDtoMapper, branchCollectionToDtoMapper); 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);
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(service.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo"));
when(service.getBranchesCommand()).thenReturn(branchesCommandBuilder); when(service.getBranchesCommand()).thenReturn(branchesCommandBuilder);
when(service.getLogCommand()).thenReturn(logCommandBuilder);
subjectThreadState.bind();
ThreadContext.bind(subject);
when(subject.isPermitted(any(String.class))).thenReturn(true);
} }
@Test @Test
public void shouldHandleMissingBranch() throws Exception { public void shouldHandleMissingBranch() throws Exception {
when(branchesCommandBuilder.getBranches()).thenReturn(new Branches()); 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(); MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response); dispatcher.invoke(request, response);
@@ -68,13 +121,40 @@ public class BranchRootResourceTest {
public void shouldFindExistingBranch() throws Exception { public void shouldFindExistingBranch() throws Exception {
when(branchesCommandBuilder.getBranches()).thenReturn(new Branches(new Branch("master", "revision"))); 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(); MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response); dispatcher.invoke(request, response);
assertEquals(200, response.getStatus()); assertEquals(200, response.getStatus());
System.out.println(response.getContentAsString()); log.info("Response :{}", response.getContentAsString());
assertTrue(response.getContentAsString().contains("\"revision\":\"revision\"")); 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

@@ -0,0 +1,165 @@
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.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 service;
@Mock
private LogCommandBuilder logCommandBuilder;
private ChangesetCollectionToDtoMapper changesetCollectionToDtoMapper;
@Mock
private BranchCollectionToDtoMapper branchCollectionToDtoMapper;
@Mock
private ChangesetToParentDtoMapperImpl changesetToParentDtoMapper;
@Mock
private TagCollectionToDtoMapper tagCollectionToDtoMapper;
@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(service);
when(serviceFactory.create(any(Repository.class))).thenReturn(service);
when(service.getRepository()).thenReturn(new Repository("repoId", "git", "space", "repo"));
dispatcher.getProviderFactory().registerProvider(RepositoryNotFoundExceptionMapper.class);
dispatcher.getProviderFactory().registerProvider(AuthorizationExceptionMapper.class);
when(service.getLogCommand()).thenReturn(logCommandBuilder);
subjectThreadState.bind();
ThreadContext.bind(subject);
when(subject.isPermitted(any(String.class))).thenReturn(true);
}
@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

@@ -26,6 +26,7 @@ public class ResourceLinksMock {
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));
when(resourceLinks.branch()).thenReturn(new ResourceLinks.BranchLinks(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.repositoryType()).thenReturn(new ResourceLinks.RepositoryTypeLinks(uriInfo));
when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo)); when(resourceLinks.repositoryTypeCollection()).thenReturn(new ResourceLinks.RepositoryTypeCollectionLinks(uriInfo));