mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-12 16:35:45 +01:00
Implement update and delete for repository
This commit is contained in:
@@ -16,6 +16,7 @@ public class MapperModule extends AbstractModule {
|
||||
bind(GroupCollectionToDtoMapper.class);
|
||||
|
||||
bind(RepositoryToRepositoryDtoMapper.class).to(Mappers.getMapper(RepositoryToRepositoryDtoMapper.class).getClass());
|
||||
bind(RepositoryDtoToRepositoryMapper.class).to(Mappers.getMapper(RepositoryDtoToRepositoryMapper.class).getClass());
|
||||
|
||||
bind(UriInfoStore.class).in(ServletScopes.REQUEST);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package sonia.scm.api.v2.resources;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.Mapping;
|
||||
import sonia.scm.repository.Repository;
|
||||
|
||||
@Mapper
|
||||
public abstract class RepositoryDtoToRepositoryMapper {
|
||||
|
||||
@Mapping(target = "creationDate", ignore = true)
|
||||
@Mapping(target = "lastModified", ignore = true)
|
||||
@Mapping(target = "id", ignore = true)
|
||||
@Mapping(target = "publicReadable", ignore = true)
|
||||
@Mapping(target = "healthCheckFailures", ignore = true)
|
||||
@Mapping(target = "permissions", ignore = true)
|
||||
public abstract Repository map(RepositoryDto repositoryDto);
|
||||
|
||||
}
|
||||
@@ -21,6 +21,7 @@ import javax.ws.rs.core.Response;
|
||||
public class RepositoryResource {
|
||||
|
||||
private final RepositoryToRepositoryDtoMapper repositoryToDtoMapper;
|
||||
private final RepositoryDtoToRepositoryMapper dtoToRepositoryMapper;
|
||||
|
||||
private final RepositoryManager manager;
|
||||
private final SingleResourceManagerAdapter<Repository, RepositoryDto, RepositoryException> adapter;
|
||||
@@ -33,11 +34,12 @@ public class RepositoryResource {
|
||||
@Inject
|
||||
public RepositoryResource(
|
||||
RepositoryToRepositoryDtoMapper repositoryToDtoMapper,
|
||||
RepositoryManager manager,
|
||||
RepositoryDtoToRepositoryMapper dtoToRepositoryMapper, RepositoryManager manager,
|
||||
Provider<TagRootResource> tagRootResource,
|
||||
Provider<BranchRootResource> branchRootResource,
|
||||
Provider<ChangesetRootResource> changesetRootResource,
|
||||
Provider<SourceRootResource> sourceRootResource, Provider<PermissionRootResource> permissionRootResource) {
|
||||
this.dtoToRepositoryMapper = dtoToRepositoryMapper;
|
||||
this.manager = manager;
|
||||
this.repositoryToDtoMapper = repositoryToDtoMapper;
|
||||
this.adapter = new SingleResourceManagerAdapter<>(manager);
|
||||
@@ -65,14 +67,25 @@ public class RepositoryResource {
|
||||
|
||||
@DELETE
|
||||
@Path("")
|
||||
@StatusCodes({
|
||||
@ResponseCode(code = 204, condition = "delete success or nothing to delete"),
|
||||
@ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
|
||||
@ResponseCode(code = 403, condition = "not authorized, the current user does not have the \"repository\" privilege"),
|
||||
@ResponseCode(code = 500, condition = "internal server error")
|
||||
})
|
||||
@TypeHint(TypeHint.NO_CONTENT.class)
|
||||
public Response delete(@PathParam("namespace") String namespace, @PathParam("name") String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
return adapter.delete(() -> manager.getByNamespace(namespace, name));
|
||||
}
|
||||
|
||||
@PUT
|
||||
@Path("")
|
||||
public Response update(@PathParam("namespace") String namespace, @PathParam("name") String name) {
|
||||
throw new UnsupportedOperationException();
|
||||
public Response update(@PathParam("namespace") String namespace, @PathParam("name") String name, RepositoryDto repositoryDto) {
|
||||
return adapter.update(() -> manager.getByNamespace(namespace, name), existing -> {
|
||||
Repository repository = dtoToRepositoryMapper.map(repositoryDto);
|
||||
repository.setId(existing.getId());
|
||||
return repository;
|
||||
});
|
||||
}
|
||||
|
||||
@Path("tags/")
|
||||
|
||||
@@ -60,6 +60,11 @@ class SingleResourceManagerAdapter<MODEL_OBJECT extends ModelObject,
|
||||
return update(getId(existingModelObject), changedModelObject);
|
||||
}
|
||||
|
||||
public Response delete(Supplier<MODEL_OBJECT> reader) {
|
||||
MODEL_OBJECT existingModelObject = reader.get();
|
||||
return delete(existingModelObject.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GenericEntity<Collection<MODEL_OBJECT>> createGenericEntity(Collection<MODEL_OBJECT> modelObjects) {
|
||||
throw new UnsupportedOperationException();
|
||||
|
||||
@@ -2,6 +2,7 @@ package sonia.scm.api.v2.resources;
|
||||
|
||||
import com.github.sdorra.shiro.ShiroRule;
|
||||
import com.github.sdorra.shiro.SubjectAware;
|
||||
import com.google.common.io.Resources;
|
||||
import org.jboss.resteasy.core.Dispatcher;
|
||||
import org.jboss.resteasy.mock.MockDispatcherFactory;
|
||||
import org.jboss.resteasy.mock.MockHttpRequest;
|
||||
@@ -14,17 +15,23 @@ import org.mockito.Mock;
|
||||
import sonia.scm.PageResult;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.RepositoryManager;
|
||||
import sonia.scm.web.VndMediaType;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
|
||||
import static java.util.Collections.singletonList;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_NOT_FOUND;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_NO_CONTENT;
|
||||
import static javax.servlet.http.HttpServletResponse.SC_OK;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
import static org.mockito.MockitoAnnotations.initMocks;
|
||||
|
||||
@@ -48,11 +55,13 @@ public class RepositoryRootResourceTest {
|
||||
|
||||
@InjectMocks
|
||||
private RepositoryToRepositoryDtoMapperImpl repositoryToDtoMapper;
|
||||
@InjectMocks
|
||||
private RepositoryDtoToRepositoryMapperImpl dtoToRepositoryMapper;
|
||||
|
||||
@Before
|
||||
public void prepareEnvironment() {
|
||||
initMocks(this);
|
||||
RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, repositoryManager, null, null, null, null, null);
|
||||
RepositoryResource repositoryResource = new RepositoryResource(repositoryToDtoMapper, dtoToRepositoryMapper, repositoryManager, null, null, null, null, null);
|
||||
RepositoryCollectionToDtoMapper repositoryCollectionToDtoMapper = new RepositoryCollectionToDtoMapper(repositoryToDtoMapper, resourceLinks);
|
||||
RepositoryCollectionResource repositoryCollectionResource = new RepositoryCollectionResource(repositoryManager, repositoryCollectionToDtoMapper);
|
||||
RepositoryRootResource repositoryRootResource = new RepositoryRootResource(MockProvider.of(repositoryResource), MockProvider.of(repositoryCollectionResource));
|
||||
@@ -98,6 +107,57 @@ public class RepositoryRootResourceTest {
|
||||
assertTrue(response.getContentAsString().contains("\"name\":\"repo\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleUpdateForNotExistingRepository() throws URISyntaxException, IOException {
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/repository-test-update.json");
|
||||
byte[] repository = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repository);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(SC_NOT_FOUND, response.getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleUpdateForExistingRepository() throws Exception {
|
||||
mockRepository("space", "repo");
|
||||
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/repository-test-update.json");
|
||||
byte[] repository = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest
|
||||
.put("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo")
|
||||
.contentType(VndMediaType.REPOSITORY)
|
||||
.content(repository);
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(SC_NO_CONTENT, response.getStatus());
|
||||
verify(repositoryManager).modify(anyObject());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldHandleDeleteForExistingRepository() throws Exception {
|
||||
mockRepository("space", "repo");
|
||||
|
||||
URL url = Resources.getResource("sonia/scm/api/v2/repository-test-update.json");
|
||||
byte[] repository = Resources.toByteArray(url);
|
||||
|
||||
MockHttpRequest request = MockHttpRequest.delete("/" + RepositoryRootResource.REPOSITORIES_PATH_V2 + "space/repo");
|
||||
MockHttpResponse response = new MockHttpResponse();
|
||||
|
||||
dispatcher.invoke(request, response);
|
||||
|
||||
assertEquals(SC_NO_CONTENT, response.getStatus());
|
||||
verify(repositoryManager).delete(anyObject());
|
||||
}
|
||||
|
||||
private PageResult<Repository> createSingletonPageResult(Repository repository) {
|
||||
return new PageResult<>(singletonList(repository), 0);
|
||||
}
|
||||
@@ -106,8 +166,10 @@ public class RepositoryRootResourceTest {
|
||||
Repository repository = new Repository();
|
||||
repository.setNamespace(namespace);
|
||||
repository.setName(name);
|
||||
repository.setId("id");
|
||||
String id = namespace + "-" + name;
|
||||
repository.setId(id);
|
||||
when(repositoryManager.getByNamespace(namespace, name)).thenReturn(repository);
|
||||
when(repositoryManager.get(id)).thenReturn(repository);
|
||||
return repository;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"contact": "none@example.com",
|
||||
"description": "Test repository",
|
||||
"namespace": "space",
|
||||
"name": "repo",
|
||||
"archived": false,
|
||||
"type": "git"
|
||||
}
|
||||
Reference in New Issue
Block a user