mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 16:35:45 +01:00
Support reading object by other identifiers than id
Therefore split adapter class for single entity and collection handling.
This commit is contained in:
@@ -38,13 +38,11 @@ package sonia.scm.repository;
|
|||||||
import sonia.scm.Type;
|
import sonia.scm.Type;
|
||||||
import sonia.scm.TypeManager;
|
import sonia.scm.TypeManager;
|
||||||
|
|
||||||
//~--- JDK imports ------------------------------------------------------------
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
//~--- JDK imports ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The central class for managing {@link Repository} objects.
|
* The central class for managing {@link Repository} objects.
|
||||||
@@ -149,4 +147,12 @@ public interface RepositoryManager
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public RepositoryHandler getHandler(String type);
|
public RepositoryHandler getHandler(String type);
|
||||||
|
|
||||||
|
default Repository getByNamespace(String namespace, String name) {
|
||||||
|
return getAll()
|
||||||
|
.stream()
|
||||||
|
.filter(r -> r.getName().equals(name) && r.getNamespace().equals(namespace))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,43 +26,14 @@ import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
|
|||||||
* @param <EXCEPTION> The exception type for the model object, eg. {@link sonia.scm.user.UserException}.
|
* @param <EXCEPTION> The exception type for the model object, eg. {@link sonia.scm.user.UserException}.
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("squid:S00119") // "MODEL_OBJECT" is much more meaningful than "M", right?
|
@SuppressWarnings("squid:S00119") // "MODEL_OBJECT" is much more meaningful than "M", right?
|
||||||
class ResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
class CollectionResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||||
DTO extends HalRepresentation,
|
DTO extends HalRepresentation,
|
||||||
EXCEPTION extends Exception> extends AbstractManagerResource<MODEL_OBJECT, EXCEPTION> {
|
EXCEPTION extends Exception> extends AbstractManagerResource<MODEL_OBJECT, EXCEPTION> {
|
||||||
|
|
||||||
ResourceManagerAdapter(Manager<MODEL_OBJECT, EXCEPTION> manager) {
|
CollectionResourceManagerAdapter(Manager<MODEL_OBJECT, EXCEPTION> manager) {
|
||||||
super(manager);
|
super(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Reads the model object for the given id, transforms it to a dto and returns a corresponding http response.
|
|
||||||
* This handles all corner cases, eg. no matching object for the id or missing privileges.
|
|
||||||
*/
|
|
||||||
Response get(String id, Function<MODEL_OBJECT, DTO> mapToDto) {
|
|
||||||
MODEL_OBJECT modelObject = manager.get(id);
|
|
||||||
if (modelObject == null) {
|
|
||||||
return Response.status(Response.Status.NOT_FOUND).build();
|
|
||||||
}
|
|
||||||
DTO dto = mapToDto.apply(modelObject);
|
|
||||||
return Response.ok(dto).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update the model object for the given id according to the given function and returns a corresponding http response.
|
|
||||||
* This handles all corner cases, eg. no matching object for the id or missing privileges.
|
|
||||||
*/
|
|
||||||
public Response update(String id, Function<MODEL_OBJECT, MODEL_OBJECT> applyChanges) {
|
|
||||||
MODEL_OBJECT existingModelObject = manager.get(id);
|
|
||||||
if (existingModelObject == null) {
|
|
||||||
return Response.status(Response.Status.NOT_FOUND).build();
|
|
||||||
}
|
|
||||||
MODEL_OBJECT changedModelObject = applyChanges.apply(existingModelObject);
|
|
||||||
if (!id.equals(changedModelObject.getId())) {
|
|
||||||
return Response.status(BAD_REQUEST).entity("illegal change of id").build();
|
|
||||||
}
|
|
||||||
return update(id, changedModelObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads all model objects in a paged way, maps them using the given function and returns a corresponding http response.
|
* Reads all model objects in a paged way, maps them using the given function and returns a corresponding http response.
|
||||||
* This handles all corner cases, eg. missing privileges.
|
* This handles all corner cases, eg. missing privileges.
|
||||||
@@ -1,13 +1,23 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
import com.webcohesion.enunciate.metadata.rs.*;
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
import sonia.scm.group.Group;
|
import sonia.scm.group.Group;
|
||||||
import sonia.scm.group.GroupException;
|
import sonia.scm.group.GroupException;
|
||||||
import sonia.scm.group.GroupManager;
|
import sonia.scm.group.GroupManager;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.ws.rs.*;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -19,14 +29,14 @@ public class GroupCollectionResource {
|
|||||||
private final GroupCollectionToDtoMapper groupCollectionToDtoMapper;
|
private final GroupCollectionToDtoMapper groupCollectionToDtoMapper;
|
||||||
private final ResourceLinks resourceLinks;
|
private final ResourceLinks resourceLinks;
|
||||||
|
|
||||||
private final ResourceManagerAdapter<Group, GroupDto, GroupException> adapter;
|
private final IdResourceManagerAdapter<Group, GroupDto, GroupException> adapter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GroupCollectionResource(GroupManager manager, GroupDtoToGroupMapper dtoToGroupMapper, GroupCollectionToDtoMapper groupCollectionToDtoMapper, ResourceLinks resourceLinks) {
|
public GroupCollectionResource(GroupManager manager, GroupDtoToGroupMapper dtoToGroupMapper, GroupCollectionToDtoMapper groupCollectionToDtoMapper, ResourceLinks resourceLinks) {
|
||||||
this.dtoToGroupMapper = dtoToGroupMapper;
|
this.dtoToGroupMapper = dtoToGroupMapper;
|
||||||
this.groupCollectionToDtoMapper = groupCollectionToDtoMapper;
|
this.groupCollectionToDtoMapper = groupCollectionToDtoMapper;
|
||||||
this.resourceLinks = resourceLinks;
|
this.resourceLinks = resourceLinks;
|
||||||
this.adapter = new ResourceManagerAdapter<>(manager);
|
this.adapter = new IdResourceManagerAdapter<>(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ public class GroupResource {
|
|||||||
|
|
||||||
private final GroupToGroupDtoMapper groupToGroupDtoMapper;
|
private final GroupToGroupDtoMapper groupToGroupDtoMapper;
|
||||||
private final GroupDtoToGroupMapper dtoToGroupMapper;
|
private final GroupDtoToGroupMapper dtoToGroupMapper;
|
||||||
private final ResourceManagerAdapter<Group, GroupDto, GroupException> adapter;
|
private final IdResourceManagerAdapter<Group, GroupDto, GroupException> adapter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public GroupResource(GroupManager manager, GroupToGroupDtoMapper groupToGroupDtoMapper,
|
public GroupResource(GroupManager manager, GroupToGroupDtoMapper groupToGroupDtoMapper,
|
||||||
GroupDtoToGroupMapper groupDtoToGroupMapper) {
|
GroupDtoToGroupMapper groupDtoToGroupMapper) {
|
||||||
this.groupToGroupDtoMapper = groupToGroupDtoMapper;
|
this.groupToGroupDtoMapper = groupToGroupDtoMapper;
|
||||||
this.dtoToGroupMapper = groupDtoToGroupMapper;
|
this.dtoToGroupMapper = groupDtoToGroupMapper;
|
||||||
this.adapter = new ResourceManagerAdapter<>(manager);
|
this.adapter = new IdResourceManagerAdapter<>(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import de.otto.edison.hal.HalRepresentation;
|
||||||
|
import sonia.scm.Manager;
|
||||||
|
import sonia.scm.ModelObject;
|
||||||
|
import sonia.scm.PageResult;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Facade for {@link SingleResourceManagerAdapter} and {@link CollectionResourceManagerAdapter}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("squid:S00119") // "MODEL_OBJECT" is much more meaningful than "M", right?
|
||||||
|
class IdResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||||
|
DTO extends HalRepresentation,
|
||||||
|
EXCEPTION extends Exception> {
|
||||||
|
|
||||||
|
private final Manager<MODEL_OBJECT, EXCEPTION> manager;
|
||||||
|
|
||||||
|
private final SingleResourceManagerAdapter<MODEL_OBJECT, DTO, EXCEPTION> singleAdapter;
|
||||||
|
private final CollectionResourceManagerAdapter<MODEL_OBJECT, DTO, EXCEPTION> collectionAdapter;
|
||||||
|
|
||||||
|
IdResourceManagerAdapter(Manager<MODEL_OBJECT, EXCEPTION> manager) {
|
||||||
|
this.manager = manager;
|
||||||
|
singleAdapter = new SingleResourceManagerAdapter<>(manager);
|
||||||
|
collectionAdapter = new CollectionResourceManagerAdapter<>(manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
Response get(String id, Function<MODEL_OBJECT, DTO> mapToDto) {
|
||||||
|
return singleAdapter.get(() -> manager.get(id), mapToDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response update(String id, Function<MODEL_OBJECT, MODEL_OBJECT> applyChanges) {
|
||||||
|
return singleAdapter.update(() -> manager.get(id), applyChanges);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response getAll(int page, int pageSize, String sortBy, boolean desc, Function<PageResult<MODEL_OBJECT>, CollectionDto> mapToDto) {
|
||||||
|
return collectionAdapter.getAll(page, pageSize, sortBy, desc, mapToDto);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response create(DTO dto, Supplier<MODEL_OBJECT> modelObjectSupplier, Function<MODEL_OBJECT, String> uriCreator) throws IOException, EXCEPTION {
|
||||||
|
return collectionAdapter.create(dto, modelObjectSupplier, uriCreator);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Response delete(String id) {
|
||||||
|
return singleAdapter.delete(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,12 +19,14 @@ public class RepositoryResource {
|
|||||||
|
|
||||||
private final RepositoryToRepositoryDtoMapper repositoryToDtoMapper;
|
private final RepositoryToRepositoryDtoMapper repositoryToDtoMapper;
|
||||||
|
|
||||||
private final ResourceManagerAdapter<Repository, RepositoryDto, RepositoryException> adapter;
|
private final RepositoryManager manager;
|
||||||
|
private final SingleResourceManagerAdapter<Repository, RepositoryDto, RepositoryException> adapter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public RepositoryResource(RepositoryToRepositoryDtoMapper repositoryToDtoMapper, RepositoryManager manager) {
|
public RepositoryResource(RepositoryToRepositoryDtoMapper repositoryToDtoMapper, RepositoryManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
this.repositoryToDtoMapper = repositoryToDtoMapper;
|
this.repositoryToDtoMapper = repositoryToDtoMapper;
|
||||||
this.adapter = new ResourceManagerAdapter<>(manager);
|
this.adapter = new SingleResourceManagerAdapter<>(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
@GET
|
@GET
|
||||||
@@ -39,6 +41,6 @@ public class RepositoryResource {
|
|||||||
@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) {
|
public Response get(@PathParam("namespace") String namespace, @PathParam("name") String name) {
|
||||||
return adapter.get("31QwjAKOK2", repositoryToDtoMapper::map);
|
return adapter.get(() -> manager.getByNamespace(namespace, name), repositoryToDtoMapper::map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
|
import de.otto.edison.hal.HalRepresentation;
|
||||||
|
import sonia.scm.Manager;
|
||||||
|
import sonia.scm.ModelObject;
|
||||||
|
import sonia.scm.api.rest.resources.AbstractManagerResource;
|
||||||
|
|
||||||
|
import javax.ws.rs.core.GenericEntity;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static javax.ws.rs.core.Response.Status.BAD_REQUEST;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adapter from resource http endpoints to managers.
|
||||||
|
*
|
||||||
|
* Provides common CRUD operations and DTO to Model Object mapping to keep Resources more DRY.
|
||||||
|
*
|
||||||
|
* @param <MODEL_OBJECT> The type of the model object, eg. {@link sonia.scm.user.User}.
|
||||||
|
* @param <DTO> The corresponding transport object, eg. {@link UserDto}.
|
||||||
|
* @param <EXCEPTION> The exception type for the model object, eg. {@link sonia.scm.user.UserException}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("squid:S00119") // "MODEL_OBJECT" is much more meaningful than "M", right?
|
||||||
|
class SingleResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||||
|
DTO extends HalRepresentation,
|
||||||
|
EXCEPTION extends Exception> extends AbstractManagerResource<MODEL_OBJECT, EXCEPTION> {
|
||||||
|
|
||||||
|
SingleResourceManagerAdapter(Manager<MODEL_OBJECT, EXCEPTION> manager) {
|
||||||
|
super(manager);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the model object for the given id, transforms it to a dto and returns a corresponding http response.
|
||||||
|
* This handles all corner cases, eg. no matching object for the id or missing privileges.
|
||||||
|
*/
|
||||||
|
Response get(Supplier<MODEL_OBJECT> reader, Function<MODEL_OBJECT, DTO> mapToDto) {
|
||||||
|
MODEL_OBJECT modelObject = reader.get();
|
||||||
|
if (modelObject == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
DTO dto = mapToDto.apply(modelObject);
|
||||||
|
return Response.ok(dto).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the model object for the given id according to the given function and returns a corresponding http response.
|
||||||
|
* This handles all corner cases, eg. no matching object for the id or missing privileges.
|
||||||
|
*/
|
||||||
|
public Response update(Supplier<MODEL_OBJECT> reader, Function<MODEL_OBJECT, MODEL_OBJECT> applyChanges) {
|
||||||
|
MODEL_OBJECT existingModelObject = reader.get();
|
||||||
|
if (existingModelObject == null) {
|
||||||
|
return Response.status(Response.Status.NOT_FOUND).build();
|
||||||
|
}
|
||||||
|
MODEL_OBJECT changedModelObject = applyChanges.apply(existingModelObject);
|
||||||
|
if (!getId(existingModelObject).equals(getId(changedModelObject))) {
|
||||||
|
return Response.status(BAD_REQUEST).entity("illegal change of id").build();
|
||||||
|
}
|
||||||
|
return update(getId(existingModelObject), changedModelObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected GenericEntity<Collection<MODEL_OBJECT>> createGenericEntity(Collection<MODEL_OBJECT> modelObjects) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getId(MODEL_OBJECT item) {
|
||||||
|
return item.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getPathPart() {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,23 @@
|
|||||||
package sonia.scm.api.v2.resources;
|
package sonia.scm.api.v2.resources;
|
||||||
|
|
||||||
import com.webcohesion.enunciate.metadata.rs.*;
|
import com.webcohesion.enunciate.metadata.rs.ResponseCode;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseHeader;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.ResponseHeaders;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.StatusCodes;
|
||||||
|
import com.webcohesion.enunciate.metadata.rs.TypeHint;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
import sonia.scm.user.UserException;
|
import sonia.scm.user.UserException;
|
||||||
import sonia.scm.user.UserManager;
|
import sonia.scm.user.UserManager;
|
||||||
import sonia.scm.web.VndMediaType;
|
import sonia.scm.web.VndMediaType;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.ws.rs.*;
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.DefaultValue;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -18,14 +28,14 @@ public class UserCollectionResource {
|
|||||||
private final UserCollectionToDtoMapper userCollectionToDtoMapper;
|
private final UserCollectionToDtoMapper userCollectionToDtoMapper;
|
||||||
private final ResourceLinks resourceLinks;
|
private final ResourceLinks resourceLinks;
|
||||||
|
|
||||||
private final ResourceManagerAdapter<User, UserDto, UserException> adapter;
|
private final IdResourceManagerAdapter<User, UserDto, UserException> adapter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public UserCollectionResource(UserManager manager, UserDtoToUserMapper dtoToUserMapper,
|
public UserCollectionResource(UserManager manager, UserDtoToUserMapper dtoToUserMapper,
|
||||||
UserCollectionToDtoMapper userCollectionToDtoMapper, ResourceLinks resourceLinks) {
|
UserCollectionToDtoMapper userCollectionToDtoMapper, ResourceLinks resourceLinks) {
|
||||||
this.dtoToUserMapper = dtoToUserMapper;
|
this.dtoToUserMapper = dtoToUserMapper;
|
||||||
this.userCollectionToDtoMapper = userCollectionToDtoMapper;
|
this.userCollectionToDtoMapper = userCollectionToDtoMapper;
|
||||||
this.adapter = new ResourceManagerAdapter<>(manager);
|
this.adapter = new IdResourceManagerAdapter<>(manager);
|
||||||
this.resourceLinks = resourceLinks;
|
this.resourceLinks = resourceLinks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ public class UserResource {
|
|||||||
private final UserDtoToUserMapper dtoToUserMapper;
|
private final UserDtoToUserMapper dtoToUserMapper;
|
||||||
private final UserToUserDtoMapper userToDtoMapper;
|
private final UserToUserDtoMapper userToDtoMapper;
|
||||||
|
|
||||||
private final ResourceManagerAdapter<User, UserDto, UserException> adapter;
|
private final IdResourceManagerAdapter<User, UserDto, UserException> adapter;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public UserResource(UserDtoToUserMapper dtoToUserMapper, UserToUserDtoMapper userToDtoMapper, UserManager manager) {
|
public UserResource(UserDtoToUserMapper dtoToUserMapper, UserToUserDtoMapper userToDtoMapper, UserManager manager) {
|
||||||
this.dtoToUserMapper = dtoToUserMapper;
|
this.dtoToUserMapper = dtoToUserMapper;
|
||||||
this.userToDtoMapper = userToDtoMapper;
|
this.userToDtoMapper = userToDtoMapper;
|
||||||
this.adapter = new ResourceManagerAdapter<>(manager);
|
this.adapter = new IdResourceManagerAdapter<>(manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,77 @@
|
|||||||
|
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;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.mockito.Answers;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import sonia.scm.repository.Repository;
|
||||||
|
import sonia.scm.repository.RepositoryManager;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||||
|
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
import static org.mockito.MockitoAnnotations.initMocks;
|
||||||
|
|
||||||
|
public class RepositoryRootResourceTest {
|
||||||
|
|
||||||
|
private final Dispatcher dispatcher = MockDispatcherFactory.createDispatcher();
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private RepositoryManager repositoryManager;
|
||||||
|
@Mock(answer = Answers.RETURNS_DEEP_STUBS)
|
||||||
|
private ResourceLinks resourceLinks;
|
||||||
|
@InjectMocks
|
||||||
|
private RepositoryToRepositoryDtoMapperImpl repositoryToDtoMapper;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void prepareEnvironment() {
|
||||||
|
initMocks(this);
|
||||||
|
ResourceLinksMock.initMock(resourceLinks, URI.create("/"));
|
||||||
|
RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, repositoryManager);
|
||||||
|
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(repositoryResource));
|
||||||
|
dispatcher.getRegistry().addSingletonResource(repositoryRootResource);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFailForNotExistingRepository() throws URISyntaxException {
|
||||||
|
mockRepository("space", "repo");
|
||||||
|
|
||||||
|
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/other");
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
|
||||||
|
assertEquals(SC_NOT_FOUND, response.getStatus());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldFindExistingRepository() throws URISyntaxException {
|
||||||
|
mockRepository("space", "repo");
|
||||||
|
|
||||||
|
MockHttpRequest request = MockHttpRequest.get("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo");
|
||||||
|
MockHttpResponse response = new MockHttpResponse();
|
||||||
|
|
||||||
|
dispatcher.invoke(request, response);
|
||||||
|
|
||||||
|
assertEquals(SC_OK, response.getStatus());
|
||||||
|
assertTrue(response.getContentAsString().contains("\"name\":\"repo\""));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Repository mockRepository(String namespace, String name) {
|
||||||
|
Repository repository = new Repository();
|
||||||
|
repository.setNamespace(namespace);
|
||||||
|
repository.setName(name);
|
||||||
|
when(repositoryManager.getByNamespace(namespace, name)).thenReturn(repository);
|
||||||
|
return repository;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user